diff --git a/.hgignore b/.hgignore index b460b0a72..ba6495930 100644 --- a/.hgignore +++ b/.hgignore @@ -21,5 +21,6 @@ projects/windows/vc2010/empty_window/empty_window.vcxproj.filters projects/windows/vc2010/empty_window/empty_window.vcxproj.user projects/src/** projects/android-project/data/** +projects/android-project/gen/** log.log ee* \ No newline at end of file diff --git a/include/eepp/ee.hpp b/include/eepp/ee.hpp index 43722330f..f8def21c3 100755 --- a/include/eepp/ee.hpp +++ b/include/eepp/ee.hpp @@ -24,7 +24,6 @@ /** @TODO Update OpenAL Soft version for Android. @TODO Improve documentation. - @TODO Add support for the native on-screen keyboard on iOS and Android. @TODO Improve Premake4 support. It should be really easy to compile eepp in Windows and OS X ( Linux is always easy thanks to package managers ). @TODO Add more examples, showing at least the basic usage of the engine ( 10 or more examples at least ). @TODO Create a default UI Theme for the engine ( get rid off the ugly Aqua Theme ). diff --git a/include/eepp/window/cwindow.hpp b/include/eepp/window/cwindow.hpp index 1efcfd594..1c76ce1d5 100644 --- a/include/eepp/window/cwindow.hpp +++ b/include/eepp/window/cwindow.hpp @@ -122,6 +122,13 @@ class WindowInfo { eeWindowContex Context; }; + +/* See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define EE_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define EE_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + class EE_API cWindow { public: typedef cb::Callback0 WindowResizeCallback; @@ -372,6 +379,40 @@ class EE_API cWindow { * @sa HasScreenKeyboardSupport() */ virtual bool IsScreenKeyboardShown(); + +#if EE_PLATFORM == EE_PLATFORM_ANDROID + /** @return The JNI environment for the current thread + * This returns JNIEnv*, but the prototype is void* so we don't need jni.h + */ + virtual void * GetJNIEnv(); + + /** @return The SDL Activity object for the application + * This returns jobject, but the prototype is void* so we don't need jni.h + */ + virtual void * GetActivity(); + + /** @return The current state of external storage, a bitmask of these values: + * EE_ANDROID_EXTERNAL_STORAGE_READ + * EE_ANDROID_EXTERNAL_STORAGE_WRITE + * If external storage is currently unavailable, this will return 0. + */ + virtual int GetExternalStorageState(); + + /** @return The path used for internal storage for this application. + * This path is unique to your application and cannot be written to + * by other applications. + */ + virtual std::string GetInternalStoragePath(); + + /** @return The path used for external storage for this application. + * This path is unique to your application, but is public and can be + * written to by other applications. + */ + virtual std::string GetExternalStoragePath(); + + /** @return The application APK file path */ + virtual std::string GetApkPath(); +#endif protected: friend class cEngine; diff --git a/projects/android-project/jni/Android.mk b/projects/android-project/jni/Android.mk index 1d754e209..429e5a89d 100644 --- a/projects/android-project/jni/Android.mk +++ b/projects/android-project/jni/Android.mk @@ -12,7 +12,7 @@ MY_C_INCLUDES := \ $(MY_SDL_PATH)/include \ $(MY_PATH)/helper/chipmunk \ $(INC_PATH)/eepp/helper/chipmunk \ - $(MY_PATH)/helper/SOIL2/include/SOIL2 \ + $(MY_PATH)/helper/SOIL2/src/SOIL2 \ $(MY_PATH)/helper/stb_vorbis \ $(INC_PATH)/eepp/helper/chipmunk diff --git a/projects/android-project/src/org/libsdl/app/SDLActivity.java b/projects/android-project/src/org/libsdl/app/SDLActivity.java index 07fcd9ac9..5fc6d33b8 100644 --- a/projects/android-project/src/org/libsdl/app/SDLActivity.java +++ b/projects/android-project/src/org/libsdl/app/SDLActivity.java @@ -9,6 +9,11 @@ import javax.microedition.khronos.egl.*; import android.app.*; import android.content.*; import android.view.*; +import android.view.inputmethod.BaseInputConnection; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import android.widget.AbsoluteLayout; import android.os.*; import android.util.Log; import android.graphics.*; @@ -16,7 +21,9 @@ import android.text.method.*; import android.text.*; import android.media.*; import android.hardware.*; -import android.content.*; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import java.lang.*; @@ -26,9 +33,14 @@ import java.lang.*; */ public class SDLActivity extends Activity { + // Keep track of the paused state + public static boolean mIsPaused; + // Main components private static SDLActivity mSingleton; private static SDLSurface mSurface; + private static View mTextEdit; + private static ViewGroup mLayout; // This is what SDL runs in. It invokes SDL_main(), eventually private static Thread mSDLThread; @@ -46,6 +58,10 @@ public class SDLActivity extends Activity { // Load the .so static { + //System.loadLibrary("SDL2"); + //System.loadLibrary("SDL2_image"); + //System.loadLibrary("SDL2_mixer"); + //System.loadLibrary("SDL2_ttf"); System.loadLibrary("main"); } @@ -57,24 +73,32 @@ public class SDLActivity extends Activity { // So we can call stuff from static callbacks mSingleton = this; + // Keep track of the paused state + mIsPaused = false; + // Set up the surface mSurface = new SDLSurface(getApplication()); - setContentView(mSurface); + + mLayout = new AbsoluteLayout(this); + mLayout.addView(mSurface); + + setContentView(mLayout); + SurfaceHolder holder = mSurface.getHolder(); } // Events - protected void onPause() { + /*protected void onPause() { Log.v("SDL", "onPause()"); super.onPause(); - SDLActivity.nativePause(); + // Don't call SDLActivity.nativePause(); here, it will be called by SDLSurface::surfaceDestroyed } protected void onResume() { Log.v("SDL", "onResume()"); super.onResume(); - SDLActivity.nativeResume(); - } + // Don't call SDLActivity.nativeResume(); here, it will be called via SDLSurface::surfaceChanged->SDLActivity::startApp + }*/ protected void onDestroy() { super.onDestroy(); @@ -96,13 +120,26 @@ public class SDLActivity extends Activity { } // Messages from the SDLMain thread - static int COMMAND_CHANGE_TITLE = 1; + static final int COMMAND_CHANGE_TITLE = 1; + static final int COMMAND_UNUSED = 2; + static final int COMMAND_TEXTEDIT_HIDE = 3; // Handler for the messages Handler commandHandler = new Handler() { + @Override public void handleMessage(Message msg) { - if (msg.arg1 == COMMAND_CHANGE_TITLE) { + switch (msg.arg1) { + case COMMAND_CHANGE_TITLE: setTitle((String)msg.obj); + break; + case COMMAND_TEXTEDIT_HIDE: + if (mTextEdit != null) { + mTextEdit.setVisibility(View.GONE); + + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); + } + break; } } }; @@ -116,7 +153,7 @@ public class SDLActivity extends Activity { } // C functions we call - public static native void nativeInit(); + public static native void nativeInit(String apkPath); public static native void nativeQuit(); public static native void nativePause(); public static native void nativeResume(); @@ -145,6 +182,10 @@ public class SDLActivity extends Activity { mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); } + public static void sendMessage(int command, int param) { + mSingleton.sendCommand(command, Integer.valueOf(param)); + } + public static Context getContext() { return mSingleton; } @@ -156,16 +197,67 @@ public class SDLActivity extends Activity { mSDLThread.start(); } else { - SDLActivity.nativeResume(); + /* + * Some Android variants may send multiple surfaceChanged events, so we don't need to resume every time + * every time we get one of those events, only if it comes after surfaceDestroyed + */ + if (mIsPaused) { + SDLActivity.nativeResume(); + SDLActivity.mIsPaused = false; + } } } + + static class ShowTextInputHandler implements Runnable { + /* + * This is used to regulate the pan&scan method to have some offset from + * the bottom edge of the input region and the top edge of an input + * method (soft keyboard) + */ + static final int HEIGHT_PADDING = 15; + + public int x, y, w, h; + + public ShowTextInputHandler(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public void run() { + AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams( + w, h + HEIGHT_PADDING, x, y); + + if (mTextEdit == null) { + mTextEdit = new DummyEdit(getContext()); + + mLayout.addView(mTextEdit, params); + } else { + mTextEdit.setLayoutParams(params); + } + + mTextEdit.setVisibility(View.VISIBLE); + mTextEdit.requestFocus(); + + InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mTextEdit, 0); + } + + } + + public static void showTextInput(int x, int y, int w, int h) { + // Transfer the task to the main thread as a Runnable + mSingleton.commandHandler.post(new ShowTextInputHandler(x, y, w, h)); + } + // EGL functions public static boolean initEGL(int majorVersion, int minorVersion) { - if (SDLActivity.mEGLDisplay == null) { - //Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); + try { + if (SDLActivity.mEGLDisplay == null) { + Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); - try { EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); @@ -194,31 +286,20 @@ public class SDLActivity extends Activity { } EGLConfig config = configs[0]; - /*int EGL_CONTEXT_CLIENT_VERSION=0x3098; - int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, majorVersion, EGL10.EGL_NONE }; - EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, contextAttrs); - - if (ctx == EGL10.EGL_NO_CONTEXT) { - Log.e("SDL", "Couldn't create context"); - return false; - } - SDLActivity.mEGLContext = ctx;*/ SDLActivity.mEGLDisplay = dpy; SDLActivity.mEGLConfig = config; SDLActivity.mGLMajor = majorVersion; SDLActivity.mGLMinor = minorVersion; - - SDLActivity.createEGLSurface(); - } catch(Exception e) { - Log.v("SDL", e + ""); - for (StackTraceElement s : e.getStackTrace()) { - Log.v("SDL", s.toString()); - } } - } - else SDLActivity.createEGLSurface(); + return SDLActivity.createEGLSurface(); - return true; + } catch(Exception e) { + Log.v("SDL", e + ""); + for (StackTraceElement s : e.getStackTrace()) { + Log.v("SDL", s.toString()); + } + return false; + } } public static boolean createEGLContext() { @@ -245,18 +326,23 @@ public class SDLActivity extends Activity { return false; } - if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { - Log.e("SDL", "Old EGL Context doesnt work, trying with a new one"); - createEGLContext(); + if (egl.eglGetCurrentContext() != SDLActivity.mEGLContext) { if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { - Log.e("SDL", "Failed making EGL Context current"); - return false; + Log.e("SDL", "Old EGL Context doesnt work, trying with a new one"); + // TODO: Notify the user via a message that the old context could not be restored, and that textures need to be manually restored. + createEGLContext(); + if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { + Log.e("SDL", "Failed making EGL Context current"); + return false; + } } } SDLActivity.mEGLSurface = surface; return true; + } else { + Log.e("SDL", "Surface creation failed, display = " + SDLActivity.mEGLDisplay + ", config = " + SDLActivity.mEGLConfig); + return false; } - return false; } // EGL buffer flip @@ -385,7 +471,18 @@ public class SDLActivity extends Activity { class SDLMain implements Runnable { public void run() { // Runs SDL_main() - SDLActivity.nativeInit(); + // return apk file path (or null on error) + String apkFilePath = null; + ApplicationInfo appInfo = null; + PackageManager packMgmr = SDLActivity.getContext().getPackageManager(); + try { + appInfo = packMgmr.getApplicationInfo("org.libsdl.app", 0); + } catch (NameNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException("Unable to locate assets, aborting..."); + } + apkFilePath = appInfo.sourceDir; + SDLActivity.nativeInit(apkFilePath); //Log.v("SDL", "SDL thread terminated"); } @@ -404,6 +501,9 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, // Sensors private static SensorManager mSensorManager; + // Keep track of the surface size to normalize touch events + private static float mWidth, mHeight; + // Startup public SDLSurface(Context context) { super(context); @@ -415,21 +515,27 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, setOnKeyListener(this); setOnTouchListener(this); - mSensorManager = (SensorManager)context.getSystemService("sensor"); + mSensorManager = (SensorManager)context.getSystemService("sensor"); + + // Some arbitrary defaults to avoid a potential division by zero + mWidth = 1.0f; + mHeight = 1.0f; } // Called when we have a valid drawing surface public void surfaceCreated(SurfaceHolder holder) { Log.v("SDL", "surfaceCreated()"); holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); - SDLActivity.createEGLSurface(); enableSensor(Sensor.TYPE_ACCELEROMETER, true); } // Called when we lose the surface public void surfaceDestroyed(SurfaceHolder holder) { Log.v("SDL", "surfaceDestroyed()"); - SDLActivity.nativePause(); + if (!SDLActivity.mIsPaused) { + SDLActivity.mIsPaused = true; + SDLActivity.nativePause(); + } enableSensor(Sensor.TYPE_ACCELEROMETER, false); } @@ -482,6 +588,9 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, Log.v("SDL", "pixel format unknown " + format); break; } + + mWidth = (float) width; + mHeight = (float) height; SDLActivity.onNativeResize(width, height, sdlFormat); Log.v("SDL", "Window size:" + width + "x"+height); @@ -517,12 +626,12 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, final int touchDevId = event.getDeviceId(); final int pointerCount = event.getPointerCount(); // touchId, pointerId, action, x, y, pressure - int actionPointerIndex = event.getActionIndex(); + int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent. ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */ int pointerFingerId = event.getPointerId(actionPointerIndex); - int action = event.getActionMasked(); + int action = (event.getAction() & MotionEvent.ACTION_MASK); /* API 8: event.getActionMasked(); */ - float x = event.getX(actionPointerIndex); - float y = event.getY(actionPointerIndex); + float x = event.getX(actionPointerIndex) / mWidth; + float y = event.getY(actionPointerIndex) / mHeight; float p = event.getPressure(actionPointerIndex); if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) { @@ -530,8 +639,8 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, // changed since prev event. for (int i = 0; i < pointerCount; i++) { pointerFingerId = event.getPointerId(i); - x = event.getX(i); - y = event.getY(i); + x = event.getX(i) / mWidth; + y = event.getY(i) / mHeight; p = event.getPressure(i); SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p); } @@ -566,6 +675,104 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, event.values[2] / SensorManager.GRAVITY_EARTH); } } - + } +/* This is a fake invisible editor view that receives the input and defines the + * pan&scan region + */ +class DummyEdit extends View implements View.OnKeyListener { + InputConnection ic; + + public DummyEdit(Context context) { + super(context); + setFocusableInTouchMode(true); + setFocusable(true); + setOnKeyListener(this); + } + + @Override + public boolean onCheckIsTextEditor() { + return true; + } + + public boolean onKey(View v, int keyCode, KeyEvent event) { + + // This handles the hardware keyboard input + if (event.isPrintingKey()) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1); + } + return true; + } + + if (event.getAction() == KeyEvent.ACTION_DOWN) { + SDLActivity.onNativeKeyDown(keyCode); + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + SDLActivity.onNativeKeyUp(keyCode); + return true; + } + + return false; + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + ic = new SDLInputConnection(this, true); + + outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI + | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */; + + return ic; + } +} + +class SDLInputConnection extends BaseInputConnection { + + public SDLInputConnection(View targetView, boolean fullEditor) { + super(targetView, fullEditor); + + } + + @Override + public boolean sendKeyEvent(KeyEvent event) { + + /* + * This handles the keycodes from soft keyboard (and IME-translated + * input from hardkeyboard) + */ + int keyCode = event.getKeyCode(); + if (event.getAction() == KeyEvent.ACTION_DOWN) { + + SDLActivity.onNativeKeyDown(keyCode); + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + + SDLActivity.onNativeKeyUp(keyCode); + return true; + } + return super.sendKeyEvent(event); + } + + @Override + public boolean commitText(CharSequence text, int newCursorPosition) { + + nativeCommitText(text.toString(), newCursorPosition); + + return super.commitText(text, newCursorPosition); + } + + @Override + public boolean setComposingText(CharSequence text, int newCursorPosition) { + + nativeSetComposingText(text.toString(), newCursorPosition); + + return super.setComposingText(text, newCursorPosition); + } + + public native void nativeCommitText(String text, int newCursorPosition); + + public native void nativeSetComposingText(String text, int newCursorPosition); + +} diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index bbecb9996..25517ff79 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget @@ -48,9 +48,9 @@ Desktop Desktop {388e5431-b31b-42b3-b9ad-9002d279d75d} - 0 + 11 0 - 0 + 4 /home/programming/eepp diff --git a/src/eepp/helper/SDL2/include/SDL.h b/src/eepp/helper/SDL2/include/SDL.h index 6b584b7bd..e5d3ecd33 100644 --- a/src/eepp/helper/SDL2/include/SDL.h +++ b/src/eepp/helper/SDL2/include/SDL.h @@ -79,13 +79,16 @@ #include "SDL_endian.h" #include "SDL_error.h" #include "SDL_events.h" +#include "SDL_gamecontroller.h" #include "SDL_hints.h" #include "SDL_loadso.h" #include "SDL_log.h" +#include "SDL_messagebox.h" #include "SDL_mutex.h" #include "SDL_power.h" #include "SDL_render.h" #include "SDL_rwops.h" +#include "SDL_system.h" #include "SDL_thread.h" #include "SDL_timer.h" #include "SDL_version.h" @@ -113,6 +116,7 @@ extern "C" { #define SDL_INIT_VIDEO 0x00000020 #define SDL_INIT_JOYSTICK 0x00000200 #define SDL_INIT_HAPTIC 0x00001000 +#define SDL_INIT_GAMECONTROLLER 0x00002000 /**< turn on game controller also implicitly does JOYSTICK */ #define SDL_INIT_NOPARACHUTE 0x00100000 /**< Don't catch fatal signals */ #define SDL_INIT_EVERYTHING 0x0000FFFF /*@}*/ diff --git a/src/eepp/helper/SDL2/include/SDL_assert.h b/src/eepp/helper/SDL2/include/SDL_assert.h index 7c3887e21..ab5d3a0d3 100644 --- a/src/eepp/helper/SDL2/include/SDL_assert.h +++ b/src/eepp/helper/SDL2/include/SDL_assert.h @@ -49,9 +49,9 @@ on the assertion line and not in some random guts of SDL, and so each assert can have unique static variables associated with it. */ -#if defined(_MSC_VER) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) /* Don't include intrin.h here because it contains C++ code */ -extern void __cdecl __debugbreak(void); + extern void __cdecl __debugbreak(void); #define SDL_TriggerBreakpoint() __debugbreak() #elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) diff --git a/src/eepp/helper/SDL2/include/SDL_atomic.h b/src/eepp/helper/SDL2/include/SDL_atomic.h index a036b6d28..4b737f548 100644 --- a/src/eepp/helper/SDL2/include/SDL_atomic.h +++ b/src/eepp/helper/SDL2/include/SDL_atomic.h @@ -65,7 +65,7 @@ /* Need to do this here because intrin.h has C++ code in it */ /* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) && (_MSC_VER >= 1500) #include #define HAVE_MSC_ATOMICS 1 #endif @@ -161,10 +161,10 @@ void _ReadWriteBarrier(void); #include #define SDL_AtomicCAS(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((oldval), (newval), &(a)->value) -#if SIZEOF_VOIDP == 4 -#define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((int32_t)(oldval), (int32_t)(newval), (int32_t*)(a)) -#elif SIZEOF_VOIDP == 8 +#ifdef __LP64__ #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap64Barrier((int64_t)(oldval), (int64_t)(newval), (int64_t*)(a)) +#else +#define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((int32_t)(oldval), (int32_t)(newval), (int32_t*)(a)) #endif #elif defined(HAVE_GCC_ATOMICS) diff --git a/src/eepp/helper/SDL2/include/SDL_config.h b/src/eepp/helper/SDL2/include/SDL_config.h index 03ff56f54..43f314a2e 100644 --- a/src/eepp/helper/SDL2/include/SDL_config.h +++ b/src/eepp/helper/SDL2/include/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2011 Sam Lantinga + Copyright (C) 1997-2012 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/eepp/helper/SDL2/include/SDL_config.h.cmake b/src/eepp/helper/SDL2/include/SDL_config.h.cmake new file mode 100644 index 000000000..d5ae1d815 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_config.h.cmake @@ -0,0 +1,365 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_config_h +#define _SDL_config_h + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C language features */ +#cmakedefine const @HAVE_CONST@ +#cmakedefine inline @HAVE_INLINE@ +#cmakedefine volatile @HAVE_VOLATILE@ + +/* C datatypes */ +#cmakedefine SIZEOF_VOIDP @SIZEOF_VOIDP@ +#cmakedefine HAVE_GCC_ATOMICS @HAVE_GCC_ATOMICS@ +#cmakedefine HAVE_GCC_SYNC_LOCK_TEST_AND_SET @HAVE_GCC_SYNC_LOCK_TEST_AND_SET@ +#cmakedefine HAVE_PTHREAD_SPINLOCK @HAVE_PTHREAD_SPINLOCK@ + +/* Comment this if you want to build without any C library requirements */ +#cmakedefine HAVE_LIBC 1 +#if HAVE_LIBC + +/* Useful headers */ +#cmakedefine HAVE_ALLOCA_H 1 +#cmakedefine HAVE_SYS_TYPES_H 1 +#cmakedefine HAVE_STDIO_H 1 +#cmakedefine STDC_HEADERS 1 +#cmakedefine HAVE_STDLIB_H 1 +#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_MALLOC_H 1 +#cmakedefine HAVE_MEMORY_H 1 +#cmakedefine HAVE_STRING_H 1 +#cmakedefine HAVE_STRINGS_H 1 +#cmakedefine HAVE_INTTYPES_H 1 +#cmakedefine HAVE_STDINT_H 1 +#cmakedefine HAVE_CTYPE_H 1 +#cmakedefine HAVE_MATH_H 1 +#cmakedefine HAVE_ICONV_H 1 +#cmakedefine HAVE_SIGNAL_H 1 +#cmakedefine HAVE_ALTIVEC_H 1 +#cmakedefine HAVE_PTHREAD_NP_H 1 +#cmakedefine HAVE_LIBUDEV_H 1 + +/* C library functions */ +#cmakedefine HAVE_MALLOC 1 +#cmakedefine HAVE_CALLOC 1 +#cmakedefine HAVE_REALLOC 1 +#cmakedefine HAVE_FREE 1 +#cmakedefine HAVE_ALLOCA 1 +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#cmakedefine HAVE_GETENV 1 +#cmakedefine HAVE_SETENV 1 +#cmakedefine HAVE_PUTENV 1 +#cmakedefine HAVE_UNSETENV 1 +#endif +#cmakedefine HAVE_QSORT 1 +#cmakedefine HAVE_ABS 1 +#cmakedefine HAVE_BCOPY 1 +#cmakedefine HAVE_MEMSET 1 +#cmakedefine HAVE_MEMCPY 1 +#cmakedefine HAVE_MEMMOVE 1 +#cmakedefine HAVE_MEMCMP 1 +#cmakedefine HAVE_STRLEN 1 +#cmakedefine HAVE_STRLCPY 1 +#cmakedefine HAVE_STRLCAT 1 +#cmakedefine HAVE_STRDUP 1 +#cmakedefine HAVE__STRREV 1 +#cmakedefine HAVE__STRUPR 1 +#cmakedefine HAVE__STRLWR 1 +#cmakedefine HAVE_INDEX 1 +#cmakedefine HAVE_RINDEX 1 +#cmakedefine HAVE_STRCHR 1 +#cmakedefine HAVE_STRRCHR 1 +#cmakedefine HAVE_STRSTR 1 +#cmakedefine HAVE_ITOA 1 +#cmakedefine HAVE__LTOA 1 +#cmakedefine HAVE__UITOA 1 +#cmakedefine HAVE__ULTOA 1 +#cmakedefine HAVE_STRTOL 1 +#cmakedefine HAVE_STRTOUL 1 +#cmakedefine HAVE__I64TOA 1 +#cmakedefine HAVE__UI64TOA 1 +#cmakedefine HAVE_STRTOLL 1 +#cmakedefine HAVE_STRTOULL 1 +#cmakedefine HAVE_STRTOD 1 +#cmakedefine HAVE_ATOI 1 +#cmakedefine HAVE_ATOF 1 +#cmakedefine HAVE_STRCMP 1 +#cmakedefine HAVE_STRNCMP 1 +#cmakedefine HAVE__STRICMP 1 +#cmakedefine HAVE_STRCASECMP 1 +#cmakedefine HAVE__STRNICMP 1 +#cmakedefine HAVE_STRNCASECMP 1 +#cmakedefine HAVE_SSCANF 1 +#cmakedefine HAVE_SNPRINTF 1 +#cmakedefine HAVE_VSNPRINTF 1 +#cmakedefine HAVE_M_PI 1 +#cmakedefine HAVE_ATAN 1 +#cmakedefine HAVE_ATAN2 1 +#cmakedefine HAVE_CEIL 1 +#cmakedefine HAVE_COPYSIGN 1 +#cmakedefine HAVE_COS 1 +#cmakedefine HAVE_COSF 1 +#cmakedefine HAVE_FABS 1 +#cmakedefine HAVE_FLOOR 1 +#cmakedefine HAVE_LOG 1 +#cmakedefine HAVE_POW 1 +#cmakedefine HAVE_SCALBN 1 +#cmakedefine HAVE_SIN 1 +#cmakedefine HAVE_SINF 1 +#cmakedefine HAVE_SQRT 1 +#cmakedefine HAVE_FSEEKO 1 +#cmakedefine HAVE_FSEEKO64 1 +#cmakedefine HAVE_SIGACTION 1 +#cmakedefine HAVE_SA_SIGACTION 1 +#cmakedefine HAVE_SETJMP 1 +#cmakedefine HAVE_NANOSLEEP 1 +#cmakedefine HAVE_SYSCONF 1 +#cmakedefine HAVE_SYSCTLBYNAME 1 +#cmakedefine HAVE_CLOCK_GETTIME 1 +#cmakedefine HAVE_GETPAGESIZE 1 +#cmakedefine HAVE_MPROTECT 1 +#cmakedefine HAVE_ICONV 1 +#cmakedefine HAVE_PTHREAD_SETNAME_NP 1 +#cmakedefine HAVE_PTHREAD_SET_NAME_NP 1 +#cmakedefine HAVE_SEM_TIMEDWAIT 1 +#elif __WIN32__ +#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_STDDEF_H 1 +#else +/* We may need some replacement for stdarg.h here */ +#include +#endif /* HAVE_LIBC */ + +/* SDL internal assertion support */ +#cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@ + +/* Allow disabling of core subsystems */ +#cmakedefine SDL_ATOMIC_DISABLED @SDL_ATOMIC_DISABLED@ +#cmakedefine SDL_AUDIO_DISABLED @SDL_AUDIO_DISABLED@ +#cmakedefine SDL_CPUINFO_DISABLED @SDL_CPUINFO_DISABLED@ +#cmakedefine SDL_EVENTS_DISABLED @SDL_EVENTS_DISABLED@ +#cmakedefine SDL_FILE_DISABLED @SDL_FILE_DISABLED@ +#cmakedefine SDL_JOYSTICK_DISABLED @SDL_JOYSTICK_DISABLED@ +#cmakedefine SDL_HAPTIC_DISABLED @SDL_HAPTIC_DISABLED@ +#cmakedefine SDL_LOADSO_DISABLED @SDL_LOADSO_DISABLED@ +#cmakedefine SDL_RENDER_DISABLED @SDL_RENDER_DISABLED@ +#cmakedefine SDL_THREADS_DISABLED @SDL_THREADS_DISABLED@ +#cmakedefine SDL_TIMERS_DISABLED @SDL_TIMERS_DISABLED@ +#cmakedefine SDL_VIDEO_DISABLED @SDL_VIDEO_DISABLED@ +#cmakedefine SDL_POWER_DISABLED @SDL_POWER_DISABLED@ + +/* Enable various audio drivers */ +#cmakedefine SDL_AUDIO_DRIVER_ALSA @SDL_AUDIO_DRIVER_ALSA@ +#cmakedefine SDL_AUDIO_DRIVER_ALSA_DYNAMIC @SDL_AUDIO_DRIVER_ALSA_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_ARTS @SDL_AUDIO_DRIVER_ARTS@ +#cmakedefine SDL_AUDIO_DRIVER_ARTS_DYNAMIC @SDL_AUDIO_DRIVER_ARTS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO @SDL_AUDIO_DRIVER_PULSEAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC @SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_BEOSAUDIO @SDL_AUDIO_DRIVER_BEOSAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_BSD @SDL_AUDIO_DRIVER_BSD@ +#cmakedefine SDL_AUDIO_DRIVER_COREAUDIO @SDL_AUDIO_DRIVER_COREAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_DISK @SDL_AUDIO_DRIVER_DISK@ +#cmakedefine SDL_AUDIO_DRIVER_DUMMY @SDL_AUDIO_DRIVER_DUMMY@ +#cmakedefine SDL_AUDIO_DRIVER_XAUDIO2 @SDL_AUDIO_DRIVER_XAUDIO2@ +#cmakedefine SDL_AUDIO_DRIVER_DSOUND @SDL_AUDIO_DRIVER_DSOUND@ +#cmakedefine SDL_AUDIO_DRIVER_ESD @SDL_AUDIO_DRIVER_ESD@ +#cmakedefine SDL_AUDIO_DRIVER_ESD_DYNAMIC @SDL_AUDIO_DRIVER_ESD_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_NAS @SDL_AUDIO_DRIVER_NAS@ +#cmakedefine SDL_AUDIO_DRIVER_NAS_DYNAMIC @SDL_AUDIO_DRIVER_NAS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_NDS @SDL_AUDIO_DRIVER_NDS@ +#cmakedefine SDL_AUDIO_DRIVER_OSS @SDL_AUDIO_DRIVER_OSS@ +#cmakedefine SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H @SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H@ +#cmakedefine SDL_AUDIO_DRIVER_PAUDIO @SDL_AUDIO_DRIVER_PAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_QSA @SDL_AUDIO_DRIVER_QSA@ +#cmakedefine SDL_AUDIO_DRIVER_SUNAUDIO @SDL_AUDIO_DRIVER_SUNAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_WINMM @SDL_AUDIO_DRIVER_WINMM@ +#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@ +#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@ + +/* Enable various input drivers */ +#cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@ +#cmakedefine SDL_INPUT_TSLIB @SDL_INPUT_TSLIB@ +#cmakedefine SDL_JOYSTICK_BEOS @SDL_JOYSTICK_BEOS@ +#cmakedefine SDL_JOYSTICK_DINPUT @SDL_JOYSTICK_DINPUT@ +#cmakedefine SDL_JOYSTICK_DUMMY @SDL_JOYSTICK_DUMMY@ +#cmakedefine SDL_JOYSTICK_IOKIT @SDL_JOYSTICK_IOKIT@ +#cmakedefine SDL_JOYSTICK_LINUX @SDL_JOYSTICK_LINUX@ +#cmakedefine SDL_JOYSTICK_NDS @SDL_JOYSTICK_NDS@ +#cmakedefine SDL_JOYSTICK_WINMM @SDL_JOYSTICK_WINMM@ +#cmakedefine SDL_JOYSTICK_USBHID @SDL_JOYSTICK_USBHID@ +#cmakedefine SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H @SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H@ +#cmakedefine SDL_HAPTIC_DUMMY @SDL_HAPTIC_DUMMY@ +#cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@ +#cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@ +#cmakedefine SDL_HAPTIC_DINPUT @SDL_HAPTIC_DINPUT@ + +/* Enable various shared object loading systems */ +#cmakedefine SDL_LOADSO_BEOS @SDL_LOADSO_BEOS@ +#cmakedefine SDL_LOADSO_DLOPEN @SDL_LOADSO_DLOPEN@ +#cmakedefine SDL_LOADSO_DUMMY @SDL_LOADSO_DUMMY@ +#cmakedefine SDL_LOADSO_LDG @SDL_LOADSO_LDG@ +#cmakedefine SDL_LOADSO_WINDOWS @SDL_LOADSO_WINDOWS@ + +/* Enable various threading systems */ +#cmakedefine SDL_THREAD_BEOS @SDL_THREAD_BEOS@ +#cmakedefine SDL_THREAD_NDS @SDL_THREAD_NDS@ +#cmakedefine SDL_THREAD_PTHREAD @SDL_THREAD_PTHREAD@ +#cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX@ +#cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP@ +#cmakedefine SDL_THREAD_WINDOWS @SDL_THREAD_WINDOWS@ + +/* Enable various timer systems */ +#cmakedefine SDL_TIMER_BEOS @SDL_TIMER_BEOS@ +#cmakedefine SDL_TIMER_DUMMY @SDL_TIMER_DUMMY@ +#cmakedefine SDL_TIMER_NDS @SDL_TIMER_NDS@ +#cmakedefine SDL_TIMER_UNIX @SDL_TIMER_UNIX@ +#cmakedefine SDL_TIMER_WINDOWS @SDL_TIMER_WINDOWS@ +#cmakedefine SDL_TIMER_WINCE @SDL_TIMER_WINCE@ + +/* Enable various video drivers */ +#cmakedefine SDL_VIDEO_DRIVER_BWINDOW @SDL_VIDEO_DRIVER_BWINDOW@ +#cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@ +#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@ +#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@ +#cmakedefine SDL_VIDEO_DRIVER_NDS @SDL_VIDEO_DRIVER_NDS@ +#cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@ +#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS @SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE @SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XCURSOR @SDL_VIDEO_DRIVER_X11_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINERAMA @SDL_VIDEO_DRIVER_X11_XINERAMA@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2 @SDL_VIDEO_DRIVER_X11_XINPUT2@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH @SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XRANDR @SDL_VIDEO_DRIVER_X11_XRANDR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSCRNSAVER @SDL_VIDEO_DRIVER_X11_XSCRNSAVER@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSHAPE @SDL_VIDEO_DRIVER_X11_XSHAPE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XVIDMODE @SDL_VIDEO_DRIVER_X11_XVIDMODE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS @SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS@ +#cmakedefine SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY @SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY@ +#cmakedefine SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM @SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM@ + +#cmakedefine SDL_VIDEO_RENDER_D3D @SDL_VIDEO_RENDER_D3D@ +#cmakedefine SDL_VIDEO_RENDER_OGL @SDL_VIDEO_RENDER_OGL@ +#cmakedefine SDL_VIDEO_RENDER_OGL_ES @SDL_VIDEO_RENDER_OGL_ES@ +#cmakedefine SDL_VIDEO_RENDER_OGL_ES2 @SDL_VIDEO_RENDER_OGL_ES2@ +#cmakedefine SDL_VIDEO_RENDER_DIRECTFB @SDL_VIDEO_RENDER_DIRECTFB@ + +/* Enable OpenGL support */ +#cmakedefine SDL_VIDEO_OPENGL @SDL_VIDEO_OPENGL@ +#cmakedefine SDL_VIDEO_OPENGL_ES @SDL_VIDEO_OPENGL_ES@ +#cmakedefine SDL_VIDEO_OPENGL_BGL @SDL_VIDEO_OPENGL_BGL@ +#cmakedefine SDL_VIDEO_OPENGL_CGL @SDL_VIDEO_OPENGL_CGL@ +#cmakedefine SDL_VIDEO_OPENGL_GLX @SDL_VIDEO_OPENGL_GLX@ +#cmakedefine SDL_VIDEO_OPENGL_WGL @SDL_VIDEO_OPENGL_WGL@ +#cmakedefine SDL_VIDEO_OPENGL_OSMESA @SDL_VIDEO_OPENGL_OSMESA@ +#cmakedefine SDL_VIDEO_OPENGL_OSMESA_DYNAMIC @SDL_VIDEO_OPENGL_OSMESA_DYNAMIC@ + +/* Enable system power support */ +#cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@ +#cmakedefine SDL_POWER_WINDOWS @SDL_POWER_WINDOWS@ +#cmakedefine SDL_POWER_MACOSX @SDL_POWER_MACOSX@ +#cmakedefine SDL_POWER_BEOS @SDL_POWER_BEOS@ +#cmakedefine SDL_POWER_NINTENDODS @SDL_POWER_NINTENDODS@ +#cmakedefine SDL_POWER_HARDWIRED @SDL_POWER_HARDWIRED@ + +/* Enable assembly routines */ +#cmakedefine SDL_ASSEMBLY_ROUTINES @SDL_ASSEMBLY_ROUTINES@ +#cmakedefine SDL_ALTIVEC_BLITTERS @SDL_ALTIVEC_BLITTERS@ + + +/* Platform specific definitions */ +#if !defined(__WIN32__) +# if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) +typedef unsigned int size_t; +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; +typedef unsigned long uintptr_t; +# endif /* if (stdint.h isn't available) */ +#else /* __WIN32__ */ +# if !defined(_STDINT_H_) && !defined(HAVE_STDINT_H) && !defined(_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 */ +#endif /* __WIN32__ */ + +#endif /* _SDL_config_h */ diff --git a/src/eepp/helper/SDL2/include/SDL_config.h.in b/src/eepp/helper/SDL2/include/SDL_config.h.in index 600dbfb00..bcf443d48 100644 --- a/src/eepp/helper/SDL2/include/SDL_config.h.in +++ b/src/eepp/helper/SDL2/include/SDL_config.h.in @@ -70,6 +70,7 @@ #undef HAVE_SIGNAL_H #undef HAVE_ALTIVEC_H #undef HAVE_PTHREAD_NP_H +#undef HAVE_LIBUDEV_H /* C library functions */ #undef HAVE_MALLOC @@ -139,6 +140,8 @@ #undef HAVE_SIN #undef HAVE_SINF #undef HAVE_SQRT +#undef HAVE_FSEEKO +#undef HAVE_FSEEKO64 #undef HAVE_SIGACTION #undef HAVE_SA_SIGACTION #undef HAVE_SETJMP @@ -242,7 +245,6 @@ #undef SDL_TIMER_NDS #undef SDL_TIMER_UNIX #undef SDL_TIMER_WINDOWS -#undef SDL_TIMER_WINCE /* Enable various video drivers */ #undef SDL_VIDEO_DRIVER_BWINDOW diff --git a/src/eepp/helper/SDL2/include/SDL_config_android.h b/src/eepp/helper/SDL2/include/SDL_config_android.h index d0acc69d5..2a8588f23 100644 --- a/src/eepp/helper/SDL2/include/SDL_config_android.h +++ b/src/eepp/helper/SDL2/include/SDL_config_android.h @@ -140,4 +140,7 @@ #define SDL_VIDEO_RENDER_OGL_ES 1 #endif -#endif /* _SDL_config_minimal_h */ +/* Enable system power support */ +#define SDL_POWER_ANDROID 1 + +#endif /* _SDL_config_android_h */ diff --git a/src/eepp/helper/SDL2/include/SDL_config_macosx.h b/src/eepp/helper/SDL2/include/SDL_config_macosx.h index d9d1c1cb6..ca43dc83e 100644 --- a/src/eepp/helper/SDL2/include/SDL_config_macosx.h +++ b/src/eepp/helper/SDL2/include/SDL_config_macosx.h @@ -130,7 +130,7 @@ /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_COCOA 1 #define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_X11 1 +#define SDL_VIDEO_DRIVER_X11 0 #define SDL_VIDEO_DRIVER_X11_DYNAMIC "/usr/X11R6/lib/libX11.6.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/usr/X11R6/lib/libXext.6.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "/usr/X11R6/lib/libXinerama.1.dylib" @@ -139,15 +139,23 @@ #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/usr/X11R6/lib/libXss.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib" #define SDL_VIDEO_DRIVER_X11_XINERAMA 1 -#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 -#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1 #define SDL_VIDEO_DRIVER_X11_XRANDR 1 #define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 #define SDL_VIDEO_DRIVER_X11_XSHAPE 1 #define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 -#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 #define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 +#ifdef MAC_OS_X_VERSION_10_8 +/* + * No matter the versions targeted, this is the 10.8 or later SDK, so you have + * to use the external Xquartz, which is a more modern Xlib. Previous SDKs + * used an older Xlib. + */ +#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 +#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1 +#endif + #ifndef SDL_VIDEO_RENDER_OGL #define SDL_VIDEO_RENDER_OGL 1 #endif diff --git a/src/eepp/helper/SDL2/include/SDL_config_windows.h b/src/eepp/helper/SDL2/include/SDL_config_windows.h index ac5b8a9dc..e8d3ffb97 100644 --- a/src/eepp/helper/SDL2/include/SDL_config_windows.h +++ b/src/eepp/helper/SDL2/include/SDL_config_windows.h @@ -85,9 +85,7 @@ typedef unsigned int uintptr_t; #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 @@ -143,8 +141,8 @@ typedef unsigned int uintptr_t; #endif /* Enable various audio drivers */ -#ifndef _WIN32_WCE #define SDL_AUDIO_DRIVER_DSOUND 1 +#ifndef __GNUC__ #define SDL_AUDIO_DRIVER_XAUDIO2 1 #endif #define SDL_AUDIO_DRIVER_WINMM 1 @@ -152,11 +150,11 @@ typedef unsigned int uintptr_t; #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 +#ifdef __GNUC__ +/* There isn't a compatible dinput.h for mingw as far as I know */ +#define SDL_HAPTIC_DISABLED 1 +#else #define SDL_HAPTIC_DINPUT 1 #endif @@ -167,24 +165,17 @@ typedef unsigned int uintptr_t; #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 -#ifndef _WIN32_WCE #ifndef SDL_VIDEO_RENDER_D3D #define SDL_VIDEO_RENDER_D3D 1 #endif -#endif /* Enable OpenGL support */ -#ifndef _WIN32_WCE #ifndef SDL_VIDEO_OPENGL #define SDL_VIDEO_OPENGL 1 #endif @@ -194,7 +185,6 @@ typedef unsigned int uintptr_t; #ifndef SDL_VIDEO_RENDER_OGL #define SDL_VIDEO_RENDER_OGL 1 #endif -#endif /* Enable system power support */ #define SDL_POWER_WINDOWS 1 diff --git a/src/eepp/helper/SDL2/include/SDL_cpuinfo.h b/src/eepp/helper/SDL2/include/SDL_cpuinfo.h index 3c5b94389..22d04a7ca 100644 --- a/src/eepp/helper/SDL2/include/SDL_cpuinfo.h +++ b/src/eepp/helper/SDL2/include/SDL_cpuinfo.h @@ -32,7 +32,7 @@ /* Need to do this here because intrin.h has C++ code in it */ /* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) && (_MSC_VER >= 1500) #include #ifndef _WIN64 #define __MMX__ diff --git a/src/eepp/helper/SDL2/include/SDL_events.h b/src/eepp/helper/SDL2/include/SDL_events.h index 39648af4d..a47c4aec4 100644 --- a/src/eepp/helper/SDL2/include/SDL_events.h +++ b/src/eepp/helper/SDL2/include/SDL_events.h @@ -34,6 +34,7 @@ #include "SDL_keyboard.h" #include "SDL_mouse.h" #include "SDL_joystick.h" +#include "SDL_gamecontroller.h" #include "SDL_quit.h" #include "SDL_gesture.h" #include "SDL_touch.h" @@ -90,6 +91,15 @@ typedef enum SDL_JOYHATMOTION, /**< Joystick hat position change */ SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ + SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + + /* Game controller events */ + SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ + SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ + SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ + SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ + SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ /* Touch events */ SDL_FINGERDOWN = 0x700, @@ -231,7 +241,7 @@ typedef struct SDL_JoyAxisEvent { Uint32 type; /**< ::SDL_JOYAXISMOTION */ Uint32 timestamp; - Uint8 which; /**< The joystick device index */ + Uint8 which; /**< The joystick instance id */ Uint8 axis; /**< The joystick axis index */ Uint8 padding1; Uint8 padding2; @@ -245,7 +255,7 @@ typedef struct SDL_JoyBallEvent { Uint32 type; /**< ::SDL_JOYBALLMOTION */ Uint32 timestamp; - Uint8 which; /**< The joystick device index */ + Uint8 which; /**< The joystick instance id */ Uint8 ball; /**< The joystick trackball index */ Uint8 padding1; Uint8 padding2; @@ -260,7 +270,7 @@ typedef struct SDL_JoyHatEvent { Uint32 type; /**< ::SDL_JOYHATMOTION */ Uint32 timestamp; - Uint8 which; /**< The joystick device index */ + Uint8 which; /**< The joystick instance id */ Uint8 hat; /**< The joystick hat index */ Uint8 value; /**< The hat position value. * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP @@ -279,12 +289,59 @@ typedef struct SDL_JoyButtonEvent { Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ Uint32 timestamp; - Uint8 which; /**< The joystick device index */ + Uint8 which; /**< The joystick instance id */ Uint8 button; /**< The joystick button index */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ Uint8 padding1; } SDL_JoyButtonEvent; +/** + * \brief Joystick device event structure (event.jdevice.*) + */ +typedef struct SDL_JoyDeviceEvent +{ + Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ + Uint32 timestamp; + Uint32 which; /**< The joystick device index for ADD, instance_id for REMOVE*/ +} SDL_JoyDeviceEvent; + + +/** + * \brief Game controller axis motion event structure (event.caxis.*) + */ +typedef struct SDL_ControllerAxisEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ + Uint32 timestamp; + Uint8 which; /**< The joystick instance id */ + SDL_CONTROLLER_AXIS axis; /**< The joystick axis index */ + int value; /**< The axis value (range: -32768 to 32767) */ +} SDL_ControllerAxisEvent; + + +/** + * \brief Game controller button event structure (event.cbutton.*) + */ +typedef struct SDL_ControllerButtonEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ + Uint32 timestamp; + Uint8 which; /**< The joystick instance id */ + SDL_CONTROLLER_BUTTON button; /**< The joystick button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ +} SDL_ControllerButtonEvent; + + +/** + * \brief Controller device event structure (event.cdevice.*) + */ +typedef struct SDL_ControllerDeviceEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED or ::SDL_CONTROLLERDEVICEREMOVED */ + Uint32 timestamp; + Uint32 which; /**< The joystick device index for ADD, instance_id for REMOVE*/ +} SDL_ControllerDeviceEvent; + /** * \brief Touch finger motion/finger event structure (event.tfinger.*) @@ -336,7 +393,7 @@ typedef struct SDL_MultiGestureEvent SDL_TouchID touchId; /**< The touch device index */ float dTheta; float dDist; - float x; //currently 0...1. Change to screen coords? + float x; /* currently 0...1. Change to screen coords? */ float y; Uint16 numFingers; Uint16 padding; @@ -430,6 +487,10 @@ typedef union SDL_Event SDL_JoyBallEvent jball; /**< Joystick ball event data */ SDL_JoyHatEvent jhat; /**< Joystick hat event data */ SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller button event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ SDL_QuitEvent quit; /**< Quit request event data */ SDL_UserEvent user; /**< Custom event data */ SDL_SysWMEvent syswm; /**< System dependent window event data */ @@ -438,6 +499,15 @@ typedef union SDL_Event SDL_MultiGestureEvent mgesture; /**< Multi Finger Gesture data */ SDL_DollarGestureEvent dgesture; /**< Multi Finger Gesture data */ SDL_DropEvent drop; /**< Drag and drop event data */ + + /* This is necessary for ABI compatibility between Visual C++ and GCC + Visual C++ will respect the push pack pragma and use 52 bytes for + this structure, and GCC will use the alignment of the largest datatype + within the union, which is 8 bytes. + + So... we'll add padding to force the size to be 56 bytes for both. + */ + Uint8 padding[56]; } SDL_Event; diff --git a/src/eepp/helper/SDL2/include/SDL_gamecontroller.h b/src/eepp/helper/SDL2/include/SDL_gamecontroller.h new file mode 100644 index 000000000..0fde9d6f9 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_gamecontroller.h @@ -0,0 +1,257 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gamecontroller.h + * + * Include file for SDL game controller event handling + */ + +#ifndef _SDL_gamecontroller_h +#define _SDL_gamecontroller_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \file SDL_gamecontroller.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + * for game controllers, and load appropriate drivers. + */ + +/* The gamecontroller structure used to identify an SDL game controller */ +struct _SDL_GameController; +typedef struct _SDL_GameController SDL_GameController; + + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT, +} SDL_CONTROLLER_BINDTYPE; +/** + * get the sdl joystick layer binding for this controller button/axis mapping + */ +struct _SDL_GameControllerHatBind +{ + int hat; + int hat_mask; +}; + +typedef struct _SDL_GameControllerButtonBind +{ + SDL_CONTROLLER_BINDTYPE m_eBindType; + union + { + int button; + int axis; + struct _SDL_GameControllerHatBind hat; + }; + +} SDL_GameControllerButtonBind; + + +/** + * To count the number of game controllers in the system for the following: + * int nJoysticks = SDL_NumJoysticks(); + * int nGameControllers = 0; + * for ( int i = 0; i < nJoysticks; i++ ) { + * if ( SDL_IsGameController(i) ) { + * nGameControllers++; + * } + * } + * + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * guid,name,mappings + * + * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. + * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. + * The mapping format for joystick is: + * bX - a joystick button, index X + * hX.Y - hat X with value Y + * aX - axis X of the joystick + * Buttons can be used as a controller axis and vice versa. + * + * This string shows an example of a valid mapping for a controller + * "341a3608000000000000504944564944,Aferglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + * + */ + + +/** + * Is the joystick on this index supported by the game controller interface? + * returns 1 if supported, 0 otherwise. + */ +extern DECLSPEC int SDLCALL SDL_IsGameController(int joystick_index); + + +/** + * Get the implementation dependent name of a game controller. + * This can be called before any controllers are opened. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); + +/** + * Open a game controller for use. + * The index passed as an argument refers to the N'th game controller on the system. + * This index is the value which will identify this controller in future controller + * events. + * + * \return A controller identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); + +/** + * Return the name for this currently opened controller + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController * gamecontroller); + +/** + * Returns 1 if the controller has been opened and currently connected, or 0 if it has not. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetAttached(SDL_GameController * gamecontroller); + +/** + * Get the underlying joystick object used by a controller + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller); + +/** + * Enable/disable controller event polling. + * + * If controller events are disabled, you must call SDL_GameControllerUpdate() + * yourself and check the state of the controller when you want controller + * information. + * + * The state can be one of ::SDL_QUERY, ::SDL_ENABLE or ::SDL_IGNORE. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); + +/** + * The list of axii available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} SDL_CONTROLLER_AXIS; + +/** + * turn this string into a axis mapping + */ +extern DECLSPEC SDL_CONTROLLER_AXIS SDLCALL SDL_GameControllerGetAxisFromString(const char *pchString); + +/** + * get the sdl joystick layer binding for this controller button mapping + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_CONTROLLER_AXIS button); + +/** + * Get the current state of an axis control on a game controller. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + */ +extern DECLSPEC Sint16 SDLCALL SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, + SDL_CONTROLLER_AXIS axis); + +/** + * The list of buttons available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MAX +} SDL_CONTROLLER_BUTTON; + +/** + * turn this string into a button mapping + */ +extern DECLSPEC SDL_CONTROLLER_BUTTON SDLCALL SDL_GameControllerGetButtonFromString(const char *pchString); + + +/** + * get the sdl joystick layer binding for this controller button mapping + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_CONTROLLER_BUTTON button); + + +/** + * Get the current state of a button on a game controller. + * + * The button indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController * gamecontroller, + SDL_CONTROLLER_BUTTON button); + +/** + * Close a controller previously opened with SDL_GameControllerOpen(). + */ +extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController * gamecontrollerk); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_gamecontroller_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_hints.h b/src/eepp/helper/SDL2/include/SDL_hints.h index 7500ee701..8b2fcb91c 100644 --- a/src/eepp/helper/SDL2/include/SDL_hints.h +++ b/src/eepp/helper/SDL2/include/SDL_hints.h @@ -118,7 +118,51 @@ extern "C" { * By default SDL does not sync screen surface updates with vertical refresh. */ #define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" - + +/** + * \brief A variable controlling whether the X11 VidMode extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XVidMode + * "1" - Enable XVidMode + * + * By default SDL will use XVidMode if it is available. + */ +#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" + +/** + * \brief A variable controlling whether the X11 Xinerama extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable Xinerama + * "1" - Enable Xinerama + * + * By default SDL will use Xinerama if it is available. + */ +#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" + +/** + * \brief A variable controlling whether the X11 XRandR extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XRandR + * "1" - Enable XRandR + * + * By default SDL will not use XRandR because of window manager issues. + */ +#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" + +/** + * \brief A variable controlling whether grabbing input grabs the keyboard + * + * This variable can be set to the following values: + * "0" - Grab will affect only the mouse + * "1" - Grab will affect mouse and keyboard + * + * By default SDL will not grab the keyboard so system shortcuts still work. + */ +#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" + /** * \brief A variable controlling whether the idle timer is disabled on iOS. * @@ -145,6 +189,14 @@ extern "C" { #define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" +/** + * \brief A variable that lets you manually hint extra gamecontroller db entries + * + * The variable expected newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h + */ +#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" + + /** * \brief An enumeration of hint priorities */ diff --git a/src/eepp/helper/SDL2/include/SDL_joystick.h b/src/eepp/helper/SDL2/include/SDL_joystick.h index 602206527..4214cef4f 100644 --- a/src/eepp/helper/SDL2/include/SDL_joystick.h +++ b/src/eepp/helper/SDL2/include/SDL_joystick.h @@ -23,6 +23,17 @@ * \file SDL_joystick.h * * Include file for SDL joystick event handling + * + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks, with the exact joystick + * behind a device_index changing as joysticks are plugged and unplugged. + * + * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted + * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. + * + * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of + * the device (a X360 wired controller for example). This identifier is platform dependent. + * + * */ #ifndef _SDL_joystick_h @@ -51,10 +62,17 @@ extern "C" { struct _SDL_Joystick; typedef struct _SDL_Joystick SDL_Joystick; +/* A structure that encodes the stable unique id for a joystick device */ +typedef struct { + Uint8 data[16]; +} SDL_JoystickGUID; + +typedef int SDL_JoystickID; + /* Function prototypes */ /** - * Count the number of joysticks attached to the system + * Count the number of joysticks attached to the system right now */ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); @@ -63,7 +81,7 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); * This can be called before any joysticks are opened. * If no name can be found, this function returns NULL. */ -extern DECLSPEC const char *SDLCALL SDL_JoystickName(int device_index); +extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); /** * Open a joystick for use. @@ -76,14 +94,41 @@ extern DECLSPEC const char *SDLCALL SDL_JoystickName(int device_index); extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); /** - * Returns 1 if the joystick has been opened, or 0 if it has not. + * Return the name for this currently opened joystick. + * If no name can be found, this function returns NULL. */ -extern DECLSPEC int SDLCALL SDL_JoystickOpened(int device_index); +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick); + +/** + * Return the GUID for the joystick at this index + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); /** - * Get the device index of an opened joystick. + * Return the GUID for this opened joystick */ -extern DECLSPEC int SDLCALL SDL_JoystickIndex(SDL_Joystick * joystick); +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick * joystick); + +/** + * Return a string representation for this guid. pszGUID must point to at least 33 bytes + * (32 for the string plus a NULL terminator). + */ +extern DECLSPEC void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); + +/** + * convert a string into a joystick formatted guid + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); + +/** + * Returns SDL_TRUE if the joystick has been opened and currently connected, or SDL_FALSE if it has not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick * joystick); + +/** + * Get the instance ID of an opened joystick. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick * joystick); /** * Get the number of general axis controls on a joystick. diff --git a/src/eepp/helper/SDL2/include/SDL_keyboard.h b/src/eepp/helper/SDL2/include/SDL_keyboard.h index 16c33b59d..19ca8b4a5 100644 --- a/src/eepp/helper/SDL2/include/SDL_keyboard.h +++ b/src/eepp/helper/SDL2/include/SDL_keyboard.h @@ -151,26 +151,60 @@ extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); /** * \brief Start accepting Unicode text input events. + * This function will show the on-screen keyboard if supported. * * \sa SDL_StopTextInput() * \sa SDL_SetTextInputRect() + * \sa SDL_HasScreenKeyboardSupport() */ extern DECLSPEC void SDLCALL SDL_StartTextInput(void); +/** + * \brief Return whether or not Unicode text input events are enabled. + * + * \sa SDL_StartTextInput() + * \sa SDL_StopTextInput() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); + /** * \brief Stop receiving any text input events. + * This function will hide the on-screen keyboard if supported. * * \sa SDL_StartTextInput() + * \sa SDL_HasScreenKeyboardSupport() */ extern DECLSPEC void SDLCALL SDL_StopTextInput(void); /** * \brief Set the rectangle used to type Unicode text inputs. + * This is used as a hint for IME and on-screen keyboard placement. * * \sa SDL_StartTextInput() */ extern DECLSPEC void SDLCALL SDL_SetTextInputRect(SDL_Rect *rect); +/** + * \brief Returns whether the platform has some screen keyboard support. + * + * \return SDL_TRUE if some keyboard support is available else SDL_FALSE. + * + * \note Not all screen keyboard functions are supported on all platforms. + * + * \sa SDL_IsScreenKeyboardShown() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(); + +/** + * \brief Returns whether the screen keyboard is shown for given window. + * + * \param window The window for which screen keyboard should be queried. + * + * \return SDL_TRUE if screen keyboard is shown else SDL_FALSE. + * + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/eepp/helper/SDL2/include/SDL_log.h b/src/eepp/helper/SDL2/include/SDL_log.h index 9f7e8b4f0..e61c44ce7 100644 --- a/src/eepp/helper/SDL2/include/SDL_log.h +++ b/src/eepp/helper/SDL2/include/SDL_log.h @@ -59,17 +59,21 @@ extern "C" { * \brief The predefined log categories * * By default the application category is enabled at the INFO level, - * and all other categories are enabled at the CRITICAL level. + * the assert category is enabled at the WARN level, test is enabled + * at the VERBOSE level and all other categories are enabled at the + * CRITICAL level. */ enum { SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_CATEGORY_AUDIO, SDL_LOG_CATEGORY_VIDEO, SDL_LOG_CATEGORY_RENDER, SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, /* Reserved for future SDL library use */ SDL_LOG_CATEGORY_RESERVED1, diff --git a/src/eepp/helper/SDL2/include/SDL_messagebox.h b/src/eepp/helper/SDL2/include/SDL_messagebox.h new file mode 100644 index 000000000..684e71ab2 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_messagebox.h @@ -0,0 +1,147 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_messagebox_h +#define _SDL_messagebox_h + +#include "SDL_stdinc.h" +#include "SDL_video.h" /* For SDL_Window */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief SDL_MessageBox flags. If supported will display warning icon, etc. + */ +typedef enum +{ + SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ + SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ + SDL_MESSAGEBOX_INFORMATION = 0x00000040 /**< informational dialog */ +} SDL_MessageBoxFlags; + +/** + * \brief Flags for SDL_MessageBoxButtonData. + */ +typedef enum +{ + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, /**< Marks the default button when return is hit */ + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 /**< Marks the default button when escape is hit */ +} SDL_MessageBoxButtonFlags; + +/** + * \brief Individual button data. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxButtonFlags */ + int buttonid; /**< User defined button id (value returned via SDL_MessageBox) */ + const char * text; /**< The UTF-8 button text */ +} SDL_MessageBoxButtonData; + +/** + * \brief RGB value used in a message box color scheme + */ +typedef struct +{ + Uint8 r, g, b; +} SDL_MessageBoxColor; + +typedef enum +{ + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX +} SDL_MessageBoxColorType; + +/** + * \brief A set of colors to use for message box dialogs + */ +typedef struct +{ + SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]; +} SDL_MessageBoxColorScheme; + +/** + * \brief MessageBox structure containing title, text, window, etc. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxFlags */ + SDL_Window *window; /**< Parent window, can be NULL */ + const char *title; /**< UTF-8 title */ + const char *message; /**< UTF-8 message text */ + + int numbuttons; + const SDL_MessageBoxButtonData *buttons; + + const SDL_MessageBoxColorScheme *colorScheme; /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */ +} SDL_MessageBoxData; + +/** + * \brief Create a modal message box. + * + * \param messagebox The SDL_MessageBox structure with title, text, etc. + * + * \return -1 on error, otherwise 0 and buttonid contains user id of button + * hit or -1 if dialog was closed. + * + * \note This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or + * closes the messagebox. + */ +extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +/** + * \brief Create a simple modal message box + * + * \param flags ::SDL_MessageBoxFlags + * \param title UTF-8 title text + * \param message UTF-8 message text + * \param window The parent window, or NULL for no parent + * + * \return 0 on success, -1 on error + * + * \sa SDL_ShowMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_messagebox_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_mouse.h b/src/eepp/helper/SDL2/include/SDL_mouse.h index 1650794f5..e0cb8e625 100644 --- a/src/eepp/helper/SDL2/include/SDL_mouse.h +++ b/src/eepp/helper/SDL2/include/SDL_mouse.h @@ -58,6 +58,25 @@ extern "C" { typedef struct SDL_Cursor SDL_Cursor; /* Implementation dependent */ +/** + * \brief Cursor types for SDL_CreateSystemCursor. + */ +typedef enum +{ + SDL_SYSTEM_CURSOR_ARROW, // Arrow + SDL_SYSTEM_CURSOR_IBEAM, // I-beam + SDL_SYSTEM_CURSOR_WAIT, // Wait + SDL_SYSTEM_CURSOR_CROSSHAIR, // Crosshair + SDL_SYSTEM_CURSOR_WAITARROW, // Small wait cursor (or Wait if not available) + SDL_SYSTEM_CURSOR_SIZENWSE, // Double arrow pointing northwest and southeast + SDL_SYSTEM_CURSOR_SIZENESW, // Double arrow pointing northeast and southwest + SDL_SYSTEM_CURSOR_SIZEWE, // Double arrow pointing west and east + SDL_SYSTEM_CURSOR_SIZENS, // Double arrow pointing north and south + SDL_SYSTEM_CURSOR_SIZEALL, // Four pointed arrow pointing north, south, east, and west + SDL_SYSTEM_CURSOR_NO, // Slashed circle or crossbones + SDL_SYSTEM_CURSOR_HAND, // Hand + SDL_NUM_SYSTEM_CURSORS +} SDL_SystemCursor; /* Function prototypes */ @@ -74,7 +93,7 @@ extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); * mouse cursor position relative to the focus window for the currently * selected mouse. You can pass NULL for either x or y. */ -extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y); +extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); /** * \brief Retrieve the relative state of the mouse. @@ -83,7 +102,7 @@ extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y); * be tested using the SDL_BUTTON(X) macros, and x and y are set to the * mouse deltas since the last call to SDL_GetRelativeMouseState(). */ -extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); +extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); /** * \brief Moves the mouse to the given position within the window. @@ -154,6 +173,13 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y); +/** + * \brief Create a system cursor. + * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); + /** * \brief Set the active cursor. */ diff --git a/src/eepp/helper/SDL2/include/SDL_opengl.h b/src/eepp/helper/SDL2/include/SDL_opengl.h index 10474c981..e1584ae8a 100644 --- a/src/eepp/helper/SDL2/include/SDL_opengl.h +++ b/src/eepp/helper/SDL2/include/SDL_opengl.h @@ -44,6 +44,10 @@ #define NO_SDL_GLEXT 1 #endif +#ifdef __FreeBSD__ /* !!! FIXME: temp compiler warning fix... */ +#define NO_SDL_GLEXT 1 +#endif + #ifdef __glext_h_ /* Someone has already included glext.h */ #define NO_SDL_GLEXT diff --git a/src/eepp/helper/SDL2/include/SDL_pixels.h b/src/eepp/helper/SDL2/include/SDL_pixels.h index 50f80fae4..99b475f3d 100644 --- a/src/eepp/helper/SDL2/include/SDL_pixels.h +++ b/src/eepp/helper/SDL2/include/SDL_pixels.h @@ -114,9 +114,10 @@ enum #define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D) #define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \ - ((1 << 31) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ + ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ ((bits) << 8) | ((bytes) << 0)) +#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F) #define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F) #define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F) #define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F) @@ -140,8 +141,9 @@ enum (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) +/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ #define SDL_ISPIXELFORMAT_FOURCC(format) \ - ((format) && !((format) & 0x80000000)) + ((format) && (SDL_PIXELFLAG(format) != 1)) /* Note: If you modify this list, update SDL_GetPixelFormatName() */ enum diff --git a/src/eepp/helper/SDL2/include/SDL_render.h b/src/eepp/helper/SDL2/include/SDL_render.h index 1832281ae..0694540b5 100644 --- a/src/eepp/helper/SDL2/include/SDL_render.h +++ b/src/eepp/helper/SDL2/include/SDL_render.h @@ -373,7 +373,7 @@ extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, const void *pixels, int pitch); /** - * \brief Lock a portion of the texture for pixel access. + * \brief Lock a portion of the texture for write-only pixel access. * * \param texture The texture to lock for access, which was created with * ::SDL_TEXTUREACCESS_STREAMING. @@ -413,10 +413,55 @@ extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *rendere * \param texture The targeted texture, which must be created with the SDL_TEXTUREACCESS_TARGET flag, or NULL for the default render target * * \return 0 on success, or -1 on error + * + * \sa SDL_GetRenderTarget() */ extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture); +/** + * \brief Get the current render target or NULL for the default render target. + * + * \return The current render target + * + * \sa SDL_SetRenderTarget() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); + +/** + * \brief Set device independent resolution for rendering + * + * \param w The width of the logical resolution + * \param h The height of the logical resolution + * + * This function uses the viewport and scaling functionality to allow a fixed logical + * resolution for rendering, regardless of the actual output resolution. If the actual + * output resolution doesn't have the same aspect ratio the output rendering will be + * centered within the output display. + * + * If the output display is a window, mouse events in the window will be filtered + * and scaled so they seem to arrive within the logical resolution. + * + * \note If this function results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. + * + * \sa SDL_RenderGetLogicalSize() + * \sa SDL_RenderSetScale() + * \sa SDL_RenderSetViewport() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); + +/** + * \brief Get device independent resolution for rendering + * + * \param w A pointer filled with the width of the logical resolution + * \param h A pointer filled with the height of the logical resolution + * + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *y); + /** * \brief Set the drawing area for rendering on the current target. * @@ -426,16 +471,52 @@ extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, * * \note When the window is resized, the current viewport is automatically * centered within the new window size. + * + * \sa SDL_RenderGetViewport() + * \sa SDL_RenderSetLogicalSize() */ extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect); /** * \brief Get the drawing area for the current target. + * + * \sa SDL_RenderSetViewport() */ extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect); +/** + * \brief Set the drawing scale for rendering on the current target. + * + * \param scaleX The horizontal scaling factor + * \param scaleY The vertical scaling factor + * + * The drawing coordinates are scaled by the x/y scaling factors + * before they are used by the renderer. This allows resolution + * independent drawing with a single coordinate system. + * + * \note If this results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. For best results use integer scaling factors. + * + * \sa SDL_RenderGetScale() + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * \brief Get the drawing scale for the current target. + * + * \param scaleX A pointer filled in with the horizontal scaling factor + * \param scaleY A pointer filled in with the vertical scaling factor + * + * \sa SDL_RenderSetScale() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + /** * \brief Set the color used for drawing operations (Rect, Line and Clear). * @@ -672,6 +753,28 @@ extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); +/** + * \brief Bind the texture to the current OpenGL/ES/ES2 context for use with + * OpenGL instructions. + * + * \param texture The SDL texture to bind + * \param texw A pointer to a float that will be filled with the texture width + * \param texh A pointer to a float that will be filled with the texture height + * + * \return 0 on success, or -1 if the operation is not supported + */ +extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); + +/** + * \brief Unbind a texture from the current OpenGL/ES/ES2 context. + * + * \param texture The SDL texture to unbind + * + * \return 0 on success, or -1 if the operation is not supported + */ +extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); + + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/eepp/helper/SDL2/include/SDL_rwops.h b/src/eepp/helper/SDL2/include/SDL_rwops.h index 87715f5ba..dbd2a0ce0 100644 --- a/src/eepp/helper/SDL2/include/SDL_rwops.h +++ b/src/eepp/helper/SDL2/include/SDL_rwops.h @@ -45,14 +45,19 @@ extern "C" { */ typedef struct SDL_RWops { + /** + * Return the size of the file in this rwops, or -1 if unknown + */ + Sint64 (SDLCALL * size) (struct SDL_RWops * context); + /** * Seek to \c offset relative to \c whence, one of stdio's whence values: * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END * * \return the final offset in the data stream. */ - long (SDLCALL * seek) (struct SDL_RWops * context, long offset, - int whence); + Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, + int whence); /** * Read up to \c maxnum objects each of size \c size from the data @@ -60,8 +65,8 @@ typedef struct SDL_RWops * * \return the number of objects read, or 0 at error or end of file. */ - size_t(SDLCALL * read) (struct SDL_RWops * context, void *ptr, - size_t size, size_t maxnum); + size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, + size_t size, size_t maxnum); /** * Write exactly \c num objects each of size \c size from the area @@ -69,8 +74,8 @@ typedef struct SDL_RWops * * \return the number of objects written, or 0 at error or end of file. */ - size_t(SDLCALL * write) (struct SDL_RWops * context, const void *ptr, - size_t size, size_t num); + size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, + size_t size, size_t num); /** * Close and free an allocated SDL_RWops structure. @@ -166,6 +171,7 @@ extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); * Macros to easily read and write from an SDL_RWops structure. */ /*@{*/ +#define SDL_RWsize(ctx) (ctx)->size(ctx) #define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence) #define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, RW_SEEK_CUR) #define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n) @@ -180,6 +186,7 @@ extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); * Read an item of the specified endianness and return in native format. */ /*@{*/ +extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); @@ -194,6 +201,7 @@ extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); * Write an item of native format to the specified endianness. */ /*@{*/ +extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); diff --git a/src/eepp/helper/SDL2/include/SDL_stdinc.h b/src/eepp/helper/SDL2/include/SDL_stdinc.h index aaef5020b..d2002ba2e 100644 --- a/src/eepp/helper/SDL2/include/SDL_stdinc.h +++ b/src/eepp/helper/SDL2/include/SDL_stdinc.h @@ -340,7 +340,7 @@ do { \ /* We can count on memcpy existing on Mac OS X and being well-tuned. */ #if defined(__MACOSX__) #define SDL_memcpy memcpy -#elif defined(__GNUC__) && defined(i386) +#elif defined(__GNUC__) && defined(i386) && !defined(__WIN32__) #define SDL_memcpy(dst, src, len) \ do { \ int u0, u1, u2; \ @@ -633,8 +633,10 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, #endif #ifndef HAVE_M_PI +#ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 /* pi */ #endif +#endif #ifdef HAVE_ATAN #define SDL_atan atan @@ -748,8 +750,8 @@ extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, const char *inbuf, size_t inbytesleft); #define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/eepp/helper/SDL2/include/SDL_system.h b/src/eepp/helper/SDL2/include/SDL_system.h new file mode 100644 index 000000000..47e557575 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_system.h @@ -0,0 +1,106 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef _SDL_system_h +#define _SDL_system_h + +#include "SDL_stdinc.h" + +#if defined(__IPHONEOS__) && __IPHONEOS__ +#include "SDL_video.h" +#include "SDL_keyboard.h" +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* Platform specific functions for iOS */ +#if defined(__IPHONEOS__) && __IPHONEOS__ + +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#if defined(__ANDROID__) && __ANDROID__ + +/* Get the JNI environment for the current thread + This returns JNIEnv*, but the prototype is void* so we don't need jni.h + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(); + +/* Get the SDL Activity object for the application + This returns jobject, but the prototype is void* so we don't need jni.h + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(); + +/* See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/* Get the path used for internal storage for this application. + This path is unique to your application and cannot be written to + by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(); + +/* Get the current state of external storage, a bitmask of these values: + SDL_ANDROID_EXTERNAL_STORAGE_READ + SDL_ANDROID_EXTERNAL_STORAGE_WRITE + If external storage is currently unavailable, this will return 0. +*/ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(); + +/* Get the path used for external storage for this application. + This path is unique to your application, but is public and can be + written to by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); + +#endif /* __ANDROID__ */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_system_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitkeyboard.h b/src/eepp/helper/SDL2/include/SDL_test.h old mode 100755 new mode 100644 similarity index 67% rename from src/eepp/helper/SDL2/src/video/uikit/SDL_uikitkeyboard.h rename to src/eepp/helper/SDL2/include/SDL_test.h index 5ed736173..af7613316 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitkeyboard.h +++ b/src/eepp/helper/SDL2/include/SDL_test.h @@ -19,9 +19,29 @@ 3. This notice may not be removed or altered from any source distribution. */ -#ifndef sdl_uikitkeyboard_h -#define sdl_uikitkeyboard_h +/** + * \file SDL_test.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ +#ifndef _SDL_test_h +#define _SDL_test_h + +#include "SDL.h" +#include "SDL_test_common.h" +#include "SDL_test_font.h" +#include "SDL_test_random.h" +#include "SDL_test_fuzzer.h" +#include "SDL_test_crc32.h" +#include "SDL_test_md5.h" +#include "SDL_test_log.h" +#include "SDL_test_assert.h" +#include "SDL_test_harness.h" + +#include "begin_code.h" /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ @@ -29,10 +49,9 @@ extern "C" { /* *INDENT-ON* */ #endif -extern DECLSPEC int SDLCALL SDL_iPhoneKeyboardShow(SDL_Window * window); -extern DECLSPEC int SDLCALL SDL_iPhoneKeyboardHide(SDL_Window * window); -extern DECLSPEC SDL_bool SDLCALL SDL_iPhoneKeyboardIsShown(SDL_Window * window); -extern DECLSPEC int SDLCALL SDL_iPhoneKeyboardToggle(SDL_Window * window); +/* Function prototypes */ + +/* ADD STUFF HERE */ /* Ends C function definitions when using C++ */ #ifdef __cplusplus @@ -40,7 +59,8 @@ extern DECLSPEC int SDLCALL SDL_iPhoneKeyboardToggle(SDL_Window * window); } /* *INDENT-ON* */ #endif +#include "close_code.h" -#endif /* sdl_uikitkeyboard_h */ +#endif /* _SDL_test_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_assert.h b/src/eepp/helper/SDL2/include/SDL_test_assert.h new file mode 100644 index 000000000..d557a76fb --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_assert.h @@ -0,0 +1,102 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_assert.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Assert API for test code and test cases + * + */ + +#ifndef _SDL_test_assert_h +#define _SDL_test_assert_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief Fails the assert. + */ +#define ASSERT_FAIL 0 + +/** + * \brief Passes the assert. + */ +#define ASSERT_PASS 1 + +/** + * \brief Assert that logs and break execution flow on failures. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_Assert(int assertCondition, char *assertDescription); + +/** + * \brief Assert for test cases that logs but does not break execution flow on failures. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + * + * \returns Returns the assertCondition so it can be used to externall to break execution flow if desired. + */ +int SDLTest_AssertCheck(int assertCondition, char *assertDescription); + +/** + * \brief Resets the assert summary counters to zero. + */ +void SDLTest_ResetAssertSummary(); + +/** + * \brief Logs summary of all assertions (total, pass, fail) since last reset as INFO or ERROR. + */ +void SDLTest_LogAssertSummary(); + + +/** + * \brief Converts the current assert summary state to a test result. + * + * \returns TEST_RESULT_PASSED, TEST_RESULT_FAILED, or TEST_RESULT_NO_ASSERT + */ +int SDLTest_AssertSummaryToTestResult(); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_assert_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_common.h b/src/eepp/helper/SDL2/include/SDL_test_common.h new file mode 100644 index 000000000..5ccb1bf3f --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_common.h @@ -0,0 +1,182 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_common.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* Ported from original test\common.h file. */ + +#ifndef _SDL_test_common_h +#define _SDL_test_common_h + +#include "SDL.h" + +#ifdef __NDS__ +#define DEFAULT_WINDOW_WIDTH 256 +#define DEFAULT_WINDOW_HEIGHT (2*192) +#else +#define DEFAULT_WINDOW_WIDTH 640 +#define DEFAULT_WINDOW_HEIGHT 480 +#endif + +#define VERBOSE_VIDEO 0x00000001 +#define VERBOSE_MODES 0x00000002 +#define VERBOSE_RENDER 0x00000004 +#define VERBOSE_EVENT 0x00000008 +#define VERBOSE_AUDIO 0x00000010 + +typedef struct +{ + /* SDL init flags */ + char **argv; + Uint32 flags; + Uint32 verbose; + + /* Video info */ + const char *videodriver; + int display; + const char *window_title; + const char *window_icon; + Uint32 window_flags; + int window_x; + int window_y; + int window_w; + int window_h; + int depth; + int refresh_rate; + int num_windows; + SDL_Window **windows; + + /* Renderer info */ + const char *renderdriver; + Uint32 render_flags; + SDL_bool skip_renderer; + SDL_Renderer **renderers; + + /* Audio info */ + const char *audiodriver; + SDL_AudioSpec audiospec; + + /* GL settings */ + int gl_red_size; + int gl_green_size; + int gl_blue_size; + int gl_alpha_size; + int gl_buffer_size; + int gl_depth_size; + int gl_stencil_size; + int gl_double_buffer; + int gl_accum_red_size; + int gl_accum_green_size; + int gl_accum_blue_size; + int gl_accum_alpha_size; + int gl_stereo; + int gl_multisamplebuffers; + int gl_multisamplesamples; + int gl_retained_backing; + int gl_accelerated; + int gl_major_version; + int gl_minor_version; +} SDLTest_CommonState; + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* Function prototypes */ + +/** + * \brief Parse command line parameters and create common state. + * + * \param argv Array of command line parameters + * \param flags Flags indicating which subsystem to initialize (i.e. SDL_INIT_VIDEO | SDL_INIT_AUDIO) + * + * \returns Returns a newly allocated common state object. + */ +SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags); + +/** + * \brief Process one common argument. + * + * \param state The common state describing the test window to create. + * \param index The index of the argument to process in argv[]. + * + * \returns The number of arguments processed (i.e. 1 for --fullscreen, 2 for --video [videodriver], or -1 on error. + */ +int SDLTest_CommonArg(SDLTest_CommonState * state, int index); + +/** + * \brief Returns common usage information + * + * \param state The common state describing the test window to create. + * + * \returns String with usage information + */ +const char *SDLTest_CommonUsage(SDLTest_CommonState * state); + +/** + * \brief Open test window. + * + * \param state The common state describing the test window to create. + * + * \returns True if initialization succeeded, false otherwise + */ +SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state); + +/** + * \brief Common event handler for test windows. + * + * \param state The common state used to create test window. + * \param event The event to handle. + * \param done Flag indicating we are done. + * + */ +void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done); + +/** + * \brief Close test window. + * + * \param state The common state used to create test window. + * + */ +void SDLTest_CommonQuit(SDLTest_CommonState * state); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_common_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_crc32.h b/src/eepp/helper/SDL2/include/SDL_test_crc32.h new file mode 100644 index 000000000..ab64df093 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_crc32.h @@ -0,0 +1,128 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_crc32.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Implements CRC32 calculations (default output is Perl String::CRC32 compatible). + +*/ + +#ifndef _SDL_test_crc32_h +#define _SDL_test_crc32_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +/* ------------ Definitions --------- */ + +/* Definition shared by all CRC routines */ + +#ifndef CrcUint32 + #define CrcUint32 unsigned int +#endif +#ifndef CrcUint8 + #define CrcUint8 unsigned char +#endif + +#ifdef ORIGINAL_METHOD + #define CRC32_POLY 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */ +#else + #define CRC32_POLY 0xEDB88320 /* Perl String::CRC32 compatible */ +#endif + +/** + * Data structure for CRC32 (checksum) computation + */ + typedef struct { + CrcUint32 crc32_table[256]; /* CRC table */ + } SDLTest_Crc32Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * /brief Initialize the CRC context + * + * Note: The function initializes the crc table required for all crc calculations. + * + * /param crcContext pointer to context variable + * + * /returns 0 for OK, -1 on error + * + */ + int SDLTest_Crc32Init(SDLTest_Crc32Context * crcContext); + + +/** + * /brief calculate a crc32 from a data block + * + * /param crcContext pointer to context variable + * /param inBuf input buffer to checksum + * /param inLen length of input buffer + * /param crc32 pointer to Uint32 to store the final CRC into + * + * /returns 0 for OK, -1 on error + * + */ +int SDLTest_crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + +/* Same routine broken down into three steps */ +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + + +/** + * /brief clean up CRC context + * + * /param crcContext pointer to context variable + * + * /returns 0 for OK, -1 on error + * +*/ + +int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_crc32_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_font.h b/src/eepp/helper/SDL2/include/SDL_test_font.h new file mode 100644 index 000000000..6d8ca5327 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_font.h @@ -0,0 +1,66 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_font.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef _SDL_test_font_h +#define _SDL_test_font_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* Function prototypes */ + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the string. + * \param y The Y coordinate of the upper left corner of the string. + * \param s The string to draw. + * + * \returns Returns 0 on success, -1 on failure. + */ +int SDLTest_DrawString(SDL_Renderer * renderer, int x, int y, const char *s); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_font_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_fuzzer.h b/src/eepp/helper/SDL2/include/SDL_test_fuzzer.h new file mode 100644 index 000000000..8cd05f098 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_fuzzer.h @@ -0,0 +1,371 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_fuzzer.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Data generators for fuzzing test data in a reproducible way. + +*/ + +#ifndef _SDL_test_fuzzer_h +#define _SDL_test_fuzzer_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +/* + Based on GSOC code by Markus Kauppila +*/ + + +/** + * \file + * Note: The fuzzer implementation uses a static instance of random context + * internally which makes it thread-UNsafe. + */ + +/** + * Initializes the fuzzer for a test + * + * /param execKey Execution "Key" that initializes the random number generator uniquely for the test. + * + */ +void SDLTest_FuzzerInit(Uint64 execKey); + + +/** + * Returns a random Uint8 + * + * \returns Generated integer + */ +Uint8 SDLTest_RandomUint8(); + +/** + * Returns a random Sint8 + * + * \returns Generated signed integer + */ +Sint8 SDLTest_RandomSint8(); + + +/** + * Returns a random Uint16 + * + * \returns Generated integer + */ +Uint16 SDLTest_RandomUint16(); + +/** + * Returns a random Sint16 + * + * \returns Generated signed integer + */ +Sint16 SDLTest_RandomSint16(); + + +/** + * Returns a random integer + * + * \returns Generated integer + */ +Sint32 SDLTest_RandomSint32(); + + +/** + * Returns a random positive integer + * + * \returns Generated integer + */ +Uint32 SDLTest_RandomUint32(); + +/** + * Returns random Uint64. + * + * \returns Generated integer + */ +Uint64 SDLTest_RandomUint64(); + + +/** + * Returns random Sint64. + * + * \returns Generated signed integer + */ +Sint64 SDLTest_RandomSint64(); + +/** + * \returns random float in range [0.0 - 1.0[ + */ +float SDLTest_RandomUnitFloat(); + +/** + * \returns random double in range [0.0 - 1.0[ + */ +double SDLTest_RandomUnitDouble(); + +/** + * \returns random float. + * + */ +float SDLTest_RandomFloat(); + +/** + * \returns random double. + * + */ +double SDLTest_RandomDouble(); + +/** + * Returns a random boundary value for Uint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint8BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint8BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint8BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint8BoundaryValue(0, 255, SDL_FALSE) returns -1 (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint16BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint16BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint16BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint16BoundaryValue(0, 0xFFFF, SDL_FALSE) returns -1 (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint32BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint32BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint32BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint32BoundaryValue(0, 0xFFFFFFFF, SDL_FALSE) returns -1 (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint64BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint64BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint64BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint64BoundaryValue(0, 0xFFFFFFFFFFFFFFFF, SDL_FALSE) returns -1 (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint8BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint8BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint8BoundaryValue(-128, 99, SDL_FALSE) returns 100 + * RandomSint8BoundaryValue(-128, 127, SDL_FALSE) returns SINT8_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain); + + +/** + * Returns a random boundary value for Sint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint16BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint16BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint16BoundaryValue(SINT8_MIN, 99, SDL_FALSE) returns 100 + * RandomSint16BoundaryValue(SINT8_MIN, SINT8_MAX, SDL_FALSE) returns SINT16_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint32BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint32BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint32BoundaryValue(SINT32_MIN, 99, SDL_FALSE) returns 100 + * RandomSint32BoundaryValue(SINT32_MIN, SINT32_MAX, SDL_FALSE) returns SINT32_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint64BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint64BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint64BoundaryValue(SINT64_MIN, 99, SDL_FALSE) returns 100 + * RandomSint64BoundaryValue(SINT64_MIN, SINT32_MAX, SDL_FALSE) returns SINT64_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid or not? + * + * \returns Boundary value in given range or error value (-1) + */ +Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain); + + +/** + * Returns integer in range [min, max] (inclusive). + * Min and max values can be negative values. + * If Max in smaller tham min, then the values are swapped. + * Min and max are the same value, that value will be returned. + * + * \returns Generated integer + */ +Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max); + + +/** + * Generates random null-terminated string. The maximum length for + * the string is 255 characters and it can contain ASCII characters + * from 1 to 127. + * + * Note: Returned string needs to be deallocated. + * + * \returns newly allocated random string + */ +char * SDLTest_RandomAsciiString(); + + +/** + * Generates random null-terminated string. The maximum length for + * the string is defined by maxLenght parameter. + * String can contain ASCII characters from 1 to 127. + * + * Note: Returned string needs to be deallocated. + * + * \param maxLength Maximum length of the generated string + * + * \returns newly allocated random string + */ +char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength); + +/** + * Returns the invocation count for the fuzzer since last ...FuzzerInit. + */ +int SDLTest_GetFuzzerInvocationCount(); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_fuzzer_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_harness.h b/src/eepp/helper/SDL2/include/SDL_test_harness.h new file mode 100644 index 000000000..cf30600e2 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_harness.h @@ -0,0 +1,111 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_harness.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + Defines types for test case definitions and the test execution harness API. + + Based on original GSOC code by Markus Kauppila +*/ + +#ifndef _SDL_test_harness_h +#define _SDL_test_harness_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +//! Definitions for test case structures +#define TEST_ENABLED 1 +#define TEST_DISABLED 0 + +//! Definition of all the possible test return values of the test case method +#define TEST_ABORTED -1 +#define TEST_COMPLETED 0 +#define TEST_SKIPPED 1 + +//! Definition of all the possible test results for the harness +#define TEST_RESULT_PASSED 0 +#define TEST_RESULT_FAILED 1 +#define TEST_RESULT_NO_ASSERT 2 +#define TEST_RESULT_SKIPPED 3 +#define TEST_RESULT_SETUP_FAILURE 4 + +//!< Function pointer to a test case setup function (run before every test) +typedef void (*SDLTest_TestCaseSetUpFp)(void *arg); + +//!< Function pointer to a test case function +typedef void (*SDLTest_TestCaseFp)(void *arg); + +//!< Function pointer to a test case teardown function (run after every test) +typedef void (*SDLTest_TestCaseTearDownFp)(void *arg); + +/** + * Holds information about a single test case. + */ +typedef struct SDLTest_TestCaseReference { + /*!< Func2Stress */ + SDLTest_TestCaseFp testCase; + /*!< Short name (or function name) "Func2Stress" */ + char *name; + /*!< Long name or full description "This test pushes func2() to the limit." */ + char *description; + /*!< Set to TEST_ENABLED or TEST_DISABLED (test won't be run) */ + int enabled; +} SDLTest_TestCaseReference; + +/** + * Holds information about a test suite (multiple test cases). + */ +typedef struct SDLTest_TestSuiteReference { + /*!< "PlatformSuite" */ + char *name; + /*!< The function that is run before each test. NULL skips. */ + SDLTest_TestCaseSetUpFp testSetUp; + /*!< The test cases that are run as part of the suite. Last item should be NULL. */ + const SDLTest_TestCaseReference **testCases; + /*!< The function that is run after each test. NULL skips. */ + SDLTest_TestCaseTearDownFp testTearDown; +} SDLTest_TestSuiteReference; + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_harness_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_log.h b/src/eepp/helper/SDL2/include/SDL_test_log.h new file mode 100644 index 000000000..e6b8d2b5c --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_log.h @@ -0,0 +1,71 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_log.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Wrapper to log in the TEST category + * + */ + +#ifndef _SDL_test_log_h +#define _SDL_test_log_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief Prints given message with a timestamp in the TEST category and INFO priority. + * + * \param fmt Message to be logged + */ +void SDLTest_Log(char *fmt, ...); + +/** + * \brief Prints given message with a timestamp in the TEST category and the ERROR priority. + * + * \param fmt Message to be logged + */ +void SDLTest_LogError(char *fmt, ...); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_log_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_md5.h b/src/eepp/helper/SDL2/include/SDL_test_md5.h new file mode 100644 index 000000000..0c4df8756 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_md5.h @@ -0,0 +1,133 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_md5.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + *********************************************************************** + ** Header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** +*/ + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** +*/ + +#ifndef _SDL_test_md5_h +#define _SDL_test_md5_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* ------------ Definitions --------- */ + +/* typedef a 32-bit type */ + typedef unsigned long int MD5UINT4; + +/* Data structure for MD5 (Message-Digest) computation */ + typedef struct { + MD5UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + MD5UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after Md5Final call */ + } SDLTest_Md5Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * /brief initialize the context + * + * /param mdContext pointer to context variable + * + * Note: The function initializes the message-digest context + * mdContext. Call before each new use of the context - + * all fields are set to zero. + */ + void SDLTest_Md5Init(SDLTest_Md5Context * mdContext); + + +/** + * /brief update digest from variable length data + * + * /param mdContext pointer to context variable + * /param inBuf pointer to data array/string + * /param inLen length of data array/string + * + * Note: The function updates the message-digest context to account + * for the presence of each of the characters inBuf[0..inLen-1] + * in the message whose digest is being computed. +*/ + + void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf, + unsigned int inLen); + + +/* + * /brief complete digest computation + * + * /param mdContext pointer to context variable + * + * Note: The function terminates the message-digest computation and + * ends with the desired message digest in mdContext.digest[0..15]. + * Always call before using the digest[] variable. +*/ + + void SDLTest_Md5Final(SDLTest_Md5Context * mdContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_md5_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_test_random.h b/src/eepp/helper/SDL2/include/SDL_test_random.h new file mode 100644 index 000000000..a1175b2f9 --- /dev/null +++ b/src/eepp/helper/SDL2/include/SDL_test_random.h @@ -0,0 +1,119 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_random.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + A "32-bit Multiply with carry random number generator. Very fast. + Includes a list of recommended multipliers. + + multiply-with-carry generator: x(n) = a*x(n-1) + carry mod 2^32. + period: (a*2^31)-1 + +*/ + +#ifndef _SDL_test_random_h +#define _SDL_test_random_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* --- Definitions */ + +/* + * Macros that return a random number in a specific format. + */ +#define SDLTest_RandomInt(c) ((int)SDLTest_Random(c)) + +/* + * Context structure for the random number generator state. + */ + typedef struct { + unsigned int a; + unsigned int x; + unsigned int c; + unsigned int ah; + unsigned int al; + } SDLTest_RandomContext; + + +/* --- Function prototypes */ + +/** + * \brief Initialize random number generator with two integers. + * + * Note: The random sequence of numbers returned by ...Random() is the + * same for the same two integers and has a period of 2^31. + * + * \param rndContext pointer to context structure + * \param xi integer that defines the random sequence + * \param ci integer that defines the random sequence + * + */ + void SDLTest_RandomInit(SDLTest_RandomContext * rndContext, unsigned int xi, + unsigned int ci); + +/** + * \brief Initialize random number generator based on current system time. + * + * \param rndContext pointer to context structure + * + */ + void SDLTest_RandomInitTime(SDLTest_RandomContext *rndContext); + + +/** + * \brief Initialize random number generator based on current system time. + * + * Note: ...RandomInit() or ...RandomInitTime() must have been called + * before using this function. + * + * \param rndContext pointer to context structure + * + * \returns A random number (32bit unsigned integer) + * + */ + unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_test_random_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_thread.h b/src/eepp/helper/SDL2/include/SDL_thread.h index 65a2253b4..6eb720145 100644 --- a/src/eepp/helper/SDL2/include/SDL_thread.h +++ b/src/eepp/helper/SDL2/include/SDL_thread.h @@ -86,9 +86,7 @@ typedef int (SDLCALL * SDL_ThreadFunction) (void *data); * library! */ #define SDL_PASSED_BEGINTHREAD_ENDTHREAD -#ifndef _WIN32_WCE #include /* This has _beginthread() and _endthread() defined! */ -#endif typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, unsigned (__stdcall * @@ -106,21 +104,11 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); -#if defined(_WIN32_WCE) - -/** - * Create a thread. - */ -#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, NULL, NULL) - -#else - /** * Create a thread. */ #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, _beginthreadex, _endthreadex) -#endif #else /** diff --git a/src/eepp/helper/SDL2/include/SDL_touch.h b/src/eepp/helper/SDL2/include/SDL_touch.h index 727f82af8..cb1324516 100644 --- a/src/eepp/helper/SDL2/include/SDL_touch.h +++ b/src/eepp/helper/SDL2/include/SDL_touch.h @@ -71,7 +71,8 @@ struct SDL_Touch { float y_max,y_min; Uint16 xres,yres,pressureres; float native_xres,native_yres,native_pressureres; - float tilt; /* for future use */ + float tilt_x; /* for future use */ + float tilt_y; /* for future use */ float rotation; /* for future use */ /* Data common to all touch */ @@ -119,6 +120,6 @@ struct SDL_Touch { #endif #include "close_code.h" -#endif /* _SDL_mouse_h */ +#endif /* _SDL_touch_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/include/SDL_video.h b/src/eepp/helper/SDL2/include/SDL_video.h index 878c053f0..5fdba063f 100644 --- a/src/eepp/helper/SDL2/include/SDL_video.h +++ b/src/eepp/helper/SDL2/include/SDL_video.h @@ -84,6 +84,7 @@ typedef struct * \sa SDL_SetWindowIcon() * \sa SDL_SetWindowPosition() * \sa SDL_SetWindowSize() + * \sa SDL_SetWindowBordered() * \sa SDL_SetWindowTitle() * \sa SDL_ShowWindow() */ @@ -183,22 +184,25 @@ typedef enum SDL_GL_RETAINED_BACKING, SDL_GL_CONTEXT_MAJOR_VERSION, SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, SDL_GL_CONTEXT_FLAGS, - SDL_GL_CONTEXT_PROFILE_MASK + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT } SDL_GLattr; typedef enum { SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, - SDL_GL_CONTEXT_PROFILE_ES2 = 0x0004 + SDL_GL_CONTEXT_PROFILE_ES = 0x0004 } SDL_GLprofile; typedef enum { SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, - SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004 + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 } SDL_GLcontextFlag; @@ -513,6 +517,42 @@ extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, */ extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, int *h); + +/** + * \brief Set the minimum size of a window's client area. + * + * \note You can't change the minimum size of a fullscreen window, it + * automatically matches the size of the display mode. + * + * \sa SDL_GetWindowMinimumSize() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, + int min_w, int min_h); + +/** + * \brief Get the minimum size of a window's client area. + * + * \sa SDL_SetWindowMinimumSize() + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, + int *w, int *h); + +/** + * \brief Set the border state of a window. + * + * This will add or remove the window's SDL_WINDOW_BORDERLESS flag and + * add or remove the border from the actual window. This is a no-op if the + * window's border already matches the requested state. + * + * \param window The window of which to change the border state. + * \param bordered SDL_FALSE to remove border, SDL_TRUE to add border. + * + * \note You can't change the border state of a fullscreen window. + * + * \sa SDL_GetWindowFlags() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, + SDL_bool bordered); /** * \brief Show a window. @@ -788,7 +828,9 @@ extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, * \brief Set the swap interval for the current OpenGL context. * * \param interval 0 for immediate updates, 1 for updates synchronized with the - * vertical retrace. + * vertical retrace. If the system supports it, you may + * specify -1 to allow late swaps to happen immediately + * instead of waiting for the next retrace. * * \return 0 on success, or -1 if setting the swap interval is not supported. * @@ -800,8 +842,10 @@ extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); * \brief Get the swap interval for the current OpenGL context. * * \return 0 if there is no vertical retrace synchronization, 1 if the buffer - * swap is synchronized with the vertical retrace, and -1 if getting - * the swap interval is not supported. + * swap is synchronized with the vertical retrace, and -1 if late + * swaps happen immediately instead of waiting for the next retrace. + * If the system can't determine the swap interval, or there isn't a + * valid current context, this will return 0 as a safe default. * * \sa SDL_GL_SetSwapInterval() */ diff --git a/src/eepp/helper/SDL2/java/src/org/libsdl/app/SDLActivity.java b/src/eepp/helper/SDL2/java/src/org/libsdl/app/SDLActivity.java index 1ea8b1fa6..dc7aa3198 100644 --- a/src/eepp/helper/SDL2/java/src/org/libsdl/app/SDLActivity.java +++ b/src/eepp/helper/SDL2/java/src/org/libsdl/app/SDLActivity.java @@ -9,6 +9,11 @@ import javax.microedition.khronos.egl.*; import android.app.*; import android.content.*; import android.view.*; +import android.view.inputmethod.BaseInputConnection; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import android.widget.AbsoluteLayout; import android.os.*; import android.util.Log; import android.graphics.*; @@ -26,9 +31,14 @@ import java.lang.*; */ public class SDLActivity extends Activity { + // Keep track of the paused state + public static boolean mIsPaused; + // Main components private static SDLActivity mSingleton; private static SDLSurface mSurface; + private static View mTextEdit; + private static ViewGroup mLayout; // This is what SDL runs in. It invokes SDL_main(), eventually private static Thread mSDLThread; @@ -61,24 +71,32 @@ public class SDLActivity extends Activity { // So we can call stuff from static callbacks mSingleton = this; + // Keep track of the paused state + mIsPaused = false; + // Set up the surface mSurface = new SDLSurface(getApplication()); - setContentView(mSurface); + + mLayout = new AbsoluteLayout(this); + mLayout.addView(mSurface); + + setContentView(mLayout); + SurfaceHolder holder = mSurface.getHolder(); } // Events - protected void onPause() { + /*protected void onPause() { Log.v("SDL", "onPause()"); super.onPause(); - SDLActivity.nativePause(); + // Don't call SDLActivity.nativePause(); here, it will be called by SDLSurface::surfaceDestroyed } protected void onResume() { Log.v("SDL", "onResume()"); super.onResume(); - SDLActivity.nativeResume(); - } + // Don't call SDLActivity.nativeResume(); here, it will be called via SDLSurface::surfaceChanged->SDLActivity::startApp + }*/ protected void onDestroy() { super.onDestroy(); @@ -100,13 +118,26 @@ public class SDLActivity extends Activity { } // Messages from the SDLMain thread - static int COMMAND_CHANGE_TITLE = 1; + static final int COMMAND_CHANGE_TITLE = 1; + static final int COMMAND_UNUSED = 2; + static final int COMMAND_TEXTEDIT_HIDE = 3; // Handler for the messages Handler commandHandler = new Handler() { + @Override public void handleMessage(Message msg) { - if (msg.arg1 == COMMAND_CHANGE_TITLE) { + switch (msg.arg1) { + case COMMAND_CHANGE_TITLE: setTitle((String)msg.obj); + break; + case COMMAND_TEXTEDIT_HIDE: + if (mTextEdit != null) { + mTextEdit.setVisibility(View.GONE); + + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); + } + break; } } }; @@ -149,6 +180,10 @@ public class SDLActivity extends Activity { mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); } + public static void sendMessage(int command, int param) { + mSingleton.sendCommand(command, Integer.valueOf(param)); + } + public static Context getContext() { return mSingleton; } @@ -160,16 +195,67 @@ public class SDLActivity extends Activity { mSDLThread.start(); } else { - SDLActivity.nativeResume(); + /* + * Some Android variants may send multiple surfaceChanged events, so we don't need to resume every time + * every time we get one of those events, only if it comes after surfaceDestroyed + */ + if (mIsPaused) { + SDLActivity.nativeResume(); + SDLActivity.mIsPaused = false; + } } } + + static class ShowTextInputHandler implements Runnable { + /* + * This is used to regulate the pan&scan method to have some offset from + * the bottom edge of the input region and the top edge of an input + * method (soft keyboard) + */ + static final int HEIGHT_PADDING = 15; + + public int x, y, w, h; + + public ShowTextInputHandler(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public void run() { + AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams( + w, h + HEIGHT_PADDING, x, y); + + if (mTextEdit == null) { + mTextEdit = new DummyEdit(getContext()); + + mLayout.addView(mTextEdit, params); + } else { + mTextEdit.setLayoutParams(params); + } + + mTextEdit.setVisibility(View.VISIBLE); + mTextEdit.requestFocus(); + + InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mTextEdit, 0); + } + + } + + public static void showTextInput(int x, int y, int w, int h) { + // Transfer the task to the main thread as a Runnable + mSingleton.commandHandler.post(new ShowTextInputHandler(x, y, w, h)); + } + // EGL functions public static boolean initEGL(int majorVersion, int minorVersion) { - if (SDLActivity.mEGLDisplay == null) { - //Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); + try { + if (SDLActivity.mEGLDisplay == null) { + Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); - try { EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); @@ -198,31 +284,20 @@ public class SDLActivity extends Activity { } EGLConfig config = configs[0]; - /*int EGL_CONTEXT_CLIENT_VERSION=0x3098; - int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, majorVersion, EGL10.EGL_NONE }; - EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, contextAttrs); - - if (ctx == EGL10.EGL_NO_CONTEXT) { - Log.e("SDL", "Couldn't create context"); - return false; - } - SDLActivity.mEGLContext = ctx;*/ SDLActivity.mEGLDisplay = dpy; SDLActivity.mEGLConfig = config; SDLActivity.mGLMajor = majorVersion; SDLActivity.mGLMinor = minorVersion; - - SDLActivity.createEGLSurface(); - } catch(Exception e) { - Log.v("SDL", e + ""); - for (StackTraceElement s : e.getStackTrace()) { - Log.v("SDL", s.toString()); - } } - } - else SDLActivity.createEGLSurface(); + return SDLActivity.createEGLSurface(); - return true; + } catch(Exception e) { + Log.v("SDL", e + ""); + for (StackTraceElement s : e.getStackTrace()) { + Log.v("SDL", s.toString()); + } + return false; + } } public static boolean createEGLContext() { @@ -249,18 +324,23 @@ public class SDLActivity extends Activity { return false; } - if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { - Log.e("SDL", "Old EGL Context doesnt work, trying with a new one"); - createEGLContext(); + if (egl.eglGetCurrentContext() != SDLActivity.mEGLContext) { if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { - Log.e("SDL", "Failed making EGL Context current"); - return false; + Log.e("SDL", "Old EGL Context doesnt work, trying with a new one"); + // TODO: Notify the user via a message that the old context could not be restored, and that textures need to be manually restored. + createEGLContext(); + if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { + Log.e("SDL", "Failed making EGL Context current"); + return false; + } } } SDLActivity.mEGLSurface = surface; return true; + } else { + Log.e("SDL", "Surface creation failed, display = " + SDLActivity.mEGLDisplay + ", config = " + SDLActivity.mEGLConfig); + return false; } - return false; } // EGL buffer flip @@ -408,6 +488,9 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, // Sensors private static SensorManager mSensorManager; + // Keep track of the surface size to normalize touch events + private static float mWidth, mHeight; + // Startup public SDLSurface(Context context) { super(context); @@ -419,21 +502,27 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, setOnKeyListener(this); setOnTouchListener(this); - mSensorManager = (SensorManager)context.getSystemService("sensor"); + mSensorManager = (SensorManager)context.getSystemService("sensor"); + + // Some arbitrary defaults to avoid a potential division by zero + mWidth = 1.0f; + mHeight = 1.0f; } // Called when we have a valid drawing surface public void surfaceCreated(SurfaceHolder holder) { Log.v("SDL", "surfaceCreated()"); holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); - SDLActivity.createEGLSurface(); enableSensor(Sensor.TYPE_ACCELEROMETER, true); } // Called when we lose the surface public void surfaceDestroyed(SurfaceHolder holder) { Log.v("SDL", "surfaceDestroyed()"); - SDLActivity.nativePause(); + if (!SDLActivity.mIsPaused) { + SDLActivity.mIsPaused = true; + SDLActivity.nativePause(); + } enableSensor(Sensor.TYPE_ACCELEROMETER, false); } @@ -486,6 +575,9 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, Log.v("SDL", "pixel format unknown " + format); break; } + + mWidth = (float) width; + mHeight = (float) height; SDLActivity.onNativeResize(width, height, sdlFormat); Log.v("SDL", "Window size:" + width + "x"+height); @@ -521,12 +613,12 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, final int touchDevId = event.getDeviceId(); final int pointerCount = event.getPointerCount(); // touchId, pointerId, action, x, y, pressure - int actionPointerIndex = event.getActionIndex(); + int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent. ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */ int pointerFingerId = event.getPointerId(actionPointerIndex); - int action = event.getActionMasked(); + int action = (event.getAction() & MotionEvent.ACTION_MASK); /* API 8: event.getActionMasked(); */ - float x = event.getX(actionPointerIndex); - float y = event.getY(actionPointerIndex); + float x = event.getX(actionPointerIndex) / mWidth; + float y = event.getY(actionPointerIndex) / mHeight; float p = event.getPressure(actionPointerIndex); if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) { @@ -534,8 +626,8 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, // changed since prev event. for (int i = 0; i < pointerCount; i++) { pointerFingerId = event.getPointerId(i); - x = event.getX(i); - y = event.getY(i); + x = event.getX(i) / mWidth; + y = event.getY(i) / mHeight; p = event.getPressure(i); SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p); } @@ -570,6 +662,104 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, event.values[2] / SensorManager.GRAVITY_EARTH); } } - + } +/* This is a fake invisible editor view that receives the input and defines the + * pan&scan region + */ +class DummyEdit extends View implements View.OnKeyListener { + InputConnection ic; + + public DummyEdit(Context context) { + super(context); + setFocusableInTouchMode(true); + setFocusable(true); + setOnKeyListener(this); + } + + @Override + public boolean onCheckIsTextEditor() { + return true; + } + + public boolean onKey(View v, int keyCode, KeyEvent event) { + + // This handles the hardware keyboard input + if (event.isPrintingKey()) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1); + } + return true; + } + + if (event.getAction() == KeyEvent.ACTION_DOWN) { + SDLActivity.onNativeKeyDown(keyCode); + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + SDLActivity.onNativeKeyUp(keyCode); + return true; + } + + return false; + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + ic = new SDLInputConnection(this, true); + + outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI + | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */; + + return ic; + } +} + +class SDLInputConnection extends BaseInputConnection { + + public SDLInputConnection(View targetView, boolean fullEditor) { + super(targetView, fullEditor); + + } + + @Override + public boolean sendKeyEvent(KeyEvent event) { + + /* + * This handles the keycodes from soft keyboard (and IME-translated + * input from hardkeyboard) + */ + int keyCode = event.getKeyCode(); + if (event.getAction() == KeyEvent.ACTION_DOWN) { + + SDLActivity.onNativeKeyDown(keyCode); + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + + SDLActivity.onNativeKeyUp(keyCode); + return true; + } + return super.sendKeyEvent(event); + } + + @Override + public boolean commitText(CharSequence text, int newCursorPosition) { + + nativeCommitText(text.toString(), newCursorPosition); + + return super.commitText(text, newCursorPosition); + } + + @Override + public boolean setComposingText(CharSequence text, int newCursorPosition) { + + nativeSetComposingText(text.toString(), newCursorPosition); + + return super.setComposingText(text, newCursorPosition); + } + + public native void nativeCommitText(String text, int newCursorPosition); + + public native void nativeSetComposingText(String text, int newCursorPosition); + +} diff --git a/src/eepp/helper/SDL2/src/SDL.c b/src/eepp/helper/SDL2/src/SDL.c old mode 100755 new mode 100644 index 9f8b2d4fc..0cf39ecc1 --- a/src/eepp/helper/SDL2/src/SDL.c +++ b/src/eepp/helper/SDL2/src/SDL.c @@ -44,7 +44,20 @@ extern int SDL_HelperWindowDestroy(void); /* The initialized subsystems */ static Uint32 SDL_initialized = 0; static Uint32 ticks_started = 0; +static SDL_bool SDL_bInMainQuit = SDL_FALSE; +static Uint8 SDL_SubsystemRefCount[ 32 ]; // keep a per subsystem init +/* helper func to return the index of the MSB in an int */ +int msb32_idx( Uint32 n) +{ + int b = 0; + if (!n) return -1; + +#define step(x) if (n >= ((Uint32)1) << x) b += x, n >>= x + step(16); step(8); step(4); step(2); step(1); +#undef step + return b; +} int SDL_InitSubSystem(Uint32 flags) @@ -55,11 +68,16 @@ SDL_InitSubSystem(Uint32 flags) SDL_StartTicks(); ticks_started = 1; } - if ((flags & SDL_INIT_TIMER) && !(SDL_initialized & SDL_INIT_TIMER)) { - if (SDL_TimerInit() < 0) { - return (-1); - } - SDL_initialized |= SDL_INIT_TIMER; + + if ((flags & SDL_INIT_TIMER) ){ + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]++; + SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] < 254 ); + if ( !(SDL_initialized & SDL_INIT_TIMER)) { + if (SDL_TimerInit() < 0) { + return (-1); + } + SDL_initialized |= SDL_INIT_TIMER; + } } #else if (flags & SDL_INIT_TIMER) { @@ -70,11 +88,15 @@ SDL_InitSubSystem(Uint32 flags) #if !SDL_VIDEO_DISABLED /* Initialize the video/event subsystem */ - if ((flags & SDL_INIT_VIDEO) && !(SDL_initialized & SDL_INIT_VIDEO)) { - if (SDL_VideoInit(NULL) < 0) { - return (-1); - } - SDL_initialized |= SDL_INIT_VIDEO; + if ((flags & SDL_INIT_VIDEO) ) { + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]++; + SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] < 254 ); + if ( !(SDL_initialized & SDL_INIT_VIDEO)) { + if (SDL_VideoInit(NULL) < 0) { + return (-1); + } + SDL_initialized |= SDL_INIT_VIDEO; + } } #else if (flags & SDL_INIT_VIDEO) { @@ -85,11 +107,15 @@ SDL_InitSubSystem(Uint32 flags) #if !SDL_AUDIO_DISABLED /* Initialize the audio subsystem */ - if ((flags & SDL_INIT_AUDIO) && !(SDL_initialized & SDL_INIT_AUDIO)) { - if (SDL_AudioInit(NULL) < 0) { - return (-1); - } - SDL_initialized |= SDL_INIT_AUDIO; + if ((flags & SDL_INIT_AUDIO) ) { + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]++; + SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] < 254 ); + if ( !(SDL_initialized & SDL_INIT_AUDIO)) { + if (SDL_AudioInit(NULL) < 0) { + return (-1); + } + SDL_initialized |= SDL_INIT_AUDIO; + } } #else if (flags & SDL_INIT_AUDIO) { @@ -100,10 +126,23 @@ SDL_InitSubSystem(Uint32 flags) #if !SDL_JOYSTICK_DISABLED /* Initialize the joystick subsystem */ - if ((flags & SDL_INIT_JOYSTICK) && !(SDL_initialized & SDL_INIT_JOYSTICK)) { - if (SDL_JoystickInit() < 0) { + if ( ( (flags & SDL_INIT_JOYSTICK) ) || ((flags & SDL_INIT_GAMECONTROLLER) ) ) { // game controller implies joystick + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]++; + SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] < 254 ); + if ( !(SDL_initialized & SDL_INIT_JOYSTICK) && SDL_JoystickInit() < 0) { return (-1); } + + if ((flags & SDL_INIT_GAMECONTROLLER) ) { + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]++; + SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] < 254 ); + if ( !(SDL_initialized & SDL_INIT_GAMECONTROLLER)) { + if (SDL_GameControllerInit() < 0) { + return (-1); + } + SDL_initialized |= SDL_INIT_GAMECONTROLLER; + } + } SDL_initialized |= SDL_INIT_JOYSTICK; } #else @@ -115,11 +154,15 @@ SDL_InitSubSystem(Uint32 flags) #if !SDL_HAPTIC_DISABLED /* Initialize the haptic subsystem */ - if ((flags & SDL_INIT_HAPTIC) && !(SDL_initialized & SDL_INIT_HAPTIC)) { - if (SDL_HapticInit() < 0) { - return (-1); - } - SDL_initialized |= SDL_INIT_HAPTIC; + if ((flags & SDL_INIT_HAPTIC) ) { + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]++; + SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] < 254 ); + if ( !(SDL_initialized & SDL_INIT_HAPTIC)) { + if (SDL_HapticInit() < 0) { + return (-1); + } + SDL_initialized |= SDL_INIT_HAPTIC; + } } #else if (flags & SDL_INIT_HAPTIC) { @@ -156,6 +199,7 @@ SDL_Init(Uint32 flags) SDL_InstallParachute(); } + SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) ); return (0); } @@ -164,33 +208,62 @@ SDL_QuitSubSystem(Uint32 flags) { /* Shut down requested initialized subsystems */ #if !SDL_JOYSTICK_DISABLED - if ((flags & SDL_initialized & SDL_INIT_JOYSTICK)) { - SDL_JoystickQuit(); - SDL_initialized &= ~SDL_INIT_JOYSTICK; + if ((flags & SDL_initialized & SDL_INIT_JOYSTICK) || (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER)) { + if ( (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER) ) { + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]--; + if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] == 0 ) { + SDL_GameControllerQuit(); + SDL_initialized &= ~SDL_INIT_GAMECONTROLLER; + } + } + + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]--; + if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] == 0 ) + { + SDL_JoystickQuit(); + SDL_initialized &= ~SDL_INIT_JOYSTICK; + } + } #endif #if !SDL_HAPTIC_DISABLED if ((flags & SDL_initialized & SDL_INIT_HAPTIC)) { - SDL_HapticQuit(); - SDL_initialized &= ~SDL_INIT_HAPTIC; + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]--; + if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] == 0 ) + { + SDL_HapticQuit(); + SDL_initialized &= ~SDL_INIT_HAPTIC; + } } #endif #if !SDL_AUDIO_DISABLED if ((flags & SDL_initialized & SDL_INIT_AUDIO)) { - SDL_AudioQuit(); - SDL_initialized &= ~SDL_INIT_AUDIO; + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]--; + if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] == 0 ) + { + SDL_AudioQuit(); + SDL_initialized &= ~SDL_INIT_AUDIO; + } } #endif #if !SDL_VIDEO_DISABLED if ((flags & SDL_initialized & SDL_INIT_VIDEO)) { - SDL_VideoQuit(); - SDL_initialized &= ~SDL_INIT_VIDEO; + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]--; + if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] == 0 ) + { + SDL_VideoQuit(); + SDL_initialized &= ~SDL_INIT_VIDEO; + } } #endif #if !SDL_TIMERS_DISABLED if ((flags & SDL_initialized & SDL_INIT_TIMER)) { - SDL_TimerQuit(); - SDL_initialized &= ~SDL_INIT_TIMER; + SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]--; + if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] == 0 ) + { + SDL_TimerQuit(); + SDL_initialized &= ~SDL_INIT_TIMER; + } } #endif } @@ -207,6 +280,7 @@ SDL_WasInit(Uint32 flags) void SDL_Quit(void) { + SDL_bInMainQuit = SDL_TRUE; /* Quit all subsystems */ #if defined(__WIN32__) SDL_HelperWindowDestroy(); @@ -219,6 +293,9 @@ SDL_Quit(void) SDL_ClearHints(); SDL_AssertionsQuit(); SDL_LogResetPriorities(); + + SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) ); + SDL_bInMainQuit = SDL_FALSE; } /* Get the library version number */ @@ -248,6 +325,8 @@ SDL_GetPlatform() { #if __AIX__ return "AIX"; +#elif __ANDROID__ + return "Android"; #elif __HAIKU__ /* Haiku must appear here before BeOS, since it also defines __BEOS__ */ return "Haiku"; @@ -288,11 +367,7 @@ SDL_GetPlatform() #elif __SOLARIS__ return "Solaris"; #elif __WIN32__ -#ifdef _WIN32_WCE - return "Windows CE"; -#else return "Windows"; -#endif #elif __IPHONEOS__ return "iPhone OS"; #else diff --git a/src/eepp/helper/SDL2/src/SDL_assert.c b/src/eepp/helper/SDL2/src/SDL_assert.c old mode 100755 new mode 100644 index 7eebfe1c6..1d0fd0539 --- a/src/eepp/helper/SDL2/src/SDL_assert.c +++ b/src/eepp/helper/SDL2/src/SDL_assert.c @@ -22,6 +22,8 @@ #include "SDL.h" #include "SDL_atomic.h" +#include "SDL_messagebox.h" +#include "SDL_video.h" #include "SDL_assert.h" #include "SDL_assert_c.h" #include "video/SDL_sysvideo.h" @@ -59,160 +61,13 @@ debug_print(const char *fmt, ...) __attribute__((format (printf, 1, 2))); static void debug_print(const char *fmt, ...) { -#ifdef __WIN32__ - /* Format into a buffer for OutputDebugStringA(). */ - char buf[1024]; - char *startptr; - char *ptr; - LPTSTR tstr; - int len; va_list ap; va_start(ap, fmt); - len = (int) SDL_vsnprintf(buf, sizeof (buf), fmt, ap); + SDL_LogMessageV(SDL_LOG_CATEGORY_ASSERT, SDL_LOG_PRIORITY_WARN, fmt, ap); va_end(ap); - - /* Visual C's vsnprintf() may not null-terminate the buffer. */ - if ((len >= sizeof (buf)) || (len < 0)) { - buf[sizeof (buf) - 1] = '\0'; - } - - /* Write it, sorting out the Unix newlines... */ - startptr = buf; - for (ptr = startptr; *ptr; ptr++) { - if (*ptr == '\n') { - *ptr = '\0'; - tstr = WIN_UTF8ToString(startptr); - OutputDebugString(tstr); - SDL_free(tstr); - OutputDebugString(TEXT("\r\n")); - startptr = ptr+1; - } - } - - /* catch that last piece if it didn't have a newline... */ - if (startptr != ptr) { - tstr = WIN_UTF8ToString(startptr); - OutputDebugString(tstr); - SDL_free(tstr); - } -#else - /* Unix has it easy. Just dump it to stderr. */ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fflush(stderr); -#endif } -#ifdef __WIN32__ -static SDL_assert_state SDL_Windows_AssertChoice = SDL_ASSERTION_ABORT; -static const SDL_assert_data *SDL_Windows_AssertData = NULL; - -static LRESULT CALLBACK -SDL_Assertion_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_CREATE: - { - /* !!! FIXME: all this code stinks. */ - const SDL_assert_data *data = SDL_Windows_AssertData; - char buf[1024]; - LPTSTR tstr; - const int w = 100; - const int h = 25; - const int gap = 10; - int x = gap; - int y = 50; - int len; - int i; - static const struct { - LPCTSTR name; - SDL_assert_state state; - } buttons[] = { - {TEXT("Abort"), SDL_ASSERTION_ABORT }, - {TEXT("Break"), SDL_ASSERTION_BREAK }, - {TEXT("Retry"), SDL_ASSERTION_RETRY }, - {TEXT("Ignore"), SDL_ASSERTION_IGNORE }, - {TEXT("Always Ignore"), SDL_ASSERTION_ALWAYS_IGNORE }, - }; - - len = (int) SDL_snprintf(buf, sizeof (buf), - "Assertion failure at %s (%s:%d), triggered %u time%s:\r\n '%s'", - data->function, data->filename, data->linenum, - data->trigger_count, (data->trigger_count == 1) ? "" : "s", - data->condition); - if ((len < 0) || (len >= sizeof (buf))) { - buf[sizeof (buf) - 1] = '\0'; - } - - tstr = WIN_UTF8ToString(buf); - CreateWindow(TEXT("STATIC"), tstr, - WS_VISIBLE | WS_CHILD | SS_LEFT, - x, y, 550, 100, - hwnd, (HMENU) 1, NULL, NULL); - SDL_free(tstr); - y += 110; - - for (i = 0; i < (sizeof (buttons) / sizeof (buttons[0])); i++) { - CreateWindow(TEXT("BUTTON"), buttons[i].name, - WS_VISIBLE | WS_CHILD, - x, y, w, h, - hwnd, (HMENU) buttons[i].state, NULL, NULL); - x += w + gap; - } - break; - } - - case WM_COMMAND: - SDL_Windows_AssertChoice = ((SDL_assert_state) (LOWORD(wParam))); - SDL_Windows_AssertData = NULL; - break; - - case WM_DESTROY: - SDL_Windows_AssertData = NULL; - break; - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} - -static SDL_assert_state -SDL_PromptAssertion_windows(const SDL_assert_data *data) -{ - HINSTANCE hInstance = 0; /* !!! FIXME? */ - HWND hwnd; - MSG msg; - WNDCLASS wc = {0}; - - SDL_Windows_AssertChoice = SDL_ASSERTION_ABORT; - SDL_Windows_AssertData = data; - - wc.lpszClassName = TEXT("SDL_assert"); - wc.hInstance = hInstance ; - wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); - wc.lpfnWndProc = SDL_Assertion_WndProc; - wc.hCursor = LoadCursor(0, IDC_ARROW); - - RegisterClass(&wc); - hwnd = CreateWindow(wc.lpszClassName, TEXT("SDL assertion failure"), - WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 150, 150, 570, 260, 0, 0, hInstance, 0); - - while (GetMessage(&msg, NULL, 0, 0) && (SDL_Windows_AssertData != NULL)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - DestroyWindow(hwnd); - UnregisterClass(wc.lpszClassName, hInstance); - return SDL_Windows_AssertChoice; -} -#endif - - static void SDL_AddAssertionToReport(SDL_assert_data *data) { /* (data) is always a static struct defined with the assert macros, so @@ -274,20 +129,39 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) const char *envr; SDL_assert_state state = SDL_ASSERTION_ABORT; SDL_Window *window; + SDL_MessageBoxData messagebox; + SDL_MessageBoxButtonData buttons[] = { + { 0, SDL_ASSERTION_RETRY, "Retry" }, + { 0, SDL_ASSERTION_BREAK, "Break" }, + { 0, SDL_ASSERTION_ABORT, "Abort" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, + SDL_ASSERTION_IGNORE, "Ignore" }, + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, + SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" } + }; + char *message; + int selected; (void) userdata; /* unused in default handler. */ - debug_print("\n\n" - "Assertion failure at %s (%s:%d), triggered %u time%s:\n" - " '%s'\n" - "\n", - data->function, data->filename, data->linenum, - data->trigger_count, (data->trigger_count == 1) ? "" : "s", - data->condition); + message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); + if (!message) { + /* Uh oh, we're in real trouble now... */ + return SDL_ASSERTION_ABORT; + } + SDL_snprintf(message, SDL_MAX_LOG_MESSAGE, + "Assertion failure at %s (%s:%d), triggered %u %s:\r\n '%s'", + data->function, data->filename, data->linenum, + data->trigger_count, (data->trigger_count == 1) ? "time" : "times", + data->condition); + + debug_print("\n\n%s\n\n", message); /* let env. variable override, so unit tests won't block in a GUI. */ envr = SDL_getenv("SDL_ASSERT"); if (envr != NULL) { + SDL_stack_free(message); + if (SDL_strcmp(envr, "abort") == 0) { return SDL_ASSERTION_ABORT; } else if (SDL_strcmp(envr, "break") == 0) { @@ -311,54 +185,65 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) } else { /* !!! FIXME: ungrab the input if we're not fullscreen? */ /* No need to mess with the window */ - window = 0; + window = NULL; } } - /* platform-specific UI... */ + /* Show a messagebox if we can, otherwise fall back to stdio */ + SDL_zero(messagebox); + messagebox.flags = SDL_MESSAGEBOX_WARNING; + messagebox.window = window; + messagebox.title = "Assertion Failed"; + messagebox.message = message; + messagebox.numbuttons = SDL_arraysize(buttons); + messagebox.buttons = buttons; -#ifdef __WIN32__ - state = SDL_PromptAssertion_windows(data); - -#elif defined __MACOSX__ && defined SDL_VIDEO_DRIVER_COCOA - /* This has to be done in an Objective-C (*.m) file, so we call out. */ - extern SDL_assert_state SDL_PromptAssertion_cocoa(const SDL_assert_data *); - state = SDL_PromptAssertion_cocoa(data); - -#else - /* this is a little hacky. */ - for ( ; ; ) { - char buf[32]; - fprintf(stderr, "Abort/Break/Retry/Ignore/AlwaysIgnore? [abriA] : "); - fflush(stderr); - if (fgets(buf, sizeof (buf), stdin) == NULL) { - break; - } - - if (SDL_strcmp(buf, "a") == 0) { - state = SDL_ASSERTION_ABORT; - break; - } else if (SDL_strcmp(buf, "b") == 0) { - state = SDL_ASSERTION_BREAK; - break; - } else if (SDL_strcmp(buf, "r") == 0) { - state = SDL_ASSERTION_RETRY; - break; - } else if (SDL_strcmp(buf, "i") == 0) { + if (SDL_ShowMessageBox(&messagebox, &selected) == 0) { + if (selected == -1) { state = SDL_ASSERTION_IGNORE; - break; - } else if (SDL_strcmp(buf, "A") == 0) { - state = SDL_ASSERTION_ALWAYS_IGNORE; - break; + } else { + state = (SDL_assert_state)selected; } } -#endif +#ifdef HAVE_STDIO_H + else + { + /* this is a little hacky. */ + for ( ; ; ) { + char buf[32]; + fprintf(stderr, "Abort/Break/Retry/Ignore/AlwaysIgnore? [abriA] : "); + fflush(stderr); + if (fgets(buf, sizeof (buf), stdin) == NULL) { + break; + } + + if (SDL_strcmp(buf, "a") == 0) { + state = SDL_ASSERTION_ABORT; + break; + } else if (SDL_strcmp(buf, "b") == 0) { + state = SDL_ASSERTION_BREAK; + break; + } else if (SDL_strcmp(buf, "r") == 0) { + state = SDL_ASSERTION_RETRY; + break; + } else if (SDL_strcmp(buf, "i") == 0) { + state = SDL_ASSERTION_IGNORE; + break; + } else if (SDL_strcmp(buf, "A") == 0) { + state = SDL_ASSERTION_ALWAYS_IGNORE; + break; + } + } + } +#endif /* HAVE_STDIO_H */ /* Re-enter fullscreen mode */ if (window) { SDL_RestoreWindow(window); } + SDL_stack_free(message); + return state; } diff --git a/src/eepp/helper/SDL2/src/SDL_assert_c.h b/src/eepp/helper/SDL2/src/SDL_assert_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/SDL_error.c b/src/eepp/helper/SDL2/src/SDL_error.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/SDL_error_c.h b/src/eepp/helper/SDL2/src/SDL_error_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/SDL_fatal.c b/src/eepp/helper/SDL2/src/SDL_fatal.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/SDL_fatal.h b/src/eepp/helper/SDL2/src/SDL_fatal.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/SDL_hints.c b/src/eepp/helper/SDL2/src/SDL_hints.c old mode 100755 new mode 100644 index b472f5322..72fd6c230 --- a/src/eepp/helper/SDL2/src/SDL_hints.c +++ b/src/eepp/helper/SDL2/src/SDL_hints.c @@ -57,7 +57,7 @@ SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority) { const char *env; - SDL_Hint *prev, *hint; + SDL_Hint *hint; if (!name || !value) { return SDL_FALSE; @@ -68,8 +68,7 @@ SDL_SetHintWithPriority(const char *name, const char *value, return SDL_FALSE; } - prev = NULL; - for (hint = SDL_hints; hint; prev = hint, hint = hint->next) { + for (hint = SDL_hints; hint; hint = hint->next) { if (SDL_strcmp(name, hint->name) == 0) { if (priority < hint->priority) { return SDL_FALSE; diff --git a/src/eepp/helper/SDL2/src/SDL_hints_c.h b/src/eepp/helper/SDL2/src/SDL_hints_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/SDL_log.c b/src/eepp/helper/SDL2/src/SDL_log.c old mode 100755 new mode 100644 index d38be9f93..b4f524326 --- a/src/eepp/helper/SDL2/src/SDL_log.c +++ b/src/eepp/helper/SDL2/src/SDL_log.c @@ -35,7 +35,9 @@ #endif #define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL +#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN #define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO +#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE typedef struct SDL_LogLevel { @@ -50,8 +52,10 @@ static void SDL_LogOutput(void *userdata, const char *message); static SDL_LogLevel *SDL_loglevels; -static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY; +static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; +static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; +static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY; static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput; static void *SDL_log_userdata = NULL; @@ -95,7 +99,9 @@ SDL_LogSetAllPriority(SDL_LogPriority priority) for (entry = SDL_loglevels; entry; entry = entry->next) { entry->priority = priority; } - SDL_application_priority = SDL_default_priority = priority; + SDL_default_priority = priority; + SDL_assert_priority = priority; + SDL_application_priority = priority; } void @@ -131,8 +137,12 @@ SDL_LogGetPriority(int category) } } - if (category == SDL_LOG_CATEGORY_APPLICATION) { + if (category == SDL_LOG_CATEGORY_TEST) { + return SDL_test_priority; + } else if (category == SDL_LOG_CATEGORY_APPLICATION) { return SDL_application_priority; + } else if (category == SDL_LOG_CATEGORY_ASSERT) { + return SDL_assert_priority; } else { return SDL_default_priority; } @@ -149,8 +159,10 @@ SDL_LogResetPriorities(void) SDL_free(entry); } - SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; SDL_default_priority = DEFAULT_PRIORITY; + SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; + SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; + SDL_test_priority = DEFAULT_TEST_PRIORITY; } void @@ -302,6 +314,19 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category)); __android_log_write(SDL_android_priority[priority], tag, message); } +#elif defined(__APPLE__) + extern void SDL_NSLog(const char *text); + { + char *text; + + text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); + if (text) { + SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message); + SDL_NSLog(text); + SDL_stack_free(text); + return; + } + } #endif #if HAVE_STDIO_H fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message); diff --git a/src/eepp/helper/SDL2/src/atomic/SDL_atomic.c b/src/eepp/helper/SDL2/src/atomic/SDL_atomic.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/atomic/SDL_spinlock.c b/src/eepp/helper/SDL2/src/atomic/SDL_spinlock.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audio.c b/src/eepp/helper/SDL2/src/audio/SDL_audio.c old mode 100755 new mode 100644 index 6c95e816e..8ef616a56 --- a/src/eepp/helper/SDL2/src/audio/SDL_audio.c +++ b/src/eepp/helper/SDL2/src/audio/SDL_audio.c @@ -314,7 +314,6 @@ SDL_RunAudio(void *devicep) int stream_len; void *udata; void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len); - int silence; Uint32 delay; /* For streaming when the buffer sizes don't match up */ Uint8 *istream; @@ -335,12 +334,6 @@ SDL_RunAudio(void *devicep) device->use_streamer = 0; if (device->convert.needed) { - if (device->convert.src_format == AUDIO_U8) { - silence = 0x80; - } else { - silence = 0; - } - #if 0 /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */ /* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */ if (device->convert.len_mult != 1 || device->convert.len_div != 1) { @@ -367,7 +360,6 @@ SDL_RunAudio(void *devicep) /* stream_len = device->convert.len; */ stream_len = device->spec.size; } else { - silence = device->spec.silence; stream_len = device->spec.size; } @@ -1036,7 +1028,7 @@ open_audio_device(const char *devname, int iscapture, char name[64]; SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1)); /* !!! FIXME: this is nasty. */ -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) +#if defined(__WIN32__) && !defined(HAVE_LIBC) #undef SDL_CreateThread device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL); #else diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audio_c.h b/src/eepp/helper/SDL2/src/audio/SDL_audio_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audiocvt.c b/src/eepp/helper/SDL2/src/audio/SDL_audiocvt.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audiodev.c b/src/eepp/helper/SDL2/src/audio/SDL_audiodev.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audiodev_c.h b/src/eepp/helper/SDL2/src/audio/SDL_audiodev_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audiomem.h b/src/eepp/helper/SDL2/src/audio/SDL_audiomem.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_audiotypecvt.c b/src/eepp/helper/SDL2/src/audio/SDL_audiotypecvt.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_mixer.c b/src/eepp/helper/SDL2/src/audio/SDL_mixer.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_sysaudio.h b/src/eepp/helper/SDL2/src/audio/SDL_sysaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/SDL_wave.c b/src/eepp/helper/SDL2/src/audio/SDL_wave.c old mode 100755 new mode 100644 index d6df07bbe..a18c1ab42 --- a/src/eepp/helper/SDL2/src/audio/SDL_wave.c +++ b/src/eepp/helper/SDL2/src/audio/SDL_wave.c @@ -49,7 +49,6 @@ static int InitMS_ADPCM(WaveFMT * format) { Uint8 *rogue_feel; - Uint16 extra_info; int i; /* Set the rogue pointer to the MS_ADPCM specific data */ @@ -62,7 +61,7 @@ InitMS_ADPCM(WaveFMT * format) SDL_SwapLE16(format->bitspersample); rogue_feel = (Uint8 *) format + sizeof(*format); if (sizeof(*format) == 16) { - extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]); + /*const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]);*/ rogue_feel += sizeof(Uint16); } MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]); @@ -233,7 +232,6 @@ static int InitIMA_ADPCM(WaveFMT * format) { Uint8 *rogue_feel; - Uint16 extra_info; /* Set the rogue pointer to the IMA_ADPCM specific data */ IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding); @@ -245,7 +243,7 @@ InitIMA_ADPCM(WaveFMT * format) SDL_SwapLE16(format->bitspersample); rogue_feel = (Uint8 *) format + sizeof(*format); if (sizeof(*format) == 16) { - extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]); + /*const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]);*/ rogue_feel += sizeof(Uint16); } IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]); @@ -424,6 +422,8 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc, /* FMT chunk */ WaveFMT *format = NULL; + SDL_zero(chunk); + /* Make sure we are passed a valid data source */ was_error = 0; if (src == NULL) { diff --git a/src/eepp/helper/SDL2/src/audio/SDL_wave.h b/src/eepp/helper/SDL2/src/audio/SDL_wave.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/alsa/SDL_alsa_audio.c b/src/eepp/helper/SDL2/src/audio/alsa/SDL_alsa_audio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/alsa/SDL_alsa_audio.h b/src/eepp/helper/SDL2/src/audio/alsa/SDL_alsa_audio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/android/SDL_androidaudio.c b/src/eepp/helper/SDL2/src/audio/android/SDL_androidaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/android/SDL_androidaudio.h b/src/eepp/helper/SDL2/src/audio/android/SDL_androidaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/arts/SDL_artsaudio.c b/src/eepp/helper/SDL2/src/audio/arts/SDL_artsaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/arts/SDL_artsaudio.h b/src/eepp/helper/SDL2/src/audio/arts/SDL_artsaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/baudio/SDL_beaudio.cc b/src/eepp/helper/SDL2/src/audio/baudio/SDL_beaudio.cc old mode 100755 new mode 100644 index 8540ea878..4c1eec5ea --- a/src/eepp/helper/SDL2/src/audio/baudio/SDL_beaudio.cc +++ b/src/eepp/helper/SDL2/src/audio/baudio/SDL_beaudio.cc @@ -48,9 +48,6 @@ FillSound(void *device, void *stream, size_t len, { SDL_AudioDevice *audio = (SDL_AudioDevice *) device; - /* Silence the buffer, since it's ours */ - SDL_memset(stream, audio->spec.silence, len); - /* Only do soemthing if audio is enabled */ if (!audio->enabled) return; diff --git a/src/eepp/helper/SDL2/src/audio/baudio/SDL_beaudio.h b/src/eepp/helper/SDL2/src/audio/baudio/SDL_beaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/bsd/SDL_bsdaudio.c b/src/eepp/helper/SDL2/src/audio/bsd/SDL_bsdaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/bsd/SDL_bsdaudio.h b/src/eepp/helper/SDL2/src/audio/bsd/SDL_bsdaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.c b/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.c old mode 100755 new mode 100644 index 53d3a08f1..1747bb2cd --- a/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.c +++ b/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.c @@ -280,8 +280,6 @@ outputCallback(void *inRefCon, while (remaining > 0) { if (this->hidden->bufferOffset >= this->hidden->bufferSize) { /* Generate the data */ - SDL_memset(this->hidden->buffer, this->spec.silence, - this->hidden->bufferSize); SDL_mutexP(this->mixer_lock); (*this->spec.callback)(this->spec.userdata, this->hidden->buffer, this->hidden->bufferSize); @@ -336,15 +334,16 @@ COREAUDIO_CloseDevice(_THIS) result = AudioOutputUnitStop(this->hidden->audioUnit); /* Remove the input callback */ - SDL_memset(&callback, '\0', sizeof(AURenderCallbackStruct)); + SDL_memset(&callback, 0, sizeof(AURenderCallbackStruct)); result = AudioUnitSetProperty(this->hidden->audioUnit, kAudioUnitProperty_SetRenderCallback, scope, bus, &callback, sizeof(callback)); - /* !!! FIXME: how does iOS free this? */ #if MACOSX_COREAUDIO CloseComponent(this->hidden->audioUnit); + #else + AudioComponentInstanceDispose(this->hidden->audioUnit); #endif this->hidden->audioUnitOpened = 0; @@ -390,7 +389,7 @@ prepare_audiounit(_THIS, const char *devname, int iscapture, desc.componentSubType = kAudioUnitSubType_DefaultOutput; comp = FindNextComponent(NULL, &desc); #else - desc.componentSubType = kAudioUnitSubType_RemoteIO; /* !!! FIXME: ? */ + desc.componentSubType = kAudioUnitSubType_RemoteIO; comp = AudioComponentFindNext(NULL, &desc); #endif @@ -431,7 +430,7 @@ prepare_audiounit(_THIS, const char *devname, int iscapture, CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)"); /* Set the audio callback */ - SDL_memset(&callback, '\0', sizeof(AURenderCallbackStruct)); + SDL_memset(&callback, 0, sizeof(AURenderCallbackStruct)); callback.inputProc = ((iscapture) ? inputCallback : outputCallback); callback.inputProcRefCon = this; result = AudioUnitSetProperty(this->hidden->audioUnit, @@ -540,8 +539,16 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl) impl->DetectDevices = COREAUDIO_DetectDevices; #else impl->OnlyHasDefaultOutputDevice = 1; + + /* Set category to ambient sound so that other music continues playing. + You can change this at runtime in your own code if you need different + behavior. If this is common, we can add an SDL hint for this. + */ + AudioSessionInitialize(NULL, NULL, NULL, nil); + UInt32 category = kAudioSessionCategory_AmbientSound; + AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(UInt32), &category); #endif - + impl->ProvidesOwnCallbackThread = 1; return 1; /* this audio target is available. */ diff --git a/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.h b/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.h old mode 100755 new mode 100644 index 65941f584..e6b47c8bc --- a/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.h +++ b/src/eepp/helper/SDL2/src/audio/coreaudio/SDL_coreaudio.h @@ -35,6 +35,8 @@ #if MAC_OS_X_VERSION_MAX_ALLOWED <= 1050 #include #endif +#else +#include #endif #include diff --git a/src/eepp/helper/SDL2/src/audio/directsound/SDL_directsound.c b/src/eepp/helper/SDL2/src/audio/directsound/SDL_directsound.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/directsound/SDL_directsound.h b/src/eepp/helper/SDL2/src/audio/directsound/SDL_directsound.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/disk/SDL_diskaudio.c b/src/eepp/helper/SDL2/src/audio/disk/SDL_diskaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/disk/SDL_diskaudio.h b/src/eepp/helper/SDL2/src/audio/disk/SDL_diskaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/dsp/SDL_dspaudio.c b/src/eepp/helper/SDL2/src/audio/dsp/SDL_dspaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/dsp/SDL_dspaudio.h b/src/eepp/helper/SDL2/src/audio/dsp/SDL_dspaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/dummy/SDL_dummyaudio.c b/src/eepp/helper/SDL2/src/audio/dummy/SDL_dummyaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/dummy/SDL_dummyaudio.h b/src/eepp/helper/SDL2/src/audio/dummy/SDL_dummyaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/esd/SDL_esdaudio.c b/src/eepp/helper/SDL2/src/audio/esd/SDL_esdaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/esd/SDL_esdaudio.h b/src/eepp/helper/SDL2/src/audio/esd/SDL_esdaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/fusionsound/SDL_fsaudio.c b/src/eepp/helper/SDL2/src/audio/fusionsound/SDL_fsaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/fusionsound/SDL_fsaudio.h b/src/eepp/helper/SDL2/src/audio/fusionsound/SDL_fsaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/nas/SDL_nasaudio.c b/src/eepp/helper/SDL2/src/audio/nas/SDL_nasaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/nas/SDL_nasaudio.h b/src/eepp/helper/SDL2/src/audio/nas/SDL_nasaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/nds/SDL_ndsaudio.c b/src/eepp/helper/SDL2/src/audio/nds/SDL_ndsaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/nds/SDL_ndsaudio.h b/src/eepp/helper/SDL2/src/audio/nds/SDL_ndsaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/paudio/SDL_paudio.c b/src/eepp/helper/SDL2/src/audio/paudio/SDL_paudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/paudio/SDL_paudio.h b/src/eepp/helper/SDL2/src/audio/paudio/SDL_paudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/pulseaudio/SDL_pulseaudio.c b/src/eepp/helper/SDL2/src/audio/pulseaudio/SDL_pulseaudio.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/pulseaudio/SDL_pulseaudio.h b/src/eepp/helper/SDL2/src/audio/pulseaudio/SDL_pulseaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/qsa/SDL_qsa_audio.c b/src/eepp/helper/SDL2/src/audio/qsa/SDL_qsa_audio.c old mode 100755 new mode 100644 index e7d624d50..8b1e138f5 --- a/src/eepp/helper/SDL2/src/audio/qsa/SDL_qsa_audio.c +++ b/src/eepp/helper/SDL2/src/audio/qsa/SDL_qsa_audio.c @@ -570,7 +570,7 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture) } /* Make sure channel is setup right one last time */ - SDL_memset(&csetup, '\0', sizeof(csetup)); + SDL_memset(&csetup, 0, sizeof(csetup)); if (!this->hidden->iscapture) { csetup.channel = SND_PCM_CHANNEL_PLAYBACK; } else { diff --git a/src/eepp/helper/SDL2/src/audio/qsa/SDL_qsa_audio.h b/src/eepp/helper/SDL2/src/audio/qsa/SDL_qsa_audio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/sun/SDL_sunaudio.c b/src/eepp/helper/SDL2/src/audio/sun/SDL_sunaudio.c old mode 100755 new mode 100644 index afdb0ca1a..a62aac091 --- a/src/eepp/helper/SDL2/src/audio/sun/SDL_sunaudio.c +++ b/src/eepp/helper/SDL2/src/audio/sun/SDL_sunaudio.c @@ -53,6 +53,10 @@ /* Open the audio device for playback, and don't block if busy */ #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) +#if defined(AUDIO_GETINFO) && !defined(AUDIO_GETBUFINFO) +#define AUDIO_GETBUFINFO AUDIO_GETINFO +#endif + /* Audio driver functions */ static int DSP_OpenAudio(_THIS, SDL_AudioSpec * spec); static void DSP_WaitAudio(_THIS); @@ -129,11 +133,11 @@ AudioBootStrap SUNAUDIO_bootstrap = { void CheckUnderflow(_THIS) { -#ifdef AUDIO_GETINFO +#ifdef AUDIO_GETBUFINFO audio_info_t info; int left; - ioctl(audio_fd, AUDIO_GETINFO, &info); + ioctl(audio_fd, AUDIO_GETBUFINFO, &info); left = (written - info.play.samples); if (written && (left == 0)) { fprintf(stderr, "audio underflow!\n"); @@ -145,12 +149,12 @@ CheckUnderflow(_THIS) void DSP_WaitAudio(_THIS) { -#ifdef AUDIO_GETINFO +#ifdef AUDIO_GETBUFINFO #define SLEEP_FUDGE 10 /* 10 ms scheduling fudge factor */ audio_info_t info; Sint32 left; - ioctl(audio_fd, AUDIO_GETINFO, &info); + ioctl(audio_fd, AUDIO_GETBUFINFO, &info); left = (written - info.play.samples); if (left > fragsize) { Sint32 sleepy; diff --git a/src/eepp/helper/SDL2/src/audio/sun/SDL_sunaudio.h b/src/eepp/helper/SDL2/src/audio/sun/SDL_sunaudio.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/winmm/SDL_winmm.c b/src/eepp/helper/SDL2/src/audio/winmm/SDL_winmm.c old mode 100755 new mode 100644 index 8df5843d0..63e48aa61 --- a/src/eepp/helper/SDL2/src/audio/winmm/SDL_winmm.c +++ b/src/eepp/helper/SDL2/src/audio/winmm/SDL_winmm.c @@ -31,9 +31,6 @@ #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "SDL_winmm.h" -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) -#include "win_ce_semaphore.h" -#endif #define DETECT_DEV_IMPL(typ, capstyp) \ static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \ @@ -75,11 +72,7 @@ CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, return; /* Signal that we have a new buffer of data */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - ReleaseSemaphoreCE(this->hidden->audio_sem, 1, NULL); -#else ReleaseSemaphore(this->hidden->audio_sem, 1, NULL); -#endif } @@ -95,11 +88,7 @@ FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, return; /* Signal that we are done playing a buffer */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - ReleaseSemaphoreCE(this->hidden->audio_sem, 1, NULL); -#else ReleaseSemaphore(this->hidden->audio_sem, 1, NULL); -#endif } static void @@ -123,11 +112,7 @@ static void WINMM_WaitDevice(_THIS) { /* Wait for an audio chunk to finish */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - WaitForSemaphoreCE(this->hidden->audio_sem, INFINITE); -#else WaitForSingleObject(this->hidden->audio_sem, INFINITE); -#endif } static Uint8 * @@ -173,11 +158,7 @@ WINMM_CloseDevice(_THIS) int i; if (this->hidden->audio_sem) { -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - CloseSynchHandle(this->hidden->audio_sem); -#else CloseHandle(this->hidden->audio_sem); -#endif this->hidden->audio_sem = 0; } @@ -349,11 +330,7 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture) /* Create the audio buffer semaphore */ this->hidden->audio_sem = -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - CreateSemaphoreCE(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL); -#else CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL); -#endif if (this->hidden->audio_sem == NULL) { WINMM_CloseDevice(this); SDL_SetError("Couldn't create semaphore"); @@ -369,7 +346,7 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture) return 0; } for (i = 0; i < NUM_BUFFERS; ++i) { - SDL_memset(&this->hidden->wavebuf[i], '\0', + SDL_memset(&this->hidden->wavebuf[i], 0, sizeof(this->hidden->wavebuf[i])); this->hidden->wavebuf[i].dwBufferLength = this->spec.size; this->hidden->wavebuf[i].dwFlags = WHDR_DONE; diff --git a/src/eepp/helper/SDL2/src/audio/winmm/SDL_winmm.h b/src/eepp/helper/SDL2/src/audio/winmm/SDL_winmm.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/audio/xaudio2/SDL_xaudio2.c b/src/eepp/helper/SDL2/src/audio/xaudio2/SDL_xaudio2.c old mode 100755 new mode 100644 index b3651827f..d42d89638 --- a/src/eepp/helper/SDL2/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/eepp/helper/SDL2/src/audio/xaudio2/SDL_xaudio2.c @@ -332,7 +332,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) return 0; } this->hidden->nextbuf = this->hidden->mixbuf; - SDL_memset(this->hidden->mixbuf, '\0', 2 * this->hidden->mixlen); + SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen); /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On Xbox360, this means 5.1 output, but on Windows, it means "figure out diff --git a/src/eepp/helper/SDL2/src/core/android/SDL_android.cpp b/src/eepp/helper/SDL2/src/core/android/SDL_android.cpp old mode 100755 new mode 100644 index 7367532b5..b1b6490ca --- a/src/eepp/helper/SDL2/src/core/android/SDL_android.cpp +++ b/src/eepp/helper/SDL2/src/core/android/SDL_android.cpp @@ -21,10 +21,13 @@ #include "SDL_config.h" #include "SDL_stdinc.h" #include "SDL_assert.h" +#include "SDL_log.h" #ifdef __ANDROID__ +#include "SDL_system.h" #include "SDL_android.h" +#include extern "C" { #include "../../events/SDL_events_c.h" @@ -33,12 +36,15 @@ extern "C" { #include "../../video/android/SDL_androidvideo.h" #include +#include #define LOG_TAG "SDL_android" //#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) //#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define LOGI(...) do {} while (false) #define LOGE(...) do {} while (false) +/* Uncomment this to log messages entering and exiting methods in this file */ +//#define DEBUG_JNI /* Implemented in audio/android/SDL_androidaudio.c */ extern void Android_RunAudioThread(); @@ -54,8 +60,7 @@ extern void Android_RunAudioThread(); /******************************************************************************* Globals *******************************************************************************/ -static JNIEnv* mEnv = NULL; -static JNIEnv* mAudioEnv = NULL; +static pthread_key_t mThreadKey; static JavaVM* mJavaVM; // Main activity @@ -78,7 +83,6 @@ static bool bHasNewData; *******************************************************************************/ // Library init -/* extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv *env; @@ -88,18 +92,30 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) LOGE("Failed to get the environment using GetEnv()"); return -1; } + /* + * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread + * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this + */ + if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed)) { + __android_log_print(ANDROID_LOG_ERROR, "SDL", "Error initializing pthread key"); + } + else { + Android_JNI_SetupThread(); + } + + AL_SetJavaVM( vm ); return JNI_VERSION_1_4; } -*/ // Called before SDL_main() to initialize JNI bindings -extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls) +extern "C" void SDL_Android_Init(JNIEnv* mEnv, jclass cls) { __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()"); - mEnv = env; - mActivityClass = (jclass)env->NewGlobalRef(cls); + Android_JNI_SetupThread(); + + mActivityClass = (jclass)mEnv->NewGlobalRef(cls); midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass, "createGLContext","(II)Z"); @@ -178,6 +194,8 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativePause( JNIEnv* env, jclass cls) { if (Android_Window) { + /* Signal the pause semaphore so the event loop knows to pause and (optionally) block itself */ + if (!SDL_SemValue(Android_PauseSem)) SDL_SemPost(Android_PauseSem); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } @@ -188,6 +206,11 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume( JNIEnv* env, jclass cls) { if (Android_Window) { + /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context + * We can't restore the GL Context here because it needs to be done on the SDL main thread + * and this function will be called from the Java thread instead. + */ + if (!SDL_SemValue(Android_ResumeSem)) SDL_SemPost(Android_ResumeSem); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0); } @@ -197,11 +220,34 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread( JNIEnv* env, jclass cls) { /* This is the audio thread, with a different environment */ - mAudioEnv = env; + Android_JNI_SetupThread(); Android_RunAudioThread(); } +extern "C" void Java_org_libsdl_app_SDLInputConnection_nativeCommitText( + JNIEnv* env, jclass cls, + jstring text, jint newCursorPosition) +{ + const char *utftext = env->GetStringUTFChars(text, NULL); + + SDL_SendKeyboardText(utftext); + + env->ReleaseStringUTFChars(text, utftext); +} + +extern "C" void Java_org_libsdl_app_SDLInputConnection_nativeSetComposingText( + JNIEnv* env, jclass cls, + jstring text, jint newCursorPosition) +{ + const char *utftext = env->GetStringUTFChars(text, NULL); + + SDL_SendEditingText(utftext, 0, 0); + + env->ReleaseStringUTFChars(text, utftext); +} + + /******************************************************************************* Functions called by SDL into Java @@ -218,8 +264,15 @@ public: } public: - LocalReferenceHolder() : m_env(NULL) { } + LocalReferenceHolder(const char *func) : m_env(NULL), m_func(func) { +#ifdef DEBUG_JNI + SDL_Log("Entering function %s", m_func); +#endif + } ~LocalReferenceHolder() { +#ifdef DEBUG_JNI + SDL_Log("Leaving function %s", m_func); +#endif if (m_env) { m_env->PopLocalFrame(NULL); --s_active; @@ -238,11 +291,13 @@ public: protected: JNIEnv *m_env; + const char *m_func; }; int LocalReferenceHolder::s_active; extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion) { + JNIEnv *mEnv = Android_JNI_GetEnv(); if (mEnv->CallStaticBooleanMethod(mActivityClass, midCreateGLContext, majorVersion, minorVersion)) { return SDL_TRUE; } else { @@ -252,13 +307,14 @@ extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion extern "C" void Android_JNI_SwapWindow() { + JNIEnv *mEnv = Android_JNI_GetEnv(); mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); } extern "C" void Android_JNI_SetActivityTitle(const char *title) { jmethodID mid; - + JNIEnv *mEnv = Android_JNI_GetEnv(); mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)V"); if (mid) { jstring jtitle = reinterpret_cast(mEnv->NewStringUTF(title)); @@ -283,6 +339,53 @@ extern "C" SDL_bool Android_JNI_GetAccelerometerValues(float values[3]) return retval; } +static void Android_JNI_ThreadDestroyed(void* value) { + /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */ + JNIEnv *env = (JNIEnv*) value; + if (env != NULL) { + mJavaVM->DetachCurrentThread(); + pthread_setspecific(mThreadKey, NULL); + } +} + +JNIEnv* Android_JNI_GetEnv(void) { + /* From http://developer.android.com/guide/practices/jni.html + * All threads are Linux threads, scheduled by the kernel. + * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then + * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the + * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv, + * and cannot make JNI calls. + * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main" + * ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread + * is a no-op. + * Note: You can call this function any number of times for the same thread, there's no harm in it + */ + + JNIEnv *env; + int status = mJavaVM->AttachCurrentThread(&env, NULL); + if(status < 0) { + LOGE("failed to attach current thread"); + return 0; + } + + return env; +} + +int Android_JNI_SetupThread(void) { + /* From http://developer.android.com/guide/practices/jni.html + * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward, + * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be + * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific + * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.) + * Note: The destructor is not called unless the stored value is != NULL + * Note: You can call this function any number of times for the same thread, there's no harm in it + * (except for some lost CPU cycles) + */ + JNIEnv *env = Android_JNI_GetEnv(); + pthread_setspecific(mThreadKey, (void*) env); + return 1; +} + // // Audio support // @@ -296,18 +399,12 @@ extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int chan int audioBufferFrames; int status; - JNIEnv *env; - static bool isAttached = false; - status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4); - if(status < 0) { - LOGE("callback_handler: failed to get JNI environment, assuming native thread"); - status = mJavaVM->AttachCurrentThread(&env, NULL); - if(status < 0) { - LOGE("callback_handler: failed to attach current thread"); - return 0; - } - isAttached = true; + JNIEnv *env = Android_JNI_GetEnv(); + + if (!env) { + LOGE("callback_handler: failed to attach current thread"); } + Android_JNI_SetupThread(); __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device"); @@ -334,10 +431,6 @@ extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int chan audioBufferFrames /= 2; } - if (isAttached) { - mJavaVM->DetachCurrentThread(); - } - return audioBufferFrames; } @@ -348,6 +441,8 @@ extern "C" void * Android_JNI_GetAudioBuffer() extern "C" void Android_JNI_WriteAudioBuffer() { + JNIEnv *mAudioEnv = Android_JNI_GetEnv(); + if (audioBuffer16Bit) { mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); @@ -362,18 +457,7 @@ extern "C" void Android_JNI_WriteAudioBuffer() extern "C" void Android_JNI_CloseAudioDevice() { int status; - JNIEnv *env; - static bool isAttached = false; - status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4); - if(status < 0) { - LOGE("callback_handler: failed to get JNI environment, assuming native thread"); - status = mJavaVM->AttachCurrentThread(&env, NULL); - if(status < 0) { - LOGE("callback_handler: failed to attach current thread"); - return; - } - isAttached = true; - } + JNIEnv *env = Android_JNI_GetEnv(); env->CallStaticVoidMethod(mActivityClass, midAudioQuit); @@ -382,16 +466,13 @@ extern "C" void Android_JNI_CloseAudioDevice() audioBuffer = NULL; audioBufferPinned = NULL; } - - if (isAttached) { - mJavaVM->DetachCurrentThread(); - } } // Test for an exception and call SDL_SetError with its detail if one occurs static bool Android_JNI_ExceptionOccurred() { SDL_assert(LocalReferenceHolder::IsActive()); + JNIEnv *mEnv = Android_JNI_GetEnv(); jthrowable exception = mEnv->ExceptionOccurred(); if (exception != NULL) { @@ -429,7 +510,7 @@ static bool Android_JNI_ExceptionOccurred() static int Android_JNI_FileOpen(SDL_RWops* ctx) { - LocalReferenceHolder refs; + LocalReferenceHolder refs(__FUNCTION__); int result = 0; jmethodID mid; @@ -440,6 +521,7 @@ static int Android_JNI_FileOpen(SDL_RWops* ctx) jobject readableByteChannel; jstring fileNameJString; + JNIEnv *mEnv = Android_JNI_GetEnv(); if (!refs.init(mEnv)) { goto failure; } @@ -523,7 +605,8 @@ failure: extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char*) { - LocalReferenceHolder refs; + LocalReferenceHolder refs(__FUNCTION__); + JNIEnv *mEnv = Android_JNI_GetEnv(); if (!refs.init(mEnv)) { return -1; @@ -536,6 +619,8 @@ extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx, jstring fileNameJString = mEnv->NewStringUTF(fileName); ctx->hidden.androidio.fileNameRef = mEnv->NewGlobalRef(fileNameJString); ctx->hidden.androidio.inputStreamRef = NULL; + ctx->hidden.androidio.readableByteChannelRef = NULL; + ctx->hidden.androidio.readMethod = NULL; return Android_JNI_FileOpen(ctx); } @@ -543,10 +628,15 @@ extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx, extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t maxnum) { - LocalReferenceHolder refs; - int bytesRemaining = size * maxnum; + LocalReferenceHolder refs(__FUNCTION__); + jlong bytesRemaining = (jlong) (size * maxnum); + jlong bytesMax = (jlong) (ctx->hidden.androidio.size - ctx->hidden.androidio.position); int bytesRead = 0; + /* Don't read more bytes than those that remain in the file, otherwise we get an exception */ + if (bytesRemaining > bytesMax) bytesRemaining = bytesMax; + + JNIEnv *mEnv = Android_JNI_GetEnv(); if (!refs.init(mEnv)) { return -1; } @@ -584,8 +674,9 @@ extern "C" size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, static int Android_JNI_FileClose(SDL_RWops* ctx, bool release) { - LocalReferenceHolder refs; + LocalReferenceHolder refs(__FUNCTION__); int result = 0; + JNIEnv *mEnv = Android_JNI_GetEnv(); if (!refs.init(mEnv)) { SDL_SetError("Failed to allocate enough JVM local references"); @@ -618,9 +709,14 @@ static int Android_JNI_FileClose(SDL_RWops* ctx, bool release) } -extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence) +extern "C" Sint64 Android_JNI_FileSize(SDL_RWops* ctx) { - long newPosition; + return ctx->hidden.androidio.size; +} + +extern "C" Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence) +{ + Sint64 newPosition; switch (whence) { case RW_SEEK_SET: @@ -636,27 +732,27 @@ extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence) SDL_SetError("Unknown value for 'whence'"); return -1; } + + /* Validate the new position */ if (newPosition < 0) { - newPosition = 0; + SDL_Error(SDL_EFSEEK); + return -1; } if (newPosition > ctx->hidden.androidio.size) { newPosition = ctx->hidden.androidio.size; } - long movement = newPosition - ctx->hidden.androidio.position; - jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef; - + Sint64 movement = newPosition - ctx->hidden.androidio.position; if (movement > 0) { - unsigned char buffer[1024]; + unsigned char buffer[4096]; // The easy case where we're seeking forwards while (movement > 0) { - long amount = (long) sizeof (buffer); + Sint64 amount = sizeof (buffer); if (amount > movement) { amount = movement; } size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount); - if (result <= 0) { // Failed to read/skip the required amount, so fail return -1; @@ -664,6 +760,7 @@ extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence) movement -= result; } + } else if (movement < 0) { // We can't seek backwards so we have to reopen the file and seek // forwards which obviously isn't very efficient @@ -672,8 +769,6 @@ extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence) Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET); } - ctx->hidden.androidio.position = newPosition; - return ctx->hidden.androidio.position; } @@ -682,6 +777,363 @@ extern "C" int Android_JNI_FileClose(SDL_RWops* ctx) return Android_JNI_FileClose(ctx, true); } +// returns a new global reference which needs to be released later +static jobject Android_JNI_GetSystemServiceObject(const char* name) +{ + LocalReferenceHolder refs(__FUNCTION__); + JNIEnv* env = Android_JNI_GetEnv(); + if (!refs.init(env)) { + return NULL; + } + + jstring service = env->NewStringUTF(name); + + jmethodID mid; + + mid = env->GetStaticMethodID(mActivityClass, "getContext", "()Landroid/content/Context;"); + jobject context = env->CallStaticObjectMethod(mActivityClass, mid); + + mid = env->GetMethodID(mActivityClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); + jobject manager = env->CallObjectMethod(context, mid, service); + + env->DeleteLocalRef(service); + + return manager ? env->NewGlobalRef(manager) : NULL; +} + +#define SETUP_CLIPBOARD(error) \ + LocalReferenceHolder refs(__FUNCTION__); \ + JNIEnv* env = Android_JNI_GetEnv(); \ + if (!refs.init(env)) { \ + return error; \ + } \ + jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \ + if (!clipboard) { \ + return error; \ + } + +extern "C" int Android_JNI_SetClipboardText(const char* text) +{ + SETUP_CLIPBOARD(-1) + + jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "setText", "(Ljava/lang/CharSequence;)V"); + jstring string = env->NewStringUTF(text); + env->CallVoidMethod(clipboard, mid, string); + env->DeleteGlobalRef(clipboard); + env->DeleteLocalRef(string); + return 0; +} + +extern "C" char* Android_JNI_GetClipboardText() +{ + SETUP_CLIPBOARD(SDL_strdup("")) + + jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "getText", "()Ljava/lang/CharSequence;"); + jobject sequence = env->CallObjectMethod(clipboard, mid); + env->DeleteGlobalRef(clipboard); + if (sequence) { + mid = env->GetMethodID(env->GetObjectClass(sequence), "toString", "()Ljava/lang/String;"); + jstring string = reinterpret_cast(env->CallObjectMethod(sequence, mid)); + const char* utf = env->GetStringUTFChars(string, 0); + if (utf) { + char* text = SDL_strdup(utf); + env->ReleaseStringUTFChars(string, utf); + return text; + } + } + return SDL_strdup(""); +} + +extern "C" SDL_bool Android_JNI_HasClipboardText() +{ + SETUP_CLIPBOARD(SDL_FALSE) + + jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "hasText", "()Z"); + jboolean has = env->CallBooleanMethod(clipboard, mid); + env->DeleteGlobalRef(clipboard); + return has ? SDL_TRUE : SDL_FALSE; +} + + +// returns 0 on success or -1 on error (others undefined then) +// returns truthy or falsy value in plugged, charged and battery +// returns the value in seconds and percent or -1 if not available +extern "C" int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent) +{ + LocalReferenceHolder refs(__FUNCTION__); + JNIEnv* env = Android_JNI_GetEnv(); + if (!refs.init(env)) { + return -1; + } + + jmethodID mid; + + mid = env->GetStaticMethodID(mActivityClass, "getContext", "()Landroid/content/Context;"); + jobject context = env->CallStaticObjectMethod(mActivityClass, mid); + + jstring action = env->NewStringUTF("android.intent.action.BATTERY_CHANGED"); + + jclass cls = env->FindClass("android/content/IntentFilter"); + + mid = env->GetMethodID(cls, "", "(Ljava/lang/String;)V"); + jobject filter = env->NewObject(cls, mid, action); + + env->DeleteLocalRef(action); + + mid = env->GetMethodID(mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); + jobject intent = env->CallObjectMethod(context, mid, NULL, filter); + + env->DeleteLocalRef(filter); + + cls = env->GetObjectClass(intent); + + jstring iname; + jmethodID imid = env->GetMethodID(cls, "getIntExtra", "(Ljava/lang/String;I)I"); + +#define GET_INT_EXTRA(var, key) \ + iname = env->NewStringUTF(key); \ + int var = env->CallIntMethod(intent, imid, iname, -1); \ + env->DeleteLocalRef(iname); + + jstring bname; + jmethodID bmid = env->GetMethodID(cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); + +#define GET_BOOL_EXTRA(var, key) \ + bname = env->NewStringUTF(key); \ + int var = env->CallBooleanMethod(intent, bmid, bname, JNI_FALSE); \ + env->DeleteLocalRef(bname); + + if (plugged) { + GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) + if (plug == -1) { + return -1; + } + // 1 == BatteryManager.BATTERY_PLUGGED_AC + // 2 == BatteryManager.BATTERY_PLUGGED_USB + *plugged = (0 < plug) ? 1 : 0; + } + + if (charged) { + GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) + if (status == -1) { + return -1; + } + // 5 == BatteryManager.BATTERY_STATUS_FULL + *charged = (status == 5) ? 1 : 0; + } + + if (battery) { + GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) + *battery = present ? 1 : 0; + } + + if (seconds) { + *seconds = -1; // not possible + } + + if (percent) { + GET_INT_EXTRA(level, "level") // == BatteryManager.EXTRA_LEVEL (API 5) + GET_INT_EXTRA(scale, "scale") // == BatteryManager.EXTRA_SCALE (API 5) + if ((level == -1) || (scale == -1)) { + return -1; + } + *percent = level * 100 / scale; + } + + env->DeleteLocalRef(intent); + + return 0; +} + +// sends message to be handled on the UI event dispatch thread +extern "C" int Android_JNI_SendMessage(int command, int param) +{ + JNIEnv *env = Android_JNI_GetEnv(); + if (!env) { + return -1; + } + jmethodID mid = env->GetStaticMethodID(mActivityClass, "sendMessage", "(II)V"); + if (!mid) { + return -1; + } + env->CallStaticVoidMethod(mActivityClass, mid, command, param); + return 0; +} + +extern "C" void Android_JNI_ShowTextInput(SDL_Rect *inputRect) +{ + JNIEnv *env = Android_JNI_GetEnv(); + if (!env) { + return; + } + + jmethodID mid = env->GetStaticMethodID(mActivityClass, "showTextInput", "(IIII)V"); + if (!mid) { + return; + } + env->CallStaticVoidMethod( mActivityClass, mid, + inputRect->x, + inputRect->y, + inputRect->w, + inputRect->h ); +} + +extern "C" void Android_JNI_HideTextInput() +{ + // has to match Activity constant + const int COMMAND_TEXTEDIT_HIDE = 3; + Android_JNI_SendMessage(COMMAND_TEXTEDIT_HIDE, 0); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Functions exposed to SDL applications in SDL_system.h +// + +extern "C" void *SDL_AndroidGetJNIEnv() +{ + return Android_JNI_GetEnv(); +} + +extern "C" void *SDL_AndroidGetActivity() +{ + LocalReferenceHolder refs(__FUNCTION__); + jmethodID mid; + + JNIEnv *env = Android_JNI_GetEnv(); + if (!refs.init(env)) { + return NULL; + } + + // return SDLActivity.getContext(); + mid = env->GetStaticMethodID(mActivityClass, + "getContext","()Landroid/content/Context;"); + return env->CallStaticObjectMethod(mActivityClass, mid); +} + +extern "C" const char * SDL_AndroidGetInternalStoragePath() +{ + static char *s_AndroidInternalFilesPath = NULL; + + if (!s_AndroidInternalFilesPath) { + LocalReferenceHolder refs(__FUNCTION__); + jmethodID mid; + jobject context; + jobject fileObject; + jstring pathString; + const char *path; + + JNIEnv *env = Android_JNI_GetEnv(); + if (!refs.init(env)) { + return NULL; + } + + // context = SDLActivity.getContext(); + mid = env->GetStaticMethodID(mActivityClass, + "getContext","()Landroid/content/Context;"); + context = env->CallStaticObjectMethod(mActivityClass, mid); + + // fileObj = context.getFilesDir(); + mid = env->GetMethodID(env->GetObjectClass(context), + "getFilesDir", "()Ljava/io/File;"); + fileObject = env->CallObjectMethod(context, mid); + if (!fileObject) { + SDL_SetError("Couldn't get internal directory"); + return NULL; + } + + // path = fileObject.getAbsolutePath(); + mid = env->GetMethodID(env->GetObjectClass(fileObject), + "getAbsolutePath", "()Ljava/lang/String;"); + pathString = (jstring)env->CallObjectMethod(fileObject, mid); + + path = env->GetStringUTFChars(pathString, NULL); + s_AndroidInternalFilesPath = SDL_strdup(path); + env->ReleaseStringUTFChars(pathString, path); + } + return s_AndroidInternalFilesPath; +} + +extern "C" int SDL_AndroidGetExternalStorageState() +{ + LocalReferenceHolder refs(__FUNCTION__); + jmethodID mid; + jclass cls; + jstring stateString; + const char *state; + int stateFlags; + + JNIEnv *env = Android_JNI_GetEnv(); + if (!refs.init(env)) { + return 0; + } + + cls = env->FindClass("android/os/Environment"); + mid = env->GetStaticMethodID(cls, + "getExternalStorageState", "()Ljava/lang/String;"); + stateString = (jstring)env->CallStaticObjectMethod(cls, mid); + + state = env->GetStringUTFChars(stateString, NULL); + + // Print an info message so people debugging know the storage state + __android_log_print(ANDROID_LOG_INFO, "SDL", "external storage state: %s", state); + + if (SDL_strcmp(state, "mounted") == 0) { + stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ | + SDL_ANDROID_EXTERNAL_STORAGE_WRITE; + } else if (SDL_strcmp(state, "mounted_ro") == 0) { + stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ; + } else { + stateFlags = 0; + } + env->ReleaseStringUTFChars(stateString, state); + + return stateFlags; +} + +extern "C" const char * SDL_AndroidGetExternalStoragePath() +{ + static char *s_AndroidExternalFilesPath = NULL; + + if (!s_AndroidExternalFilesPath) { + LocalReferenceHolder refs(__FUNCTION__); + jmethodID mid; + jobject context; + jobject fileObject; + jstring pathString; + const char *path; + + JNIEnv *env = Android_JNI_GetEnv(); + if (!refs.init(env)) { + return NULL; + } + + // context = SDLActivity.getContext(); + mid = env->GetStaticMethodID(mActivityClass, + "getContext","()Landroid/content/Context;"); + context = env->CallStaticObjectMethod(mActivityClass, mid); + + // fileObj = context.getExternalFilesDir(); + mid = env->GetMethodID(env->GetObjectClass(context), + "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); + fileObject = env->CallObjectMethod(context, mid, NULL); + if (!fileObject) { + SDL_SetError("Couldn't get external directory"); + return NULL; + } + + // path = fileObject.getAbsolutePath(); + mid = env->GetMethodID(env->GetObjectClass(fileObject), + "getAbsolutePath", "()Ljava/lang/String;"); + pathString = (jstring)env->CallObjectMethod(fileObject, mid); + + path = env->GetStringUTFChars(pathString, NULL); + s_AndroidExternalFilesPath = SDL_strdup(path); + env->ReleaseStringUTFChars(pathString, path); + } + return s_AndroidExternalFilesPath; +} + #endif /* __ANDROID__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/core/android/SDL_android.h b/src/eepp/helper/SDL2/src/core/android/SDL_android.h old mode 100755 new mode 100644 index 5c6a2d8e0..d72761bfb --- a/src/eepp/helper/SDL2/src/core/android/SDL_android.h +++ b/src/eepp/helper/SDL2/src/core/android/SDL_android.h @@ -27,11 +27,15 @@ extern "C" { /* *INDENT-ON* */ #endif +#include "SDL_rect.h" + /* Interface from the SDL library into the Android Java activity */ extern SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion); extern void Android_JNI_SwapWindow(); extern void Android_JNI_SetActivityTitle(const char *title); extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]); +extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect); +extern void Android_JNI_HideTextInput(); // Audio support extern int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); @@ -42,11 +46,29 @@ extern void Android_JNI_CloseAudioDevice(); #include "SDL_rwops.h" int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode); -long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence); +Sint64 Android_JNI_FileSize(SDL_RWops* ctx); +Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence); size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t maxnum); size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, size_t num); int Android_JNI_FileClose(SDL_RWops* ctx); +/* Clipboard support */ +int Android_JNI_SetClipboardText(const char* text); +char* Android_JNI_GetClipboardText(); +SDL_bool Android_JNI_HasClipboardText(); + +/* Power support */ +int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent); + +// Threads +#include +static void Android_JNI_ThreadDestroyed(void*); +JNIEnv *Android_JNI_GetEnv(void); +int Android_JNI_SetupThread(void); + +// Generic messages +int Android_JNI_SendMessage(int command, int param); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/eepp/helper/SDL2/src/core/windows/SDL_windows.c b/src/eepp/helper/SDL2/src/core/windows/SDL_windows.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/core/windows/SDL_windows.h b/src/eepp/helper/SDL2/src/core/windows/SDL_windows.h old mode 100755 new mode 100644 index ab21627d6..c7c6f9576 --- a/src/eepp/helper/SDL2/src/core/windows/SDL_windows.h +++ b/src/eepp/helper/SDL2/src/core/windows/SDL_windows.h @@ -30,15 +30,15 @@ #define UNICODE 1 #endif #undef _WIN32_WINNT -#define _WIN32_WINNT 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */ +#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ #include /* Routines to convert from UTF8 to native Windows text */ #if 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) +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) +#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2-INTERNAL", "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) diff --git a/src/eepp/helper/SDL2/src/cpuinfo/SDL_cpuinfo.c b/src/eepp/helper/SDL2/src/cpuinfo/SDL_cpuinfo.c old mode 100755 new mode 100644 index 294b1e4c7..db258405d --- a/src/eepp/helper/SDL2/src/cpuinfo/SDL_cpuinfo.c +++ b/src/eepp/helper/SDL2/src/cpuinfo/SDL_cpuinfo.c @@ -33,6 +33,10 @@ #endif #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__)) #include /* For AltiVec check */ +#elif defined(__OpenBSD__) && defined(__powerpc__) +#include +#include /* For AltiVec check */ +#include #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP #include #include @@ -51,7 +55,7 @@ #define CPU_HAS_SSE41 0x00000100 #define CPU_HAS_SSE42 0x00000200 -#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ +#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__ /* This is the brute force way of detecting instruction sets... the idea is borrowed from the libmpeg2 library - thanks! */ @@ -214,8 +218,12 @@ static __inline__ int CPU_haveAltiVec(void) { volatile int altivec = 0; -#if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__)) +#if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__)) +#ifdef __OpenBSD__ + int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC }; +#else int selectors[2] = { CTL_HW, HW_VECTORUNIT }; +#endif int hasVectorUnit = 0; size_t length = sizeof(hasVectorUnit); int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); diff --git a/src/eepp/helper/SDL2/src/events/SDL_clipboardevents.c b/src/eepp/helper/SDL2/src/events/SDL_clipboardevents.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_clipboardevents_c.h b/src/eepp/helper/SDL2/src/events/SDL_clipboardevents_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_dropevents.c b/src/eepp/helper/SDL2/src/events/SDL_dropevents.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_dropevents_c.h b/src/eepp/helper/SDL2/src/events/SDL_dropevents_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_events.c b/src/eepp/helper/SDL2/src/events/SDL_events.c old mode 100755 new mode 100644 index 642db5d1a..c6aa97415 --- a/src/eepp/helper/SDL2/src/events/SDL_events.c +++ b/src/eepp/helper/SDL2/src/events/SDL_events.c @@ -63,14 +63,14 @@ static struct SDL_Event event[MAXEVENTS]; int wmmsg_next; struct SDL_SysWMmsg wmmsg[MAXEVENTS]; -} SDL_EventQ; +} SDL_EventQ = { NULL, 1 }; static __inline__ SDL_bool SDL_ShouldPollJoystick() { #if !SDL_JOYSTICK_DISABLED - if (SDL_numjoysticks && + if (SDL_PrivateJoystickNeedsPolling() && (!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY))) { return SDL_TRUE; @@ -86,6 +86,8 @@ SDL_StopEventLoop(void) { int i; + SDL_EventQ.active = 0; + if (SDL_EventQ.lock) { SDL_DestroyMutex(SDL_EventQ.lock); SDL_EventQ.lock = NULL; @@ -115,18 +117,23 @@ SDL_StopEventLoop(void) int SDL_StartEventLoop(void) { - /* Clean out the event queue */ - SDL_EventQ.lock = NULL; - SDL_StopEventLoop(); + /* We'll leave the event queue alone, since we might have gotten + some important events at launch (like SDL_DROPFILE) + + FIXME: Does this introduce any other bugs with events at startup? + */ /* No filter to start with, process most event types */ SDL_EventOK = NULL; - SDL_EventState(SDL_DROPFILE, SDL_DISABLE); + SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); + SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE); /* Create the lock and set ourselves active */ #if !SDL_THREADS_DISABLED - SDL_EventQ.lock = SDL_CreateMutex(); + if (!SDL_EventQ.lock) { + SDL_EventQ.lock = SDL_CreateMutex(); + } if (SDL_EventQ.lock == NULL) { return (-1); } @@ -205,7 +212,7 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, } /* Lock the event queue */ used = 0; - if (SDL_mutexP(SDL_EventQ.lock) == 0) { + if (!SDL_EventQ.lock || SDL_mutexP(SDL_EventQ.lock) == 0) { if (action == SDL_ADDEVENT) { for (i = 0; i < numevents; ++i) { used += SDL_AddEvent(&events[i]); @@ -372,7 +379,6 @@ SDL_PushEvent(SDL_Event * event) } SDL_GestureProcessEvent(event); - return 1; } diff --git a/src/eepp/helper/SDL2/src/events/SDL_events_c.h b/src/eepp/helper/SDL2/src/events/SDL_events_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_gesture.c b/src/eepp/helper/SDL2/src/events/SDL_gesture.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_gesture_c.h b/src/eepp/helper/SDL2/src/events/SDL_gesture_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_keyboard.c b/src/eepp/helper/SDL2/src/events/SDL_keyboard.c old mode 100755 new mode 100644 index 366e0184e..9e2b59b1d --- a/src/eepp/helper/SDL2/src/events/SDL_keyboard.c +++ b/src/eepp/helper/SDL2/src/events/SDL_keyboard.c @@ -28,6 +28,8 @@ #include "../video/SDL_sysvideo.h" +/*#define DEBUG_KEYBOARD*/ + /* Global keyboard information */ typedef struct SDL_Keyboard SDL_Keyboard; @@ -563,6 +565,9 @@ SDL_ResetKeyboard(void) SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Scancode scancode; +#ifdef DEBUG_KEYBOARD + printf("Resetting keyboard\n"); +#endif for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) { if (keyboard->keystate[scancode] == SDL_PRESSED) { SDL_SendKeyboardKey(SDL_RELEASED, scancode); @@ -607,6 +612,11 @@ SDL_SetKeyboardFocus(SDL_Window * window) { SDL_Keyboard *keyboard = &SDL_keyboard; + if (keyboard->focus && !window) { + /* We won't get anymore keyboard messages, so reset keyboard state */ + SDL_ResetKeyboard(); + } + /* See if the current window has lost focus */ if (keyboard->focus && keyboard->focus != window) { SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST, @@ -648,7 +658,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) if (!scancode) { return 0; } -#if 0 +#ifdef DEBUG_KEYBOARD printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode), state == SDL_PRESSED ? "pressed" : "released"); #endif diff --git a/src/eepp/helper/SDL2/src/events/SDL_keyboard_c.h b/src/eepp/helper/SDL2/src/events/SDL_keyboard_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_mouse.c b/src/eepp/helper/SDL2/src/events/SDL_mouse.c old mode 100755 new mode 100644 index ff20a79ed..a61f21520 --- a/src/eepp/helper/SDL2/src/events/SDL_mouse.c +++ b/src/eepp/helper/SDL2/src/events/SDL_mouse.c @@ -22,11 +22,13 @@ /* General mouse handling code for SDL */ +#include "SDL_assert.h" #include "SDL_events.h" #include "SDL_events_c.h" #include "default_cursor.h" #include "../video/SDL_sysvideo.h" +/*#define DEBUG_MOUSE*/ /* The mouse state */ static SDL_Mouse SDL_mouse; @@ -68,6 +70,23 @@ SDL_GetMouseFocus(void) return mouse->focus; } +void +SDL_ResetMouse(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + Uint8 i; + +#ifdef DEBUG_MOUSE + printf("Resetting mouse\n"); +#endif + for (i = 1; i <= sizeof(mouse->buttonstate)*8; ++i) { + if (mouse->buttonstate & SDL_BUTTON(i)) { + SDL_SendMouseButton(mouse->focus, SDL_RELEASED, i); + } + } + SDL_assert(mouse->buttonstate == 0); +} + void SDL_SetMouseFocus(SDL_Window * window) { @@ -77,6 +96,11 @@ SDL_SetMouseFocus(SDL_Window * window) return; } + if (mouse->focus && !window) { + /* We won't get anymore mouse messages, so reset mouse state */ + SDL_ResetMouse(); + } + /* See if the current window has lost focus */ if (mouse->focus) { SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0); @@ -87,6 +111,59 @@ SDL_SetMouseFocus(SDL_Window * window) if (mouse->focus) { SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0); } + + /* Update cursor visibility */ + SDL_SetCursor(NULL); +} + +/* Check to see if we need to synthesize focus events */ +static SDL_bool +SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + int w, h; + SDL_bool inWindow; + + SDL_GetWindowSize(window, &w, &h); + if (x < 0 || y < 0 || x >= w || y >= h) { + inWindow = SDL_FALSE; + } else { + inWindow = SDL_TRUE; + } + +/* Linux doesn't give you mouse events outside your window unless you grab + the pointer. + + Windows doesn't give you mouse events outside your window unless you call + SetCapture(). + + Both of these are slightly scary changes, so for now we'll punt and if the + mouse leaves the window you'll lose mouse focus and reset button state. +*/ +#ifdef SUPPORT_DRAG_OUTSIDE_WINDOW + if (!inWindow && !buttonstate) { +#else + if (!inWindow) { +#endif + if (window == mouse->focus) { +#ifdef DEBUG_MOUSE + printf("Mouse left window, synthesizing focus lost event\n"); +#endif + SDL_SetMouseFocus(NULL); + } + return SDL_FALSE; + } + + if (window != mouse->focus) { + mouse->last_x = x; + mouse->last_y = y; + +#ifdef DEBUG_MOUSE + printf("Mouse entered window, synthesizing focus gain event\n"); +#endif + SDL_SetMouseFocus(window); + } + return SDL_TRUE; } int @@ -98,11 +175,13 @@ SDL_SendMouseMotion(SDL_Window * window, int relative, int x, int y) int yrel; int x_max = 0, y_max = 0; - if (window) { - SDL_SetMouseFocus(window); + if (window && !relative) { + if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) { + return 0; + } } - /* the relative motion is calculated regarding the system cursor last position */ + /* relative motion is calculated regarding the system cursor last position */ if (relative) { xrel = x; yrel = y; @@ -115,7 +194,7 @@ SDL_SendMouseMotion(SDL_Window * window, int relative, int x, int y) /* Drop events that don't change state */ if (!xrel && !yrel) { -#if 0 +#ifdef DEBUG_MOUSE printf("Mouse event didn't change state - dropped!\n"); #endif return 0; @@ -135,7 +214,6 @@ SDL_SendMouseMotion(SDL_Window * window, int relative, int x, int y) --y_max; /* make sure that the pointers find themselves inside the windows */ - /* only check if mouse->xmax is set ! */ if (mouse->x > x_max) { mouse->x = x_max; } @@ -174,8 +252,9 @@ SDL_SendMouseMotion(SDL_Window * window, int relative, int x, int y) event.motion.yrel = yrel; posted = (SDL_PushEvent(&event) > 0); } - mouse->last_x = mouse->x; - mouse->last_y = mouse->y; + /* Use unclamped values if we're getting events outside the window */ + mouse->last_x = x; + mouse->last_y = y; return posted; } @@ -185,34 +264,34 @@ SDL_SendMouseButton(SDL_Window * window, Uint8 state, Uint8 button) SDL_Mouse *mouse = SDL_GetMouse(); int posted; Uint32 type; - - if (window) { - SDL_SetMouseFocus(window); - } + Uint32 buttonstate = mouse->buttonstate; /* Figure out which event to perform */ switch (state) { case SDL_PRESSED: - if (mouse->buttonstate & SDL_BUTTON(button)) { - /* Ignore this event, no state change */ - return 0; - } type = SDL_MOUSEBUTTONDOWN; - mouse->buttonstate |= SDL_BUTTON(button); + buttonstate |= SDL_BUTTON(button); break; case SDL_RELEASED: - if (!(mouse->buttonstate & SDL_BUTTON(button))) { - /* Ignore this event, no state change */ - return 0; - } type = SDL_MOUSEBUTTONUP; - mouse->buttonstate &= ~SDL_BUTTON(button); + buttonstate &= ~SDL_BUTTON(button); break; default: /* Invalid state -- bail */ return 0; } + /* We do this after calculating buttonstate so button presses gain focus */ + if (window && state == SDL_PRESSED) { + SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); + } + + if (buttonstate == mouse->buttonstate) { + /* Ignore this event, no state change */ + return 0; + } + mouse->buttonstate = buttonstate; + /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(type) == SDL_ENABLE) { @@ -225,6 +304,12 @@ SDL_SendMouseButton(SDL_Window * window, Uint8 state, Uint8 button) event.button.windowID = mouse->focus ? mouse->focus->id : 0; posted = (SDL_PushEvent(&event) > 0); } + + /* We do this after dispatching event so button releases can lose focus */ + if (window && state == SDL_RELEASED) { + SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); + } + return posted; } @@ -260,7 +345,7 @@ SDL_MouseQuit(void) { } -Uint8 +Uint32 SDL_GetMouseState(int *x, int *y) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -274,7 +359,7 @@ SDL_GetMouseState(int *x, int *y) return mouse->buttonstate; } -Uint8 +Uint32 SDL_GetRelativeMouseState(int *x, int *y) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -443,6 +528,26 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) return cursor; } +SDL_Cursor * +SDL_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Cursor *cursor; + + if (!mouse->CreateSystemCursor) { + SDL_SetError("CreateSystemCursor is not currently supported"); + return NULL; + } + + cursor = mouse->CreateSystemCursor(id); + if (cursor) { + cursor->next = mouse->cursors; + mouse->cursors = cursor; + } + + return cursor; +} + /* SDL_SetCursor(NULL) can be used to force the cursor redraw, if this is desired for any reason. This is used when setting the video mode and when the SDL window gains the mouse focus. diff --git a/src/eepp/helper/SDL2/src/events/SDL_mouse_c.h b/src/eepp/helper/SDL2/src/events/SDL_mouse_c.h old mode 100755 new mode 100644 index d571ddabd..4918aea98 --- a/src/eepp/helper/SDL2/src/events/SDL_mouse_c.h +++ b/src/eepp/helper/SDL2/src/events/SDL_mouse_c.h @@ -36,6 +36,9 @@ typedef struct /* Create a cursor from a surface */ SDL_Cursor *(*CreateCursor) (SDL_Surface * surface, int hot_x, int hot_y); + /* Create a system cursor */ + SDL_Cursor *(*CreateSystemCursor) (SDL_SystemCursor id); + /* Show the specified cursor, or hide if cursor is NULL */ int (*ShowCursor) (SDL_Cursor * cursor); @@ -58,7 +61,7 @@ typedef struct int xdelta; int ydelta; int last_x, last_y; /* the last reported x and y coordinates */ - Uint8 buttonstate; + Uint32 buttonstate; SDL_bool relative_mode; /* the x and y coordinates when relative mode was activated */ int original_x, original_y; diff --git a/src/eepp/helper/SDL2/src/events/SDL_quit.c b/src/eepp/helper/SDL2/src/events/SDL_quit.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_sysevents.h b/src/eepp/helper/SDL2/src/events/SDL_sysevents.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_touch.c b/src/eepp/helper/SDL2/src/events/SDL_touch.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_touch_c.h b/src/eepp/helper/SDL2/src/events/SDL_touch_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/SDL_windowevents.c b/src/eepp/helper/SDL2/src/events/SDL_windowevents.c old mode 100755 new mode 100644 index fca48e3e5..88629c807 --- a/src/eepp/helper/SDL2/src/events/SDL_windowevents.c +++ b/src/eepp/helper/SDL2/src/events/SDL_windowevents.c @@ -29,13 +29,26 @@ static int -RemovePendingSizeEvents(void * userdata, SDL_Event *event) +RemovePendingResizedEvents(void * userdata, SDL_Event *event) { SDL_Event *new_event = (SDL_Event *)userdata; if (event->type == SDL_WINDOWEVENT && - (event->window.event == SDL_WINDOWEVENT_RESIZED || - event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) && + event->window.event == SDL_WINDOWEVENT_RESIZED && + event->window.windowID == new_event->window.windowID) { + /* We're about to post a new size event, drop the old one */ + return 0; + } + return 1; +} + +static int +RemovePendingSizeChangedEvents(void * userdata, SDL_Event *event) +{ + SDL_Event *new_event = (SDL_Event *)userdata; + + if (event->type == SDL_WINDOWEVENT && + event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED && event->window.windowID == new_event->window.windowID) { /* We're about to post a new size event, drop the old one */ return 0; @@ -169,9 +182,11 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, event.window.windowID = window->id; /* Fixes queue overflow with resize events that aren't processed */ - if (windowevent == SDL_WINDOWEVENT_RESIZED || - windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) { - SDL_FilterEvents(RemovePendingSizeEvents, &event); + if (windowevent == SDL_WINDOWEVENT_RESIZED) { + SDL_FilterEvents(RemovePendingResizedEvents, &event); + } + if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) { + SDL_FilterEvents(RemovePendingSizeChangedEvents, &event); } if (windowevent == SDL_WINDOWEVENT_MOVED) { SDL_FilterEvents(RemovePendingMoveEvents, &event); diff --git a/src/eepp/helper/SDL2/src/events/SDL_windowevents_c.h b/src/eepp/helper/SDL2/src/events/SDL_windowevents_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/blank_cursor.h b/src/eepp/helper/SDL2/src/events/blank_cursor.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/default_cursor.h b/src/eepp/helper/SDL2/src/events/default_cursor.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/nds/SDL_ndsgesture.c b/src/eepp/helper/SDL2/src/events/nds/SDL_ndsgesture.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/scancodes_darwin.h b/src/eepp/helper/SDL2/src/events/scancodes_darwin.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/scancodes_linux.h b/src/eepp/helper/SDL2/src/events/scancodes_linux.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/scancodes_windows.h b/src/eepp/helper/SDL2/src/events/scancodes_windows.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/events/scancodes_xfree86.h b/src/eepp/helper/SDL2/src/events/scancodes_xfree86.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/file/SDL_rwops.c b/src/eepp/helper/SDL2/src/file/SDL_rwops.c old mode 100755 new mode 100644 index d4868cc7a..225d0a1d6 --- a/src/eepp/helper/SDL2/src/file/SDL_rwops.c +++ b/src/eepp/helper/SDL2/src/file/SDL_rwops.c @@ -18,6 +18,8 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +/* Need this so Linux systems define fseek64o, ftell64o and off64_t */ +#define _LARGEFILE64_SOURCE #include "SDL_config.h" /* This file provides a general interface for SDL to read and write @@ -43,9 +45,6 @@ #ifdef __WIN32__ /* Functions to read/write Win32 API file pointers */ -/* Will not use it on WinCE because stdio is buffered, it means - faster, and all stdio functions anyway are embedded in coredll.dll - - the main wince dll*/ #include "../core/windows/SDL_windows.h" @@ -58,9 +57,7 @@ static int SDLCALL windows_file_open(SDL_RWops * context, const char *filename, const char *mode) { -#ifndef _WIN32_WCE UINT old_error_mode; -#endif HANDLE h; DWORD r_right, w_right; DWORD must_exist, truncate; @@ -98,16 +95,6 @@ windows_file_open(SDL_RWops * context, const char *filename, const char *mode) SDL_OutOfMemory(); return -1; } -#ifdef _WIN32_WCE - { - LPTSTR tstr = WIN_UTF8ToString(filename); - h = CreateFile(tstr, (w_right | r_right), - (w_right) ? 0 : FILE_SHARE_READ, NULL, - (must_exist | truncate | a_mode), - FILE_ATTRIBUTE_NORMAL, NULL); - SDL_free(tstr); - } -#else /* Do not open a dialog box if failure */ old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); @@ -123,7 +110,6 @@ windows_file_open(SDL_RWops * context, const char *filename, const char *mode) /* restore old behavior */ SetErrorMode(old_error_mode); -#endif /* _WIN32_WCE */ if (h == INVALID_HANDLE_VALUE) { SDL_free(context->hidden.windowsio.buffer.data); @@ -137,11 +123,29 @@ windows_file_open(SDL_RWops * context, const char *filename, const char *mode) return 0; /* ok */ } -static long SDLCALL -windows_file_seek(SDL_RWops * context, long offset, int whence) +static Sint64 SDLCALL +windows_file_size(SDL_RWops * context) +{ + LARGE_INTEGER size; + + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { + SDL_SetError("windows_file_size: invalid context/file not opened"); + return -1; + } + + if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) { + WIN_SetError("windows_file_size"); + return -1; + } + + return size.QuadPart; +} + +static Sint64 SDLCALL +windows_file_seek(SDL_RWops * context, Sint64 offset, int whence) { DWORD windowswhence; - long file_pos; + LARGE_INTEGER windowsoffset; if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { SDL_SetError("windows_file_seek: invalid context/file not opened"); @@ -169,14 +173,12 @@ windows_file_seek(SDL_RWops * context, long offset, int whence) return -1; } - file_pos = - SetFilePointer(context->hidden.windowsio.h, offset, NULL, windowswhence); - - if (file_pos != INVALID_SET_FILE_POINTER) - return file_pos; /* success */ - - SDL_Error(SDL_EFSEEK); - return -1; /* error */ + windowsoffset.QuadPart = offset; + if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) { + WIN_SetError("windows_file_seek"); + return -1; + } + return windowsoffset.QuadPart; } static size_t SDLCALL @@ -297,15 +299,39 @@ windows_file_close(SDL_RWops * context) /* Functions to read/write stdio file pointers */ -static long SDLCALL -stdio_seek(SDL_RWops * context, long offset, int whence) +static Sint64 SDLCALL +stdio_size(SDL_RWops * context) { + Sint64 pos, size; + + pos = SDL_RWseek(context, 0, RW_SEEK_CUR); + if (pos < 0) { + return -1; + } + size = SDL_RWseek(context, 0, RW_SEEK_END); + + SDL_RWseek(context, pos, RW_SEEK_SET); + return size; +} + +static Sint64 SDLCALL +stdio_seek(SDL_RWops * context, Sint64 offset, int whence) +{ +#ifdef HAVE_FSEEKO64 + if (fseeko64(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) { + return ftello64(context->hidden.stdio.fp); + } +#elif defined(HAVE_FSEEKO) + if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) { + return ftello(context->hidden.stdio.fp); + } +#else if (fseek(context->hidden.stdio.fp, offset, whence) == 0) { return (ftell(context->hidden.stdio.fp)); - } else { - SDL_Error(SDL_EFSEEK); - return (-1); } +#endif + SDL_Error(SDL_EFSEEK); + return (-1); } static size_t SDLCALL @@ -352,8 +378,14 @@ stdio_close(SDL_RWops * context) /* Functions to read/write memory pointers */ -static long SDLCALL -mem_seek(SDL_RWops * context, long offset, int whence) +static Sint64 SDLCALL +mem_size(SDL_RWops * context) +{ + return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base); +} + +static Sint64 SDLCALL +mem_seek(SDL_RWops * context, Sint64 offset, int whence) { Uint8 *newpos; @@ -378,7 +410,7 @@ mem_seek(SDL_RWops * context, long offset, int whence) newpos = context->hidden.mem.stop; } context->hidden.mem.here = newpos; - return (long)(context->hidden.mem.here - context->hidden.mem.base); + return (Sint64)(context->hidden.mem.here - context->hidden.mem.base); } static size_t SDLCALL @@ -438,14 +470,37 @@ SDL_RWops * SDL_RWFromFile(const char *file, const char *mode) { SDL_RWops *rwops = NULL; -#ifdef HAVE_STDIO_H - FILE *fp = NULL; -#endif if (!file || !*file || !mode || !*mode) { SDL_SetError("SDL_RWFromFile(): No file or no mode specified"); return NULL; } #if defined(ANDROID) +#ifdef HAVE_STDIO_H + /* Try to open the file on the filesystem first */ + if (*file == '/') { + FILE *fp = fopen(file, mode); + if (fp) { + return SDL_RWFromFP(fp, 1); + } + } else { + /* Try opening it from internal storage if it's a relative path */ + char *path; + FILE *fp; + + path = SDL_stack_alloc(char, PATH_MAX); + if (path) { + SDL_snprintf(path, PATH_MAX, "%s/%s", + SDL_AndroidGetInternalStoragePath(), file); + fp = fopen(path, mode); + SDL_stack_free(path); + if (fp) { + return SDL_RWFromFP(fp, 1); + } + } + } +#endif /* HAVE_STDIO_H */ + + /* Try to open the file from the asset system */ rwops = SDL_AllocRW(); if (!rwops) return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ @@ -453,6 +508,7 @@ SDL_RWFromFile(const char *file, const char *mode) SDL_FreeRW(rwops); return NULL; } + rwops->size = Android_JNI_FileSize; rwops->seek = Android_JNI_FileSeek; rwops->read = Android_JNI_FileRead; rwops->write = Android_JNI_FileWrite; @@ -466,21 +522,24 @@ SDL_RWFromFile(const char *file, const char *mode) SDL_FreeRW(rwops); return NULL; } + rwops->size = windows_file_size; 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__ - fp = SDL_OpenFPFromBundleOrFallback(file, mode); - #else - fp = fopen(file, mode); - #endif - if (fp == NULL) { - SDL_SetError("Couldn't open %s", file); - } else { - rwops = SDL_RWFromFP(fp, 1); + { + #ifdef __APPLE__ + FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode); + #else + FILE *fp = fopen(file, mode); + #endif + if (fp == NULL) { + SDL_SetError("Couldn't open %s", file); + } else { + rwops = SDL_RWFromFP(fp, 1); + } } #else SDL_SetError("SDL not compiled with stdio support"); @@ -504,6 +563,7 @@ SDL_RWFromFP(FILE * fp, SDL_bool autoclose) rwops = SDL_AllocRW(); if (rwops != NULL) { + rwops->size = stdio_size; rwops->seek = stdio_seek; rwops->read = stdio_read; rwops->write = stdio_write; @@ -529,6 +589,7 @@ SDL_RWFromMem(void *mem, int size) rwops = SDL_AllocRW(); if (rwops != NULL) { + rwops->size = mem_size; rwops->seek = mem_seek; rwops->read = mem_read; rwops->write = mem_write; @@ -547,6 +608,7 @@ SDL_RWFromConstMem(const void *mem, int size) rwops = SDL_AllocRW(); if (rwops != NULL) { + rwops->size = mem_size; rwops->seek = mem_seek; rwops->read = mem_read; rwops->write = mem_writeconst; @@ -578,10 +640,19 @@ SDL_FreeRW(SDL_RWops * area) /* Functions for dynamically reading and writing endian-specific values */ +Uint8 +SDL_ReadU8(SDL_RWops * src) +{ + Uint8 value = 0; + + SDL_RWread(src, &value, (sizeof value), 1); + return value; +} + Uint16 SDL_ReadLE16(SDL_RWops * src) { - Uint16 value; + Uint16 value = 0; SDL_RWread(src, &value, (sizeof value), 1); return (SDL_SwapLE16(value)); @@ -590,7 +661,7 @@ SDL_ReadLE16(SDL_RWops * src) Uint16 SDL_ReadBE16(SDL_RWops * src) { - Uint16 value; + Uint16 value = 0; SDL_RWread(src, &value, (sizeof value), 1); return (SDL_SwapBE16(value)); @@ -599,7 +670,7 @@ SDL_ReadBE16(SDL_RWops * src) Uint32 SDL_ReadLE32(SDL_RWops * src) { - Uint32 value; + Uint32 value = 0; SDL_RWread(src, &value, (sizeof value), 1); return (SDL_SwapLE32(value)); @@ -608,7 +679,7 @@ SDL_ReadLE32(SDL_RWops * src) Uint32 SDL_ReadBE32(SDL_RWops * src) { - Uint32 value; + Uint32 value = 0; SDL_RWread(src, &value, (sizeof value), 1); return (SDL_SwapBE32(value)); @@ -617,7 +688,7 @@ SDL_ReadBE32(SDL_RWops * src) Uint64 SDL_ReadLE64(SDL_RWops * src) { - Uint64 value; + Uint64 value = 0; SDL_RWread(src, &value, (sizeof value), 1); return (SDL_SwapLE64(value)); @@ -626,12 +697,18 @@ SDL_ReadLE64(SDL_RWops * src) Uint64 SDL_ReadBE64(SDL_RWops * src) { - Uint64 value; + Uint64 value = 0; SDL_RWread(src, &value, (sizeof value), 1); return (SDL_SwapBE64(value)); } +size_t +SDL_WriteU8(SDL_RWops * dst, Uint8 value) +{ + return (SDL_RWwrite(dst, &value, (sizeof value), 1)); +} + size_t SDL_WriteLE16(SDL_RWops * dst, Uint16 value) { diff --git a/src/eepp/helper/SDL2/src/haptic/SDL_haptic.c b/src/eepp/helper/SDL2/src/haptic/SDL_haptic.c old mode 100755 new mode 100644 index 2ab4cbf4d..eca9c9632 --- a/src/eepp/helper/SDL2/src/haptic/SDL_haptic.c +++ b/src/eepp/helper/SDL2/src/haptic/SDL_haptic.c @@ -238,7 +238,7 @@ SDL_JoystickIsHaptic(SDL_Joystick * joystick) int ret; /* Must be a valid joystick */ - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return -1; } @@ -263,7 +263,7 @@ SDL_HapticOpenFromJoystick(SDL_Joystick * joystick) SDL_Haptic *haptic; /* Must be a valid joystick */ - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { SDL_SetError("Haptic: Joystick isn't valid."); return NULL; } @@ -766,7 +766,6 @@ SDL_HapticRumbleInit(SDL_Haptic * haptic) int SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length) { - int ret; SDL_HapticPeriodic *efx; if (!ValidHaptic(haptic)) { @@ -790,7 +789,7 @@ SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length) efx = &haptic->rumble_effect.periodic; efx->magnitude = (Sint16)(32767.0f*strength); efx->length = length; - ret = SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect); + SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect); return SDL_HapticRunEffect(haptic, haptic->rumble_id, 1); } diff --git a/src/eepp/helper/SDL2/src/haptic/SDL_haptic_c.h b/src/eepp/helper/SDL2/src/haptic/SDL_haptic_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/haptic/SDL_syshaptic.h b/src/eepp/helper/SDL2/src/haptic/SDL_syshaptic.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/haptic/darwin/SDL_syshaptic.c b/src/eepp/helper/SDL2/src/haptic/darwin/SDL_syshaptic.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/haptic/dummy/SDL_syshaptic.c b/src/eepp/helper/SDL2/src/haptic/dummy/SDL_syshaptic.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/haptic/linux/SDL_syshaptic.c b/src/eepp/helper/SDL2/src/haptic/linux/SDL_syshaptic.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/haptic/nds/SDL_syshaptic.c b/src/eepp/helper/SDL2/src/haptic/nds/SDL_syshaptic.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/haptic/windows/SDL_syshaptic.c b/src/eepp/helper/SDL2/src/haptic/windows/SDL_syshaptic.c old mode 100755 new mode 100644 index 86ab60372..28bd87582 --- a/src/eepp/helper/SDL2/src/haptic/windows/SDL_syshaptic.c +++ b/src/eepp/helper/SDL2/src/haptic/windows/SDL_syshaptic.c @@ -49,7 +49,7 @@ static struct */ struct haptic_hwdata { - LPDIRECTINPUTDEVICE2 device; + LPDIRECTINPUTDEVICE8 device; DWORD axes[3]; /* Axes to use. */ int is_joystick; /* Device is loaded as joystick. */ }; @@ -69,7 +69,7 @@ struct haptic_hweffect * Internal stuff. */ static SDL_bool coinitialized = SDL_FALSE; -static LPDIRECTINPUT dinput = NULL; +static LPDIRECTINPUT8 dinput = NULL; /* @@ -85,8 +85,8 @@ 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 int SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic, + LPDIRECTINPUTDEVICE8 device8); static DWORD DIGetTriggerButton(Uint16 button); static int SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes); @@ -120,12 +120,7 @@ DI_SetError(const char *str, HRESULT err) 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; + return (SDL_memcmp(a, b, sizeof (GUID)) == 0); } @@ -156,8 +151,8 @@ SDL_SYS_HapticInit(void) coinitialized = SDL_TRUE; - ret = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectInput, (LPVOID) & dinput); + ret = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, + &IID_IDirectInput8, (LPVOID) & dinput); if (FAILED(ret)) { SDL_SYS_HapticQuit(); DI_SetError("CoCreateInstance", ret); @@ -172,7 +167,7 @@ SDL_SYS_HapticInit(void) GetLastError()); return -1; } - ret = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); + ret = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION); if (FAILED(ret)) { SDL_SYS_HapticQuit(); DI_SetError("Initializing DirectInput device", ret); @@ -180,7 +175,7 @@ SDL_SYS_HapticInit(void) } /* Look for haptic devices. */ - ret = IDirectInput_EnumDevices(dinput, + ret = IDirectInput8_EnumDevices(dinput, 0, EnumHapticsCallback, NULL, @@ -202,14 +197,14 @@ static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { HRESULT ret; - LPDIRECTINPUTDEVICE device; + LPDIRECTINPUTDEVICE8 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, + ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL); if (FAILED(ret)) { /* DI_SetError("Creating DirectInput device",ret); */ @@ -218,12 +213,12 @@ EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) /* Get capabilities. */ SDL_hapticlist[SDL_numhaptics].capabilities.dwSize = sizeof(DIDEVCAPS); - ret = IDirectInputDevice_GetCapabilities(device, + ret = IDirectInputDevice8_GetCapabilities(device, &SDL_hapticlist[SDL_numhaptics]. capabilities); if (FAILED(ret)) { /* DI_SetError("Getting device capabilities",ret); */ - IDirectInputDevice_Release(device); + IDirectInputDevice8_Release(device); return DIENUM_CONTINUE; } @@ -231,7 +226,7 @@ EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) SDL_hapticlist[SDL_numhaptics].name = WIN_StringToUTF8(SDL_hapticlist[SDL_numhaptics].instance.tszProductName); /* Close up device and count it. */ - IDirectInputDevice_Release(device); + IDirectInputDevice8_Release(device); SDL_numhaptics++; /* Watch out for hard limit. */ @@ -311,16 +306,16 @@ DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) * * Steps: * - Open temporary DirectInputDevice interface. - * - Create DirectInputDevice2 interface. + * - Create DirectInputDevice8 interface. * - Release DirectInputDevice interface. - * - Call SDL_SYS_HapticOpenFromDevice2 + * - Call SDL_SYS_HapticOpenFromDevice8 */ static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) { HRESULT ret; int ret2; - LPDIRECTINPUTDEVICE device; + LPDIRECTINPUTDEVICE8 device; /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *) @@ -332,26 +327,26 @@ SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); /* Open the device */ - ret = IDirectInput_CreateDevice(dinput, &instance.guidInstance, + ret = IDirectInput8_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, + /* Now get the IDirectInputDevice8 interface, instead. */ + ret = IDirectInputDevice8_QueryInterface(device, + &IID_IDirectInputDevice8, (LPVOID *) & haptic->hwdata-> device); /* Done with the temporary one now. */ - IDirectInputDevice_Release(device); + IDirectInputDevice8_Release(device); if (FAILED(ret)) { DI_SetError("Querying DirectInput interface", ret); goto creat_err; } - ret2 = SDL_SYS_HapticOpenFromDevice2(haptic, haptic->hwdata->device); + ret2 = SDL_SYS_HapticOpenFromDevice8(haptic, haptic->hwdata->device); if (ret2 < 0) { goto query_err; } @@ -359,7 +354,7 @@ SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) return 0; query_err: - IDirectInputDevice2_Release(haptic->hwdata->device); + IDirectInputDevice8_Release(haptic->hwdata->device); creat_err: if (haptic->hwdata != NULL) { SDL_free(haptic->hwdata); @@ -380,17 +375,17 @@ SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) * - Get supported featuers. */ static int -SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, - LPDIRECTINPUTDEVICE2 device2) +SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic, + LPDIRECTINPUTDEVICE8 device8) { HRESULT ret; DIPROPDWORD dipdw; - /* We'll use the device2 from now on. */ - haptic->hwdata->device = device2; + /* We'll use the device8 from now on. */ + haptic->hwdata->device = device8; /* Grab it exclusively to use force feedback stuff. */ - ret = IDirectInputDevice2_SetCooperativeLevel(haptic->hwdata->device, + ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device, SDL_HelperWindow, DISCL_EXCLUSIVE | DISCL_BACKGROUND); @@ -400,7 +395,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, } /* Set data format. */ - ret = IDirectInputDevice2_SetDataFormat(haptic->hwdata->device, + ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device, &c_dfDIJoystick2); if (FAILED(ret)) { DI_SetError("Setting data format", ret); @@ -408,7 +403,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, } /* Get number of axes. */ - ret = IDirectInputDevice2_EnumObjects(haptic->hwdata->device, + ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device, DI_DeviceObjectCallback, haptic, DIDFT_AXIS); if (FAILED(ret)) { @@ -417,14 +412,14 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, } /* Acquire the device. */ - ret = IDirectInputDevice2_Acquire(haptic->hwdata->device); + ret = IDirectInputDevice8_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, + ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_RESET); if (FAILED(ret)) { DI_SetError("Resetting device", ret); @@ -432,7 +427,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, } /* Enabling actuators. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_SETACTUATORSON); if (FAILED(ret)) { DI_SetError("Enabling actuators", ret); @@ -440,7 +435,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, } /* Get supported effects. */ - ret = IDirectInputDevice2_EnumEffects(haptic->hwdata->device, + ret = IDirectInputDevice8_EnumEffects(haptic->hwdata->device, DI_EffectCallback, haptic, DIEFT_ALL); if (FAILED(ret)) { @@ -458,7 +453,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 10000; - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_FFGAIN, &dipdw.diph); if (!FAILED(ret)) { /* Gain is supported. */ haptic->supported |= SDL_HAPTIC_GAIN; @@ -466,7 +461,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = DIPROPAUTOCENTER_OFF; - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_AUTOCENTER, &dipdw.diph); if (!FAILED(ret)) { /* Autocenter is supported. */ haptic->supported |= SDL_HAPTIC_AUTOCENTER; @@ -497,7 +492,7 @@ SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, /* Error handling */ acquire_err: - IDirectInputDevice2_Unacquire(haptic->hwdata->device); + IDirectInputDevice8_Unacquire(haptic->hwdata->device); return -1; } @@ -525,7 +520,7 @@ SDL_SYS_HapticMouse(void) /* Grab the first mouse haptic device we find. */ for (i = 0; i < SDL_numhaptics; i++) { - if (SDL_hapticlist[i].capabilities.dwDevType == DIDEVTYPE_MOUSE) { + if (SDL_hapticlist[i].capabilities.dwDevType == DI8DEVCLASS_POINTER ) { return i; } } @@ -560,12 +555,12 @@ SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) joy_instance.dwSize = sizeof(DIDEVICEINSTANCE); /* Get the device instances. */ - ret = IDirectInputDevice2_GetDeviceInfo(haptic->hwdata->device, + ret = IDirectInputDevice8_GetDeviceInfo(haptic->hwdata->device, &hap_instance); if (FAILED(ret)) { return 0; } - ret = IDirectInputDevice2_GetDeviceInfo(joystick->hwdata->InputDevice, + ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance); if (FAILED(ret)) { return 0; @@ -591,7 +586,7 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */ for (i=0; ihwdata->InputDevice, + idret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance); if (FAILED(idret)) { return -1; @@ -617,7 +612,7 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) /* Now open the device. */ ret = - SDL_SYS_HapticOpenFromDevice2(haptic, joystick->hwdata->InputDevice); + SDL_SYS_HapticOpenFromDevice8(haptic, joystick->hwdata->InputDevice); if (ret < 0) { return -1; } @@ -643,10 +638,10 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic) haptic->neffects = 0; /* Clean up */ - IDirectInputDevice2_Unacquire(haptic->hwdata->device); + IDirectInputDevice8_Unacquire(haptic->hwdata->device); /* Only release if isn't grabbed by a joystick. */ if (haptic->hwdata->is_joystick == 0) { - IDirectInputDevice2_Release(haptic->hwdata->device); + IDirectInputDevice8_Release(haptic->hwdata->device); } /* Free */ @@ -672,7 +667,7 @@ SDL_SYS_HapticQuit(void) } if (dinput != NULL) { - IDirectInput_Release(dinput); + IDirectInput8_Release(dinput); dinput = NULL; } @@ -1153,7 +1148,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, } /* Create the actual effect. */ - ret = IDirectInputDevice2_CreateEffect(haptic->hwdata->device, type, + ret = IDirectInputDevice8_CreateEffect(haptic->hwdata->device, type, &effect->hweffect->effect, &effect->hweffect->ref, NULL); if (FAILED(ret)) { @@ -1324,7 +1319,7 @@ SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) dipdw.dwData = gain * 100; /* 0 to 10,000 */ /* Try to set the autocenter. */ - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_FFGAIN, &dipdw.diph); if (FAILED(ret)) { DI_SetError("Setting gain", ret); @@ -1353,7 +1348,7 @@ SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) DIPROPAUTOCENTER_ON; /* Try to set the autocenter. */ - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_AUTOCENTER, &dipdw.diph); if (FAILED(ret)) { DI_SetError("Setting autocenter", ret); @@ -1373,7 +1368,7 @@ SDL_SYS_HapticPause(SDL_Haptic * haptic) HRESULT ret; /* Pause the device. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_PAUSE); if (FAILED(ret)) { DI_SetError("Pausing the device", ret); @@ -1393,7 +1388,7 @@ SDL_SYS_HapticUnpause(SDL_Haptic * haptic) HRESULT ret; /* Unpause the device. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_CONTINUE); if (FAILED(ret)) { DI_SetError("Pausing the device", ret); @@ -1413,7 +1408,7 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic) HRESULT ret; /* Try to stop the effects. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_STOPALL); if (FAILED(ret)) { DI_SetError("Stopping the device", ret); diff --git a/src/eepp/helper/SDL2/src/joystick/SDL_gamecontroller.c b/src/eepp/helper/SDL2/src/joystick/SDL_gamecontroller.c new file mode 100644 index 000000000..b1de6ee7a --- /dev/null +++ b/src/eepp/helper/SDL2/src/joystick/SDL_gamecontroller.c @@ -0,0 +1,1126 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +/* This is the game controller API for Simple DirectMedia Layer */ + +#include "SDL_events.h" +#include "SDL_assert.h" +#include "SDL_sysjoystick.h" +#include "SDL_hints.h" + +#if !SDL_EVENTS_DISABLED +#include "../events/SDL_events_c.h" +#endif +#define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) + + +/* a list of currently opened game controllers */ +static SDL_GameController *SDL_gamecontrollers = NULL; + +/* keep track of the hat and mask value that transforms this hat movement into a button press */ +struct _SDL_HatAsButton +{ + int hat; + Uint8 mask; +}; + +#define k_nMaxReverseEntries 20 + +/* our in memory mapping db between joystick objects and controller mappings*/ +struct _SDL_ControllerMapping +{ + SDL_JoystickGUID guid; + const char *name; + + // mapping of axis/button id to controller version + int axes[SDL_CONTROLLER_AXIS_MAX]; + int buttons[SDL_CONTROLLER_BUTTON_MAX]; + + int axesasbutton[SDL_CONTROLLER_BUTTON_MAX]; + struct _SDL_HatAsButton hatasbutton[SDL_CONTROLLER_BUTTON_MAX]; + int buttonasaxis[SDL_CONTROLLER_AXIS_MAX]; + + // reverse mapping, joystick indices to buttons + SDL_CONTROLLER_AXIS raxes[k_nMaxReverseEntries]; + SDL_CONTROLLER_BUTTON rbuttons[k_nMaxReverseEntries]; + SDL_CONTROLLER_BUTTON raxesasbutton[k_nMaxReverseEntries]; + struct _SDL_HatAsButton rhatasbutton[k_nMaxReverseEntries]; + SDL_CONTROLLER_AXIS rbuttonasaxis[k_nMaxReverseEntries]; +}; + + +/* our hard coded list of mapping support */ +typedef struct _ControllerMapping_t +{ + SDL_JoystickGUID guid; + char *name; + const char *mapping; + struct _ControllerMapping_t *next; +} ControllerMapping_t; + + +/* default mappings we support */ +const char *s_ControllerMappings [] = +{ +#ifdef SDL_JOYSTICK_DINPUT + "xinput,X360 Controller,a:b10,b:b11,y:b13,x:b12,start:b4,guide:b14,back:b5,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftshoulder:b8,rightshoulder:b9,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5", + "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + "88880803000000000000504944564944,PS3,a:b2,b:b1,x:b0,y:b3,start:b11,back:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,guide:b12", + "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,x:b0,y:b3,start:b8,guide:,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5", +#elif defined(__MACOSX__) + "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftshoulder:b4,rightshoulder:b5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5", + "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,x:b12,y:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b6,dpdown:b7,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9", +#elif defined(__LINUX__) + +#endif + NULL +}; + +static ControllerMapping_t *s_pSupportedControllers = NULL; +#ifdef SDL_JOYSTICK_DINPUT +static ControllerMapping_t *s_pXInputMapping = NULL; +#endif + +/* The SDL game controller structure */ +struct _SDL_GameController +{ + SDL_Joystick *joystick; /* underlying joystick device */ + int ref_count; + struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */ + struct _SDL_GameController *next; /* pointer to next game controller we have allocated */ +}; + + +int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_CONTROLLER_AXIS axis, Sint16 value); +int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_CONTROLLER_BUTTON button, Uint8 state); + +/* + * Event filter to fire controller events from joystick ones + */ +int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) +{ + switch( event->type ) + { + case SDL_JOYAXISMOTION: + { + SDL_GameController *controllerlist = SDL_gamecontrollers; + while ( controllerlist ) + { + if ( controllerlist->joystick->instance_id == event->jaxis.which ) + { + if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) // simple axis to axis, send it through + { + SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.raxes[event->jaxis.axis], event->jaxis.value ); + } + else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) // simlate an axis as a button + { + SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? 1 : 0 ); + } + break; + } + controllerlist = controllerlist->next; + } + } + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + { + SDL_GameController *controllerlist = SDL_gamecontrollers; + while ( controllerlist ) + { + if ( controllerlist->joystick->instance_id == event->jbutton.which ) + { + if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) // simple button as button + { + SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state ); + } + else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) // an button pretending to be an axis + { + SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32768 : 0 ); + } + break; + } + controllerlist = controllerlist->next; + } + } + break; + case SDL_JOYHATMOTION: + { + if ( event->jhat.hat == 0 ) // BUGBUG - multiple hat support?? + { + SDL_GameController *controllerlist = SDL_gamecontrollers; + while ( controllerlist ) + { + if ( controllerlist->joystick->instance_id == event->jhat.which ) + { + static Uint8 bHatsDown = 0; + if ( event->jhat.value == 0 ) + { + if ( bHatsDown & SDL_HAT_DOWN ) + SDL_PrivateGameControllerButton( controllerlist, SDL_CONTROLLER_BUTTON_DPAD_DOWN, 0 ); + if ( bHatsDown & SDL_HAT_UP ) + SDL_PrivateGameControllerButton( controllerlist, SDL_CONTROLLER_BUTTON_DPAD_UP, 0 ); + if ( bHatsDown & SDL_HAT_LEFT ) + SDL_PrivateGameControllerButton( controllerlist, SDL_CONTROLLER_BUTTON_DPAD_LEFT, 0 ); + if ( bHatsDown & SDL_HAT_RIGHT ) + SDL_PrivateGameControllerButton( controllerlist, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 0 ); + bHatsDown = 0; + } + else if ( controllerlist->mapping.rhatasbutton[event->jhat.value].hat >= 0 ) + { + bHatsDown |= event->jhat.value; + SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[event->jhat.value].hat, (event->jhat.value & controllerlist->mapping.rhatasbutton[event->jhat.value].mask) > 0 ? 1 : 0 ); + } + break; + } + controllerlist = controllerlist->next; + } + } + } + break; + case SDL_JOYDEVICEADDED: + { + if ( SDL_IsGameController(event->jdevice.which ) ) + { + SDL_Event deviceevent; + deviceevent.type = SDL_CONTROLLERDEVICEADDED; + deviceevent.cdevice.which = event->jdevice.which; + SDL_PushEvent(&deviceevent); + } + } + break; + case SDL_JOYDEVICEREMOVED: + { + SDL_GameController *controllerlist = SDL_gamecontrollers; + while ( controllerlist ) + { + if ( controllerlist->joystick->instance_id == event->jdevice.which ) + { + SDL_Event deviceevent; + deviceevent.type = SDL_CONTROLLERDEVICEREMOVED; + deviceevent.cdevice.which = event->jdevice.which; + SDL_PushEvent(&deviceevent); + break; + } + controllerlist = controllerlist->next; + } + } + break; + default: + break; + } + + return 1; +} + +/* + * Helper function to determine pre-caclulated offset to certain joystick mappings + */ +ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) +{ +#ifdef SDL_JOYSTICK_DINPUT + if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping ) + { + return s_pXInputMapping; + } +#endif + return NULL; +} + + +/* + * convert a string to its enum equivalent + */ +SDL_CONTROLLER_AXIS SDL_GameControllerGetAxisFromString( const char *pchString ) +{ + if ( !pchString || !pchString[0] ) + return SDL_CONTROLLER_AXIS_INVALID; + + if ( !SDL_strcasecmp( pchString, "leftx" ) ) + return SDL_CONTROLLER_AXIS_LEFTX; + else if ( !SDL_strcasecmp( pchString, "lefty" ) ) + return SDL_CONTROLLER_AXIS_LEFTY; + else if ( !SDL_strcasecmp( pchString, "rightx" ) ) + return SDL_CONTROLLER_AXIS_RIGHTX; + else if ( !SDL_strcasecmp( pchString, "righty" ) ) + return SDL_CONTROLLER_AXIS_RIGHTY; + else if ( !SDL_strcasecmp( pchString, "lefttrigger" ) ) + return SDL_CONTROLLER_AXIS_TRIGGERLEFT; + else if ( !SDL_strcasecmp( pchString, "righttrigger" ) ) + return SDL_CONTROLLER_AXIS_TRIGGERRIGHT; + else + return SDL_CONTROLLER_AXIS_INVALID; +} + + +/* + * convert a string to its enum equivalent + */ +SDL_CONTROLLER_BUTTON SDL_GameControllerGetButtonFromString( const char *pchString ) +{ + if ( !pchString || !pchString[0] ) + return SDL_CONTROLLER_BUTTON_INVALID; + + if ( !SDL_strcasecmp( pchString, "a" ) ) + return SDL_CONTROLLER_BUTTON_A; + else if ( !SDL_strcasecmp( pchString, "b" ) ) + return SDL_CONTROLLER_BUTTON_B; + else if ( !SDL_strcasecmp( pchString, "x" ) ) + return SDL_CONTROLLER_BUTTON_X; + else if ( !SDL_strcasecmp( pchString, "y" ) ) + return SDL_CONTROLLER_BUTTON_Y; + else if ( !SDL_strcasecmp( pchString, "start" ) ) + return SDL_CONTROLLER_BUTTON_START; + else if ( !SDL_strcasecmp( pchString, "guide" ) ) + return SDL_CONTROLLER_BUTTON_GUIDE; + else if ( !SDL_strcasecmp( pchString, "back" ) ) + return SDL_CONTROLLER_BUTTON_BACK; + else if ( !SDL_strcasecmp( pchString, "dpup" ) ) + return SDL_CONTROLLER_BUTTON_DPAD_UP; + else if ( !SDL_strcasecmp( pchString, "dpdown" ) ) + return SDL_CONTROLLER_BUTTON_DPAD_DOWN; + else if ( !SDL_strcasecmp( pchString, "dpleft" ) ) + return SDL_CONTROLLER_BUTTON_DPAD_LEFT; + else if ( !SDL_strcasecmp( pchString, "dpright" ) ) + return SDL_CONTROLLER_BUTTON_DPAD_RIGHT; + else if ( !SDL_strcasecmp( pchString, "leftshoulder" ) ) + return SDL_CONTROLLER_BUTTON_LEFTSHOULDER; + else if ( !SDL_strcasecmp( pchString, "rightshoulder" ) ) + return SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; + else if ( !SDL_strcasecmp( pchString, "leftstick" ) ) + return SDL_CONTROLLER_BUTTON_LEFTSTICK; + else if ( !SDL_strcasecmp( pchString, "rightstick" ) ) + return SDL_CONTROLLER_BUTTON_RIGHTSTICK; + else + return SDL_CONTROLLER_BUTTON_INVALID; +} + + +/* + * given a controller button name and a joystick name update our mapping structure with it + */ +void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping ) +{ + int iSDLButton = 0; + SDL_CONTROLLER_BUTTON button; + SDL_CONTROLLER_AXIS axis; + button = SDL_GameControllerGetButtonFromString( szGameButton ); + axis = SDL_GameControllerGetAxisFromString( szGameButton ); + iSDLButton = SDL_atoi( &szJoystickButton[1] ); + + if ( iSDLButton >= k_nMaxReverseEntries ) + { + SDL_SetError("Button index too large: %d", iSDLButton ); + return; + } + + if ( szJoystickButton[0] == 'a' ) + { + if ( axis != SDL_CONTROLLER_AXIS_INVALID ) + { + pMapping->axes[ axis ] = iSDLButton; + pMapping->raxes[ iSDLButton ] = axis; + } + else if ( button != SDL_CONTROLLER_BUTTON_INVALID ) + { + pMapping->buttonasaxis[ button ] = iSDLButton; + pMapping->rbuttonasaxis[ iSDLButton ] = button; + } + else + { + SDL_assert( !"How did we get here?" ); + } + + } + else if ( szJoystickButton[0] == 'b' ) + { + if ( button != SDL_CONTROLLER_BUTTON_INVALID ) + { + pMapping->buttons[ button ] = iSDLButton; + pMapping->rbuttons[ iSDLButton ] = button; + } + else if ( axis != SDL_CONTROLLER_AXIS_INVALID ) + { + pMapping->buttonasaxis[ axis ] = iSDLButton; + pMapping->rbuttonasaxis[ iSDLButton ] = axis; + } + else + { + SDL_assert( !"How did we get here?" ); + } + } + else if ( szJoystickButton[0] == 'h' ) + { + int hat = SDL_atoi( &szJoystickButton[1] ); + int mask = SDL_atoi( &szJoystickButton[3] ); + + if ( button != SDL_CONTROLLER_BUTTON_INVALID ) + { + pMapping->hatasbutton[ button ].hat = hat; + pMapping->hatasbutton[ button ].mask = mask; + pMapping->rhatasbutton[ mask ].hat = button; + pMapping->rhatasbutton[ mask ].mask = mask; + } + else if ( axis != SDL_CONTROLLER_AXIS_INVALID ) + { + SDL_assert( !"Support hat as axis" ); + } + else + { + SDL_assert( !"How did we get here?" ); + } + } + +} + + +/* + * given a controller mapping string update our mapping object + */ +static void +SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString ) +{ + char szGameButton[20]; + char szJoystickButton[20]; + SDL_bool bGameButton = SDL_TRUE; + int i = 0; + const char *pchPos = pchString; + + SDL_memset( szGameButton, 0x0, sizeof(szGameButton) ); + SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) ); + + while ( pchPos && *pchPos ) + { + if ( *pchPos == ':' ) + { + i = 0; + bGameButton = SDL_FALSE; + } + else if ( *pchPos == ' ' ) + { + + } + else if ( *pchPos == ',' ) + { + i = 0; + bGameButton = SDL_TRUE; + SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping ); + SDL_memset( szGameButton, 0x0, sizeof(szGameButton) ); + SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) ); + + } + else if ( bGameButton ) + { + if ( i >= sizeof(szGameButton)) + { + SDL_SetError( "Button name too large: %s", szGameButton ); + return; + } + szGameButton[i] = *pchPos; + i++; + } + else + { + if ( i >= sizeof(szJoystickButton)) + { + SDL_SetError( "Joystick button name too large: %s", szJoystickButton ); + return; + } + szJoystickButton[i] = *pchPos; + i++; + } + pchPos++; + } + + SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping ); + +} + +/* + * Make a new button mapping struct + */ +void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping ) +{ + int j; + + pMapping->guid = guid; + pMapping->name = pchName; + + // set all the button mappings to non defaults + for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ ) + { + pMapping->axes[j] = -1; + pMapping->buttonasaxis[j] = -1; + } + for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ ) + { + pMapping->buttons[j] = -1; + pMapping->axesasbutton[j] = -1; + pMapping->hatasbutton[j].hat = -1; + } + + for ( j = 0; j < k_nMaxReverseEntries; j++ ) + { + pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID; + pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID; + pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID; + pMapping->rhatasbutton[j].hat = -1; + pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID; + } + + SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping ); +} + + +/* + * grab the guid string from a mapping string + */ +char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping ) +{ + const char *pFirstComma = SDL_strchr( pMapping, ',' ); + if ( pFirstComma ) + { + char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 ); + if ( !pchGUID ) + { + SDL_OutOfMemory(); + return NULL; + } + SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping ); + pchGUID[ pFirstComma - pMapping ] = 0; + return pchGUID; + } + return NULL; +} + + +/* + * grab the name string from a mapping string + */ +char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping ) +{ + const char *pFirstComma = SDL_strchr( pMapping, ',' ); + const char *pSecondComma = SDL_strchr( pFirstComma + 1, ',' ); + if ( pFirstComma && pSecondComma ) + { + char *pchName = SDL_malloc( pSecondComma - pFirstComma ); + if ( !pchName ) + { + SDL_OutOfMemory(); + return NULL; + } + SDL_memcpy( pchName, pFirstComma + 1, pSecondComma - pFirstComma ); + pchName[ pSecondComma - pFirstComma - 1 ] = 0; + return pchName; + } + return NULL; +} + + +/* + * grab the button mapping string from a mapping string + */ +const char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping ) +{ + const char *pFirstComma = SDL_strchr( pMapping, ',' ); + const char *pSecondComma = SDL_strchr( pFirstComma + 1, ',' ); + if ( pSecondComma ) + return pSecondComma + 1; // mapping is everything after the 3rd comma, no need to malloc it + else + return NULL; +} + + +/* + * Initialize the game controller system, mostly load our DB of controller config mappings + */ +int +SDL_GameControllerInit(void) +{ + int i = 0; + const char *pMappingString = NULL; + s_pSupportedControllers = NULL; + pMappingString = s_ControllerMappings[i]; + while ( pMappingString ) + { + ControllerMapping_t *pControllerMapping; + char *pchGUID; + char *pchName; + const char *pchMapping; + pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) ); + if ( !pControllerMapping ) + { + SDL_OutOfMemory(); + return -1; + } + + pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( pMappingString ); + pchName = SDL_PrivateGetControllerNameFromMappingString( pMappingString ); + pchMapping = SDL_PrivateGetControllerMappingFromMappingString( pMappingString ); + if ( pchGUID && pchName ) + { +#ifdef SDL_JOYSTICK_DINPUT + if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) + { + s_pXInputMapping = pControllerMapping; + } +#endif + pControllerMapping->guid = SDL_JoystickGetGUIDFromString( pchGUID ); + pControllerMapping->name = pchName; + pControllerMapping->mapping = pchMapping; + pControllerMapping->next = s_pSupportedControllers; + s_pSupportedControllers = pControllerMapping; + + SDL_free( pchGUID ); + } + + i++; + pMappingString = s_ControllerMappings[i]; + } + + // load in any user supplied config + { + const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG); + if ( hint && hint[0] ) + { + int nchHints = SDL_strlen( hint ); + char *pUserMappings = SDL_malloc( nchHints + 1 ); + SDL_memcpy( pUserMappings, hint, nchHints ); + while ( pUserMappings ) + { + char *pchGUID; + char *pchName; + const char *pchMapping; + char *pchNewLine = NULL; + ControllerMapping_t *pControllerMapping; + + pchNewLine = SDL_strchr( pUserMappings, '\n' ); + if ( pchNewLine ) + *pchNewLine = '\0'; + + pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) ); + if ( !pControllerMapping ) + { + SDL_OutOfMemory(); + return -1; + } + + pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( pUserMappings ); + pchName = SDL_PrivateGetControllerNameFromMappingString( pUserMappings ); + pchMapping = SDL_PrivateGetControllerMappingFromMappingString( pUserMappings ); + + if ( pchGUID && pchName ) + { +#ifdef SDL_JOYSTICK_DINPUT + if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) + { + s_pXInputMapping = pControllerMapping; + } +#endif + + pControllerMapping->guid = SDL_JoystickGetGUIDFromString( pchGUID ); + pControllerMapping->name = pchName; + pControllerMapping->mapping = pchMapping; + pControllerMapping->next = s_pSupportedControllers; + s_pSupportedControllers = pControllerMapping; + + SDL_free( pchGUID ); + } + + if ( pchNewLine ) + pUserMappings = pchNewLine + 1; + else + pUserMappings = NULL; + } + } + } + + /* watch for joy events and fire controller ones if needed */ + SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL ); + return (0); +} + + +/* + * Get the implementation dependent name of a controller + */ +const char * +SDL_GameControllerNameForIndex(int device_index) +{ + ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index); + if ( pSupportedController ) + { + return pSupportedController->name; + } + else + { + SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index ); + pSupportedController = s_pSupportedControllers; + while ( pSupportedController ) + { + if ( !SDL_memcmp( &jGUID, &pSupportedController->guid, sizeof(jGUID) ) ) + { + return pSupportedController->name; + } + pSupportedController = pSupportedController->next; + } + } + return NULL; +} + + +/* + * Return 1 if the joystick at this device index is a supported controller + */ +int SDL_IsGameController(int device_index) +{ + ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index); + if ( pSupportedController ) + { + return 1; + } + else + { + SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index ); + pSupportedController = s_pSupportedControllers; + // debug code to help get the guid string for a new joystick + /* char szGUID[33]; + SDL_JoystickGetGUIDString( jGUID, szGUID, sizeof(szGUID) ); + printf( "%s\n", pchGUID ); + SDL_free( pchGUID );*/ + while ( pSupportedController ) + { + if ( !SDL_memcmp( &jGUID, &pSupportedController->guid, sizeof(jGUID) ) ) + { + return 1; + } + pSupportedController = pSupportedController->next; + } + } + return 0; +} + +/* + * Open a controller for use - the index passed as an argument refers to + * the N'th controller on the system. This index is the value which will + * identify this controller in future controller events. + * + * This function returns a controller identifier, or NULL if an error occurred. + */ +SDL_GameController * +SDL_GameControllerOpen(int device_index) +{ + SDL_GameController *gamecontroller; + SDL_GameController *gamecontrollerlist; + ControllerMapping_t *pSupportedController = NULL; + + if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) { + SDL_SetError("There are %d joysticks available", SDL_NumJoysticks()); + return (NULL); + } + + gamecontrollerlist = SDL_gamecontrollers; + // If the controller is already open, return it + while ( gamecontrollerlist ) + { + if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) { + gamecontroller = gamecontrollerlist; + ++gamecontroller->ref_count; + return (gamecontroller); + } + gamecontrollerlist = gamecontrollerlist->next; + } + + // Create and initialize the joystick + gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller)); + if (gamecontroller == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + pSupportedController = SDL_PrivateGetControllerMapping(device_index); + if ( !pSupportedController ) + { + SDL_JoystickGUID jGUID; + + jGUID = SDL_JoystickGetDeviceGUID( device_index ); + pSupportedController = s_pSupportedControllers; + while ( pSupportedController ) + { + if ( !SDL_memcmp( &jGUID, &pSupportedController->guid, sizeof(jGUID) ) ) + { + break; + } + + pSupportedController = pSupportedController->next; + } + } + + if ( !pSupportedController ) + { + SDL_SetError("Couldn't find mapping for device (%d)", device_index ); + return (NULL); + } + + SDL_memset(gamecontroller, 0, (sizeof *gamecontroller)); + gamecontroller->joystick = SDL_JoystickOpen(device_index); + if ( !gamecontroller->joystick ) { + SDL_free(gamecontroller); + return NULL; + } + + SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping ); + + // Add joystick to list + ++gamecontroller->ref_count; + // Link the joystick in the list + gamecontroller->next = SDL_gamecontrollers; + SDL_gamecontrollers = gamecontroller; + + SDL_SYS_JoystickUpdate( gamecontroller->joystick ); + + return (gamecontroller); +} + + +/* + * Get the current state of an axis control on a controller + */ +Sint16 +SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_CONTROLLER_AXIS axis) +{ + if ( !gamecontroller ) + return 0; + + if (gamecontroller->mapping.axes[axis] >= 0 ) + { + return ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) ); + } + else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 ) + { + Uint8 value; + value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] ); + if ( value > 0 ) + return 32767; + return 0; + } + return 0; +} + + +/* + * Get the current state of a button on a controller + */ +Uint8 +SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_CONTROLLER_BUTTON button) +{ + if ( !gamecontroller ) + return 0; + + if ( gamecontroller->mapping.buttons[button] >= 0 ) + { + return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) ); + } + else if ( gamecontroller->mapping.axesasbutton[button] >= 0 ) + { + Sint16 value; + value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] ); + if ( ABS(value) > 32768/2 ) + return 1; + return 0; + } + else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 ) + { + Uint8 value; + value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat ); + + if ( value & gamecontroller->mapping.hatasbutton[button].mask ) + return 1; + return 0; + } + + return 0; +} + +/* + * Return if the joystick in question is currently attached to the system, + * \return 0 if not plugged in, 1 if still present. + */ +int +SDL_GameControllerGetAttached( SDL_GameController * gamecontroller ) +{ + if ( !gamecontroller ) + return 0; + + return SDL_JoystickGetAttached(gamecontroller->joystick); +} + + +/* + * Get the number of multi-dimensional axis controls on a joystick + */ +const char * +SDL_GameControllerName(SDL_GameController * gamecontroller) +{ + if ( !gamecontroller ) + return NULL; + + return (gamecontroller->mapping.name); +} + + +/* + * Get the joystick for this controller + */ +SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller) +{ + if ( !gamecontroller ) + return NULL; + + return gamecontroller->joystick; +} + +/** + * get the sdl joystick layer binding for this controller axi mapping + */ +SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis( SDL_GameController * gamecontroller, SDL_CONTROLLER_AXIS axis ) +{ + SDL_GameControllerButtonBind bind; + SDL_memset( &bind, 0x0, sizeof(bind) ); + + if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID ) + return bind; + + if (gamecontroller->mapping.axes[axis] >= 0 ) + { + bind.m_eBindType = SDL_CONTROLLER_BINDTYPE_AXIS; + bind.button = gamecontroller->mapping.axes[axis]; + } + else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 ) + { + bind.m_eBindType = SDL_CONTROLLER_BINDTYPE_BUTTON; + bind.button = gamecontroller->mapping.buttonasaxis[axis]; + } + + return bind; +} + + +/** + * get the sdl joystick layer binding for this controller button mapping + */ +SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton( SDL_GameController * gamecontroller, SDL_CONTROLLER_BUTTON button ) +{ + SDL_GameControllerButtonBind bind; + SDL_memset( &bind, 0x0, sizeof(bind) ); + + if ( !gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID ) + return bind; + + if ( gamecontroller->mapping.buttons[button] >= 0 ) + { + bind.m_eBindType = SDL_CONTROLLER_BINDTYPE_BUTTON; + bind.button = gamecontroller->mapping.buttons[button]; + } + else if ( gamecontroller->mapping.axesasbutton[button] >= 0 ) + { + bind.m_eBindType = SDL_CONTROLLER_BINDTYPE_AXIS; + bind.axis = gamecontroller->mapping.axesasbutton[button]; + } + else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 ) + { + bind.m_eBindType = SDL_CONTROLLER_BINDTYPE_HAT; + bind.hat.hat = gamecontroller->mapping.hatasbutton[button].hat; + bind.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask; + } + + return bind; +} + + +/* + * Close a joystick previously opened with SDL_JoystickOpen() + */ +void +SDL_GameControllerClose(SDL_GameController * gamecontroller) +{ + SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev; + + if ( !gamecontroller ) + return; + + // First decrement ref count + if (--gamecontroller->ref_count > 0) { + return; + } + + SDL_JoystickClose( gamecontroller->joystick ); + + gamecontrollerlist = SDL_gamecontrollers; + gamecontrollerlistprev = NULL; + while ( gamecontrollerlist ) + { + if (gamecontroller == gamecontrollerlist) + { + if ( gamecontrollerlistprev ) + { + // unlink this entry + gamecontrollerlistprev->next = gamecontrollerlist->next; + } + else + { + SDL_gamecontrollers = gamecontroller->next; + } + + break; + } + gamecontrollerlistprev = gamecontrollerlist; + gamecontrollerlist = gamecontrollerlist->next; + } + + SDL_free(gamecontroller); +} + + +/* + * Quit the controller subsystem + */ +void +SDL_GameControllerQuit(void) +{ + ControllerMapping_t *pControllerMap; + while ( SDL_gamecontrollers ) + { + SDL_gamecontrollers->ref_count = 1; + SDL_GameControllerClose(SDL_gamecontrollers); + } + + pControllerMap = s_pSupportedControllers; + while ( s_pSupportedControllers ) + { + pControllerMap = s_pSupportedControllers; + s_pSupportedControllers = s_pSupportedControllers->next; + SDL_free( pControllerMap->name ); + SDL_free( pControllerMap ); + } + + SDL_DelEventWatch( SDL_GameControllerEventWatcher, NULL ); + +} + +/* + * Event filter to transform joystick events into appropriate game controller ones + */ +int +SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_CONTROLLER_AXIS axis, Sint16 value) +{ + int posted; + + /* translate the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_CONTROLLERAXISMOTION; + event.caxis.which = gamecontroller->joystick->instance_id; + event.caxis.axis = axis; + event.caxis.value = value; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return (posted); +} + + +/* + * Event filter to transform joystick events into appropriate game controller ones + */ +int +SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_CONTROLLER_BUTTON button, Uint8 state) +{ + int posted; +#if !SDL_EVENTS_DISABLED + SDL_Event event; + + switch (state) { + case SDL_PRESSED: + event.type = SDL_CONTROLLERBUTTONDOWN; + break; + case SDL_RELEASED: + event.type = SDL_CONTROLLERBUTTONUP; + break; + default: + /* Invalid state -- bail */ + return (0); + } +#endif /* !SDL_EVENTS_DISABLED */ + + /* translate the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.cbutton.which = gamecontroller->joystick->instance_id; + event.cbutton.button = button; + event.cbutton.state = state; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return (posted); +} + +/* + * Turn off controller events + */ +int +SDL_GameControllerEventState(int state) +{ +#if SDL_EVENTS_DISABLED + return SDL_IGNORE; +#else + const Uint32 event_list[] = { + SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, + }; + unsigned int i; + + switch (state) { + case SDL_QUERY: + state = SDL_IGNORE; + for (i = 0; i < SDL_arraysize(event_list); ++i) { + state = SDL_EventState(event_list[i], SDL_QUERY); + if (state == SDL_ENABLE) { + break; + } + } + break; + default: + for (i = 0; i < SDL_arraysize(event_list); ++i) { + SDL_EventState(event_list[i], state); + } + break; + } + return (state); +#endif /* SDL_EVENTS_DISABLED */ +} + + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/SDL_joystick.c b/src/eepp/helper/SDL2/src/joystick/SDL_joystick.c old mode 100755 new mode 100644 index 9bc6e5864..fe45a023d --- a/src/eepp/helper/SDL2/src/joystick/SDL_joystick.c +++ b/src/eepp/helper/SDL2/src/joystick/SDL_joystick.c @@ -24,34 +24,23 @@ #include "SDL_events.h" #include "SDL_sysjoystick.h" -#include "SDL_joystick_c.h" #include "SDL_assert.h" #if !SDL_EVENTS_DISABLED #include "../events/SDL_events_c.h" #endif -Uint8 SDL_numjoysticks = 0; -SDL_Joystick **SDL_joysticks = NULL; +static SDL_Joystick *SDL_joysticks = NULL; +static SDL_Joystick *SDL_updating_joystick = NULL; int SDL_JoystickInit(void) { - int arraylen; int status; - SDL_numjoysticks = 0; status = SDL_SYS_JoystickInit(); if (status >= 0) { - arraylen = (status + 1) * sizeof(*SDL_joysticks); - SDL_joysticks = (SDL_Joystick **) SDL_malloc(arraylen); - if (SDL_joysticks == NULL) { - SDL_numjoysticks = 0; - } else { - SDL_memset(SDL_joysticks, 0, arraylen); - SDL_numjoysticks = status; - } - status = 0; + status = 0; } return (status); } @@ -62,20 +51,20 @@ SDL_JoystickInit(void) int SDL_NumJoysticks(void) { - return SDL_numjoysticks; + return SDL_SYS_NumJoysticks(); } /* * Get the implementation dependent name of a joystick */ const char * -SDL_JoystickName(int device_index) +SDL_JoystickNameForIndex(int device_index) { - if ((device_index < 0) || (device_index >= SDL_numjoysticks)) { - SDL_SetError("There are %d joysticks available", SDL_numjoysticks); + if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) { + SDL_SetError("There are %d joysticks available", SDL_NumJoysticks()); return (NULL); } - return (SDL_SYS_JoystickName(device_index)); + return (SDL_SYS_JoystickNameForDeviceIndex(device_index)); } /* @@ -88,21 +77,27 @@ SDL_JoystickName(int device_index) SDL_Joystick * SDL_JoystickOpen(int device_index) { - int i; SDL_Joystick *joystick; + SDL_Joystick *joysticklist; + const char *joystickname = NULL; - if ((device_index < 0) || (device_index >= SDL_numjoysticks)) { - SDL_SetError("There are %d joysticks available", SDL_numjoysticks); + if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) { + SDL_SetError("There are %d joysticks available", SDL_NumJoysticks()); return (NULL); } - /* If the joystick is already open, return it */ - for (i = 0; SDL_joysticks[i]; ++i) { - if (device_index == SDL_joysticks[i]->index) { - joystick = SDL_joysticks[i]; - ++joystick->ref_count; - return (joystick); - } + joysticklist = SDL_joysticks; + /* If the joystick is already open, return it + * it is important that we have a single joystick * for each instance id + */ + while ( joysticklist ) + { + if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == joysticklist->instance_id ) { + joystick = joysticklist; + ++joystick->ref_count; + return (joystick); + } + joysticklist = joysticklist->next; } /* Create and initialize the joystick */ @@ -113,11 +108,17 @@ SDL_JoystickOpen(int device_index) } SDL_memset(joystick, 0, (sizeof *joystick)); - joystick->index = device_index; - if (SDL_SYS_JoystickOpen(joystick) < 0) { + if (SDL_SYS_JoystickOpen(joystick, device_index) < 0) { SDL_free(joystick); return NULL; } + + joystickname = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + if ( joystickname ) + joystick->name = SDL_strdup( joystickname ); + else + joystick->name = NULL; + if (joystick->naxes > 0) { joystick->axes = (Sint16 *) SDL_malloc (joystick->naxes * sizeof(Sint16)); @@ -158,68 +159,46 @@ SDL_JoystickOpen(int device_index) /* Add joystick to list */ ++joystick->ref_count; - for (i = 0; SDL_joysticks[i]; ++i) - /* Skip to next joystick */ ; - SDL_joysticks[i] = joystick; + /* Link the joystick in the list */ + joystick->next = SDL_joysticks; + SDL_joysticks = joystick; + + SDL_SYS_JoystickUpdate( joystick ); return (joystick); } -/* - * Returns 1 if the joystick has been opened, or 0 if it has not. - */ -int -SDL_JoystickOpened(int device_index) -{ - int i, opened; - - opened = 0; - for (i = 0; SDL_joysticks[i]; ++i) { - if (SDL_joysticks[i]->index == (Uint8) device_index) { - opened = 1; - break; - } - } - return (opened); -} - /* * Checks to make sure the joystick is valid. */ int -SDL_PrivateJoystickValid(SDL_Joystick ** joystick) +SDL_PrivateJoystickValid(SDL_Joystick * joystick) { int valid; - if (*joystick == NULL) { + if ( joystick == NULL ) { SDL_SetError("Joystick hasn't been opened yet"); valid = 0; } else { valid = 1; } + + if ( joystick && joystick->closed ) + { + valid = 0; + } + return valid; } -/* - * Get the device index of an opened joystick. - */ -int -SDL_JoystickIndex(SDL_Joystick * joystick) -{ - if (!SDL_PrivateJoystickValid(&joystick)) { - return (-1); - } - return (joystick->index); -} - /* * Get the number of multi-dimensional axis controls on a joystick */ int SDL_JoystickNumAxes(SDL_Joystick * joystick) { - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (-1); } return (joystick->naxes); @@ -231,7 +210,7 @@ SDL_JoystickNumAxes(SDL_Joystick * joystick) int SDL_JoystickNumHats(SDL_Joystick * joystick) { - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (-1); } return (joystick->nhats); @@ -243,7 +222,7 @@ SDL_JoystickNumHats(SDL_Joystick * joystick) int SDL_JoystickNumBalls(SDL_Joystick * joystick) { - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (-1); } return (joystick->nballs); @@ -255,7 +234,7 @@ SDL_JoystickNumBalls(SDL_Joystick * joystick) int SDL_JoystickNumButtons(SDL_Joystick * joystick) { - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (-1); } return (joystick->nbuttons); @@ -269,7 +248,7 @@ SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis) { Sint16 state; - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (0); } if (axis < joystick->naxes) { @@ -289,7 +268,7 @@ SDL_JoystickGetHat(SDL_Joystick * joystick, int hat) { Uint8 state; - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (0); } if (hat < joystick->nhats) { @@ -309,7 +288,7 @@ SDL_JoystickGetBall(SDL_Joystick * joystick, int ball, int *dx, int *dy) { int retval; - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (-1); } @@ -338,7 +317,7 @@ SDL_JoystickGetButton(SDL_Joystick * joystick, int button) { Uint8 state; - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!SDL_PrivateJoystickValid(joystick)) { return (0); } if (button < joystick->nbuttons) { @@ -350,15 +329,56 @@ SDL_JoystickGetButton(SDL_Joystick * joystick, int button) return (state); } +/* + * Return if the joystick in question is currently attached to the system, + * \return 0 if not plugged in, 1 if still present. + */ +SDL_bool +SDL_JoystickGetAttached(SDL_Joystick * joystick) +{ + if (!SDL_PrivateJoystickValid(joystick)) { + return SDL_FALSE; + } + + return SDL_SYS_JoystickAttached(joystick); +} + +/* + * Get the instance id for this opened joystick + */ +SDL_JoystickID +SDL_JoystickInstanceID(SDL_Joystick * joystick) +{ + if (!SDL_PrivateJoystickValid(joystick)) { + return (-1); + } + + return (joystick->instance_id); +} + +/* + * Get the friendly name of this joystick + */ +const char * +SDL_JoystickName(SDL_Joystick * joystick) +{ + if (!SDL_PrivateJoystickValid(joystick)) { + return (NULL); + } + + return (joystick->name); +} + /* * Close a joystick previously opened with SDL_JoystickOpen() */ void SDL_JoystickClose(SDL_Joystick * joystick) { - int i; + SDL_Joystick *joysticklist; + SDL_Joystick *joysticklistprev; - if (!SDL_PrivateJoystickValid(&joystick)) { + if (!joystick) { return; } @@ -367,17 +387,37 @@ SDL_JoystickClose(SDL_Joystick * joystick) return; } - SDL_SYS_JoystickClose(joystick); - - /* Remove joystick from list */ - for (i = 0; SDL_joysticks[i]; ++i) { - if (joystick == SDL_joysticks[i]) { - SDL_memmove(&SDL_joysticks[i], &SDL_joysticks[i + 1], - (SDL_numjoysticks - i) * sizeof(joystick)); - break; - } + if (joystick == SDL_updating_joystick) { + return; } + SDL_SYS_JoystickClose(joystick); + + joysticklist = SDL_joysticks; + joysticklistprev = NULL; + while ( joysticklist ) + { + if (joystick == joysticklist) + { + if ( joysticklistprev ) + { + // unlink this entry + joysticklistprev->next = joysticklist->next; + } + else + { + SDL_joysticks = joystick->next; + } + + break; + } + joysticklistprev = joysticklist; + joysticklist = joysticklist->next; + } + + if (joystick->name) + SDL_free(joystick->name); + /* Free the data associated with this joystick */ if (joystick->axes) { SDL_free(joystick->axes); @@ -397,26 +437,18 @@ SDL_JoystickClose(SDL_Joystick * joystick) void SDL_JoystickQuit(void) { - const int numsticks = SDL_numjoysticks; - int i; + /* Make sure we're not getting called in the middle of updating joysticks */ + SDL_assert(!SDL_updating_joystick); /* Stop the event polling */ - SDL_numjoysticks = 0; - - for (i = numsticks; i--; ) { - SDL_Joystick *stick = SDL_joysticks[i]; - if (stick && (stick->ref_count >= 1)) { - stick->ref_count = 1; - SDL_JoystickClose(stick); - } - } + while ( SDL_joysticks ) + { + SDL_joysticks->ref_count = 1; + SDL_JoystickClose(SDL_joysticks); + } /* Quit the joystick setup */ SDL_SYS_JoystickQuit(); - if (SDL_joysticks) { - SDL_free(SDL_joysticks); - SDL_joysticks = NULL; - } } @@ -433,6 +465,9 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) } /* Update internal joystick state */ + if (value == joystick->axes[axis]) { + return 0; + } joystick->axes[axis] = value; /* Post the event, if desired */ @@ -441,14 +476,10 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) { SDL_Event event; event.type = SDL_JOYAXISMOTION; - event.jaxis.which = joystick->index; + event.jaxis.which = joystick->instance_id; event.jaxis.axis = axis; event.jaxis.value = value; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - posted = 1; - SDL_PushEvent(&event); - } + posted = SDL_PushEvent(&event) == 1; } #endif /* !SDL_EVENTS_DISABLED */ return (posted); @@ -473,14 +504,10 @@ SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) if (SDL_GetEventState(SDL_JOYHATMOTION) == SDL_ENABLE) { SDL_Event event; event.jhat.type = SDL_JOYHATMOTION; - event.jhat.which = joystick->index; + event.jhat.which = joystick->instance_id; event.jhat.hat = hat; event.jhat.value = value; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - posted = 1; - SDL_PushEvent(&event); - } + posted = SDL_PushEvent(&event) == 1; } #endif /* !SDL_EVENTS_DISABLED */ return (posted); @@ -507,15 +534,11 @@ SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball, if (SDL_GetEventState(SDL_JOYBALLMOTION) == SDL_ENABLE) { SDL_Event event; event.jball.type = SDL_JOYBALLMOTION; - event.jball.which = joystick->index; + event.jball.which = joystick->instance_id; event.jball.ball = ball; event.jball.xrel = xrel; event.jball.yrel = yrel; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - posted = 1; - SDL_PushEvent(&event); - } + posted = SDL_PushEvent(&event) == 1; } #endif /* !SDL_EVENTS_DISABLED */ return (posted); @@ -553,14 +576,10 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) posted = 0; #if !SDL_EVENTS_DISABLED if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jbutton.which = joystick->index; + event.jbutton.which = joystick->instance_id; event.jbutton.button = button; event.jbutton.state = state; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - posted = 1; - SDL_PushEvent(&event); - } + posted = SDL_PushEvent(&event) == 1; } #endif /* !SDL_EVENTS_DISABLED */ return (posted); @@ -569,11 +588,49 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) void SDL_JoystickUpdate(void) { - int i; + SDL_Joystick *joystick; + + joystick = SDL_joysticks; + while ( joystick ) + { + SDL_Joystick *joysticknext; + /* save off the next pointer, the Update call may cause a joystick removed event + * and cause our joystick pointer to be freed + */ + joysticknext = joystick->next; - for (i = 0; SDL_joysticks[i]; ++i) { - SDL_SYS_JoystickUpdate(SDL_joysticks[i]); - } + SDL_updating_joystick = joystick; + + SDL_SYS_JoystickUpdate( joystick ); + + if ( joystick->closed && joystick->uncentered ) + { + int i; + joystick->uncentered = 0; + + /* Tell the app that everything is centered/unpressed... */ + for (i = 0; i < joystick->naxes; i++) + SDL_PrivateJoystickAxis(joystick, i, 0); + + for (i = 0; i < joystick->nbuttons; i++) + SDL_PrivateJoystickButton(joystick, i, 0); + + for (i = 0; i < joystick->nhats; i++) + SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); + + } + + SDL_updating_joystick = NULL; + + /* If the joystick was closed while updating, free it here */ + if ( joystick->ref_count <= 0 ) { + SDL_JoystickClose(joystick); + } + + joystick = joysticknext; + } + + SDL_SYS_JoystickDetect(); } int @@ -584,7 +641,7 @@ SDL_JoystickEventState(int state) #else const Uint32 event_list[] = { SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION, - SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, + SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED }; unsigned int i; @@ -608,4 +665,113 @@ SDL_JoystickEventState(int state) #endif /* SDL_EVENTS_DISABLED */ } +/* return 1 if you want to run the joystick update loop this frame, used by hotplug support */ +SDL_bool +SDL_PrivateJoystickNeedsPolling() +{ + if ( SDL_SYS_JoystickNeedsPolling() ) + { + // sys layer needs us to think + return SDL_TRUE; + } + else + { + // otherwise only do it if a joystick is opened + return SDL_joysticks != NULL; + } +} + + +/* return the guid for this index */ +SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index) +{ + return SDL_SYS_JoystickGetDeviceGUID( device_index ); +} + +/* return the guid for this opened device */ +SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick * joystick) +{ + return SDL_SYS_JoystickGetGUID( joystick ); +} + +/* convert the guid to a printable string */ +void SDL_JoystickGetGUIDString( SDL_JoystickGUID guid, char *pszGUID, int cbGUID ) +{ + static const char k_rgchHexToASCII[] = "0123456789abcdef"; + int i; + + if ((pszGUID == NULL) || (cbGUID <= 0)) { + return; + } + + for ( i = 0; i < sizeof(guid.data) && i < (cbGUID-1); i++ ) + { + // each input byte writes 2 ascii chars, and might write a null byte. + // If we don't have room for next input byte, stop + unsigned char c = guid.data[i]; + + *pszGUID++ = k_rgchHexToASCII[ c >> 4 ]; + *pszGUID++ = k_rgchHexToASCII[ c & 0x0F ]; + } + *pszGUID = '\0'; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the 4 bit nibble for a hex character +// Input : c - +// Output : unsigned char +//----------------------------------------------------------------------------- +static unsigned char nibble( char c ) +{ + if ( ( c >= '0' ) && + ( c <= '9' ) ) + { + return (unsigned char)(c - '0'); + } + + if ( ( c >= 'A' ) && + ( c <= 'F' ) ) + { + return (unsigned char)(c - 'A' + 0x0a); + } + + if ( ( c >= 'a' ) && + ( c <= 'f' ) ) + { + return (unsigned char)(c - 'a' + 0x0a); + } + + // received an invalid character, and no real way to return an error + // AssertMsg1( false, "Q_nibble invalid hex character '%c' ", c ); + return 0; +} + + +/* convert the string version of a joystick guid to the struct */ +SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) +{ + SDL_JoystickGUID guid; + int maxoutputbytes= sizeof(guid); + int len = SDL_strlen( pchGUID ); + Uint8 *p; + int i; + + // Make sure it's even + len = ( len ) & ~0x1; + + SDL_memset( &guid, 0x00, sizeof(guid) ); + + p = (Uint8 *)&guid; + for ( i = 0; + ( i < len ) && ( ( p - (Uint8 *)&guid ) < maxoutputbytes ); + i+=2, p++ ) + { + *p = ( nibble( pchGUID[i] ) << 4 ) | nibble( pchGUID[i+1] ); + } + + return guid; +} + + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/SDL_joystick_c.h b/src/eepp/helper/SDL2/src/joystick/SDL_joystick_c.h old mode 100755 new mode 100644 index 1705219c2..221fffa47 --- a/src/eepp/helper/SDL2/src/joystick/SDL_joystick_c.h +++ b/src/eepp/helper/SDL2/src/joystick/SDL_joystick_c.h @@ -23,13 +23,15 @@ /* Useful functions and variables from SDL_joystick.c */ #include "SDL_joystick.h" -/* The number of available joysticks on the system */ -extern Uint8 SDL_numjoysticks; - /* Initialization and shutdown functions */ extern int SDL_JoystickInit(void); extern void SDL_JoystickQuit(void); +/* Initialization and shutdown functions */ +extern int SDL_GameControllerInit(void); +extern void SDL_GameControllerQuit(void); + + /* Internal event queueing functions */ extern int SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value); @@ -39,8 +41,11 @@ extern int SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value); extern int SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state); + +/* Helper function to let lower sys layer tell the event system if the joystick code needs to think */ +extern SDL_bool SDL_PrivateJoystickNeedsPolling(); /* Internal sanity checking functions */ -extern int SDL_PrivateJoystickValid(SDL_Joystick ** joystick); +extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/SDL_sysjoystick.h b/src/eepp/helper/SDL2/src/joystick/SDL_sysjoystick.h old mode 100755 new mode 100644 index 2a9b78595..1821beec7 --- a/src/eepp/helper/SDL2/src/joystick/SDL_sysjoystick.h +++ b/src/eepp/helper/SDL2/src/joystick/SDL_sysjoystick.h @@ -23,12 +23,13 @@ /* This is the system specific header for the SDL joystick API */ #include "SDL_joystick.h" +#include "SDL_joystick_c.h" /* The SDL joystick structure */ struct _SDL_Joystick { - Uint8 index; /* Device index */ - const char *name; /* Joystick name - system dependent */ + int instance_id; /* Device instance, monotonically increasing from 0 */ + char *name; /* Joystick name - system dependent */ int naxes; /* Number of axis controls on the joystick */ Sint16 *axes; /* Current axis states */ @@ -49,6 +50,10 @@ struct _SDL_Joystick struct joystick_hwdata *hwdata; /* Driver dependent information */ int ref_count; /* Reference count for multiple opens */ + + Uint8 closed; /* 1 if this device is no longer valid */ + Uint8 uncentered; /* 1 if this device needs to have its state reset to 0 */ + struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */ }; /* Function to scan the system for joysticks. @@ -58,15 +63,32 @@ struct _SDL_Joystick */ extern int SDL_SYS_JoystickInit(void); +/* Function to return the number of joystick devices plugged in right now */ +extern int SDL_SYS_NumJoysticks(); + +/* Function to cause any queued joystick insertions to be processed */ +extern void SDL_SYS_JoystickDetect(); + +/* Function to determine if the joystick loop needs to run right now */ +extern SDL_bool SDL_SYS_JoystickNeedsPolling(); + /* Function to get the device-dependent name of a joystick */ -extern const char *SDL_SYS_JoystickName(int index); +extern const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index); + +/* Function to get the current instance id of the joystick located at device_index */ +extern SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index); /* 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. */ -extern int SDL_SYS_JoystickOpen(SDL_Joystick * joystick); +extern int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index); + +/* Function to query if the joystick is currently attached + * It returns 1 if attached, 0 otherwise. + */ +extern SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick); /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, @@ -81,4 +103,15 @@ extern void SDL_SYS_JoystickClose(SDL_Joystick * joystick); /* Function to perform any system-specific joystick related cleanup */ extern void SDL_SYS_JoystickQuit(void); +/* Function to return the stable GUID for a plugged in device */ +extern SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index); + +/* Function to return the stable GUID for a opened joystick */ +extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick); + +#ifdef SDL_JOYSTICK_DINPUT +/* Function to get the current instance id of the joystick located at device_index */ +extern SDL_bool SDL_SYS_IsXInputDeviceIndex( int device_index ); +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/android/SDL_sysjoystick.c b/src/eepp/helper/SDL2/src/joystick/android/SDL_sysjoystick.c old mode 100755 new mode 100644 index fab2d1c37..78208c0b7 --- a/src/eepp/helper/SDL2/src/joystick/android/SDL_sysjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/android/SDL_sysjoystick.c @@ -43,21 +43,34 @@ static const char *accelerometerName = "Android accelerometer"; int SDL_SYS_JoystickInit(void) { - SDL_numjoysticks = 1; - return (1); } +int SDL_SYS_NumJoysticks() +{ + return 1; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; +} + /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - if (index == 0) { - return accelerometerName; - } else { - SDL_SetError("No joystick available with that index"); - return (NULL); - } + return accelerometerName; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; } /* Function to open a joystick for use. @@ -66,16 +79,25 @@ SDL_SYS_JoystickName(int index) It returns 0, or -1 if there is an error. */ int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { - joystick->nbuttons = 0; - joystick->nhats = 0; - joystick->nballs = 0; - joystick->naxes = 3; - joystick->name = accelerometerName; - return 0; + if (device_index == 0) { + joystick->nbuttons = 0; + joystick->nhats = 0; + joystick->nballs = 0; + joystick->naxes = 3; + return 0; + } else { + SDL_SetError("No joystick available with that index"); + return (-1); + } } +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; +} /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, @@ -109,6 +131,26 @@ SDL_SYS_JoystickQuit(void) { } -#endif /* SDL_JOYSTICK_NDS */ +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +#endif /* SDL_JOYSTICK_ANDROID */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/beos/SDL_bejoystick.cc b/src/eepp/helper/SDL2/src/joystick/beos/SDL_bejoystick.cc old mode 100755 new mode 100644 index cae0ae188..1fc35184e --- a/src/eepp/helper/SDL2/src/joystick/beos/SDL_bejoystick.cc +++ b/src/eepp/helper/SDL2/src/joystick/beos/SDL_bejoystick.cc @@ -50,6 +50,8 @@ extern "C" int16 *new_axes; }; + static int SDL_SYS_numjoysticks = 0; + /* 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. @@ -58,36 +60,55 @@ extern "C" int SDL_SYS_JoystickInit(void) { BJoystick joystick; - int numjoysticks; int i; int32 nports; char name[B_OS_NAME_LENGTH]; /* Search for attached joysticks */ nports = joystick.CountDevices(); - numjoysticks = 0; + SDL_SYS_numjoysticks = 0; SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport)); SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname)); - for (i = 0; (SDL_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i) + for (i = 0; (SDL_SYS_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i) { if (joystick.GetDeviceName(i, name) == B_OK) { if (joystick.Open(name) != B_ERROR) { BString stick_name; joystick.GetControllerName(&stick_name); - SDL_joyport[numjoysticks] = strdup(name); - SDL_joyname[numjoysticks] = strdup(stick_name.String()); - numjoysticks++; + SDL_joyport[SDL_SYS_numjoysticks] = strdup(name); + SDL_joyname[SDL_SYS_numjoysticks] = strdup(stick_name.String()); + SDL_SYS_numjoysticks++; joystick.Close(); } } } - return (numjoysticks); + return (SDL_SYS_numjoysticks); + } + + int SDL_SYS_NumJoysticks() + { + return SDL_SYS_numjoysticks; + } + + void SDL_SYS_JoystickDetect() + { + } + + SDL_bool SDL_SYS_JoystickNeedsPolling() + { + return SDL_FALSE; } /* Function to get the device-dependent name of a joystick */ - const char *SDL_SYS_JoystickName(int index) + const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - return SDL_joyname[index]; + return SDL_joyname[device_index]; + } + +/* Function to perform the mapping from device index to the instance id for this index */ + SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) + { + return device_index; } /* Function to open a joystick for use. @@ -95,11 +116,12 @@ extern "C" This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ - int SDL_SYS_JoystickOpen(SDL_Joystick * joystick) + int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { BJoystick *stick; /* Create the joystick data structure */ + joystick->instance_id = device_index; joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); if (joystick->hwdata == NULL) { @@ -111,7 +133,7 @@ extern "C" joystick->hwdata->stick = stick; /* Open the requested joystick for use */ - if (stick->Open(SDL_joyport[joystick->index]) == B_ERROR) { + if (stick->Open(SDL_joyport[device_index]) == B_ERROR) { SDL_SetError("Unable to open joystick"); SDL_SYS_JoystickClose(joystick); return (-1); @@ -139,6 +161,12 @@ extern "C" return (0); } +/* Function to determine is this joystick is attached to the system right now */ + SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) + { + return SDL_TRUE; + } + /* 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 @@ -233,6 +261,26 @@ extern "C" SDL_joyname[0] = NULL; } + SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) + { + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; + } + + SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) + { + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; + } + }; // extern "C" #endif /* SDL_JOYSTICK_BEOS */ diff --git a/src/eepp/helper/SDL2/src/joystick/bsd/SDL_sysjoystick.c b/src/eepp/helper/SDL2/src/joystick/bsd/SDL_sysjoystick.c old mode 100755 new mode 100644 index f46896c25..fc2e9c3db --- a/src/eepp/helper/SDL2/src/joystick/bsd/SDL_sysjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/bsd/SDL_sysjoystick.c @@ -76,7 +76,7 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" -#define MAX_UHID_JOYS 4 +#define MAX_UHID_JOYS 16 #define MAX_JOY_JOYS 2 #define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) @@ -157,13 +157,15 @@ static void report_free(struct report *); #define REP_BUF_DATA(rep) ((rep)->buf->data) #endif +static int SDL_SYS_numjoysticks = 0; + int SDL_SYS_JoystickInit(void) { char s[16]; int i, fd; - SDL_numjoysticks = 0; + SDL_SYS_numjoysticks = 0; SDL_memset(joynames, 0, sizeof(joynames)); SDL_memset(joydevnames, 0, sizeof(joydevnames)); @@ -173,22 +175,21 @@ SDL_SYS_JoystickInit(void) SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); - nj.index = SDL_numjoysticks; - joynames[nj.index] = strdup(s); + joynames[SDL_SYS_numjoysticks] = strdup(s); - if (SDL_SYS_JoystickOpen(&nj) == 0) { + if (SDL_SYS_JoystickOpen(&nj, SDL_SYS_numjoysticks) == 0) { SDL_SYS_JoystickClose(&nj); - SDL_numjoysticks++; + SDL_SYS_numjoysticks++; } else { - SDL_free(joynames[nj.index]); - joynames[nj.index] = NULL; + SDL_free(joynames[SDL_SYS_numjoysticks]); + joynames[SDL_SYS_numjoysticks] = NULL; } } for (i = 0; i < MAX_JOY_JOYS; i++) { SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); fd = open(s, O_RDONLY); if (fd != -1) { - joynames[SDL_numjoysticks++] = strdup(s); + joynames[SDL_SYS_numjoysticks++] = strdup(s); close(fd); } } @@ -196,16 +197,36 @@ SDL_SYS_JoystickInit(void) /* Read the default USB HID usage table. */ hid_init(NULL); - return (SDL_numjoysticks); + return (SDL_SYS_numjoysticks); +} + +int SDL_SYS_NumJoysticks() +{ + return SDL_SYS_numjoysticks; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; } const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - if (joydevnames[index] != NULL) { - return (joydevnames[index]); + if (joydevnames[device_index] != NULL) { + return (joydevnames[device_index]); } - return (joynames[index]); + return (joynames[device_index]); +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; } static int @@ -260,9 +281,9 @@ hatval_to_sdl(Sint32 hatval) int -SDL_SYS_JoystickOpen(SDL_Joystick * joy) +SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index) { - char *path = joynames[joy->index]; + char *path = joynames[device_index]; struct joystick_hwdata *hw; struct hid_item hitem; struct hid_data *hdata; @@ -276,6 +297,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy) return (-1); } + joy->instance_id = device_index; hw = (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata)); if (hw == NULL) { @@ -292,7 +314,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy) joy->nbuttons = 2; joy->nhats = 0; joy->nballs = 0; - joydevnames[joy->index] = strdup("Gameport joystick"); + joydevnames[device_index] = strdup("Gameport joystick"); goto usbend; } else { hw->type = BSDJOY_UHID; @@ -356,8 +378,8 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy) s = hid_usage_in_page(hitem.usage); sp = SDL_malloc(SDL_strlen(s) + 5); SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", - s, joy->index); - joydevnames[joy->index] = sp; + s, device_index); + joydevnames[device_index] = sp; } } break; @@ -402,6 +424,12 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy) return (-1); } +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; +} + void SDL_SYS_JoystickUpdate(SDL_Joystick * joy) { @@ -556,6 +584,26 @@ SDL_SYS_JoystickQuit(void) return; } +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + static int report_alloc(struct report *r, struct report_desc *rd, int repind) { @@ -612,4 +660,5 @@ report_free(struct report *r) } #endif /* SDL_JOYSTICK_USBHID */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick.c b/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick.c old mode 100755 new mode 100644 index ce7658407..abba9307d --- a/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick.c @@ -42,6 +42,7 @@ #include #include #include /* for NewPtrClear, DisposePtr */ +#include /* For force feedback testing. */ #include @@ -51,11 +52,21 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" #include "SDL_sysjoystick_c.h" +#include "SDL_events.h" +#if !SDL_EVENTS_DISABLED +#include "../../events/SDL_events_c.h" +#endif /* Linked list of all available devices */ static recDevice *gpDeviceList = NULL; +/* OSX reference to the notification object that tells us about device insertion/removal */ +IONotificationPortRef notificationPort = 0; +/* if 1 then a device was added since the last update call */ +static SDL_bool s_bDeviceAdded = SDL_FALSE; +/* static incrementing counter for new joystick devices seen on the system. Devices should start with index 0 */ +static int s_joystick_instance_id = -1; static void HIDReportErrorNum(char *strError, long numError) @@ -115,10 +126,20 @@ HIDRemovalCallback(void *target, IOReturn result, void *refcon, void *sender) { recDevice *device = (recDevice *) refcon; device->removed = 1; - device->uncentered = 1; } +/* Called by the io port notifier on removal of this device + */ +void JoystickDeviceWasRemovedCallback( void * refcon, io_service_t service, natural_t messageType, void * messageArgument ) +{ + if( messageType == kIOMessageServiceIsTerminated && refcon ) + { + recDevice *device = (recDevice *) refcon; + device->removed = 1; + } +} + /* Create and open an interface to device, required prior to extracting values or building queues. * Note: appliction now owns the device and must close and release it prior to exiting @@ -162,9 +183,33 @@ HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice) HIDReportErrorNum ("Failed to open pDevice->interface via open.", result); else + { + pDevice->portIterator = 0; + + // It's okay if this fails, we have another detection method below (*(pDevice->interface))->setRemovalCallback(pDevice->interface, HIDRemovalCallback, pDevice, pDevice); + + /* now connect notification for new devices */ + pDevice->notificationPort = IONotificationPortCreate(kIOMasterPortDefault); + + CFRunLoopAddSource(CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(pDevice->notificationPort), + kCFRunLoopDefaultMode); + + // Register for notifications when a serial port is added to the system + result = IOServiceAddInterestNotification(pDevice->notificationPort, + hidDevice, + kIOGeneralInterest, + JoystickDeviceWasRemovedCallback, + pDevice, + &pDevice->portIterator); + if (kIOReturnSuccess != result) { + HIDReportErrorNum + ("Failed to register for removal callback.", result); + } + } } return result; @@ -195,6 +240,12 @@ HIDCloseReleaseInterface(recDevice * pDevice) HIDReportErrorNum("Failed to release IOHIDDeviceInterface.", result); pDevice->interface = NULL; + + if ( pDevice->portIterator ) + { + IOObjectRelease( pDevice->portIterator ); + pDevice->portIterator = 0; + } } return result; } @@ -461,6 +512,26 @@ HIDGetDeviceInfo(io_object_t hidDevice, CFMutableDictionaryRef hidProperties, ("CFNumberGetValue error retrieving pDevice->usage."); } + refCF = + CFDictionaryGetValue(hidProperties, + CFSTR(kIOHIDVendorIDKey)); + if (refCF) { + if (!CFNumberGetValue + (refCF, kCFNumberLongType, &pDevice->guid.data[0])) + SDL_SetError + ("CFNumberGetValue error retrieving pDevice->guid."); + } + refCF = + CFDictionaryGetValue(hidProperties, + CFSTR(kIOHIDProductIDKey)); + if (refCF) { + if (!CFNumberGetValue + (refCF, kCFNumberLongType, &pDevice->guid.data[8])) + SDL_SetError + ("CFNumberGetValue error retrieving pDevice->guid[8]."); + } + + if (NULL == refCF) { /* get top level element HID usage page or usage */ /* use top level element instead */ CFTypeRef refCFTopElement = 0; @@ -505,6 +576,7 @@ HIDBuildDevice(io_object_t hidDevice) if (kIOReturnSuccess == result) { HIDGetDeviceInfo(hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */ HIDGetCollectionElements(hidProperties, pDevice); + pDevice->instance_id = ++s_joystick_instance_id; } else { DisposePtr((Ptr) pDevice); pDevice = NULL; @@ -569,6 +641,79 @@ HIDDisposeDevice(recDevice ** ppDevice) } +/* Given an io_object_t from OSX adds a joystick device to our list if appropriate + */ +int +AddDeviceHelper( io_object_t ioHIDDeviceObject ) +{ + recDevice *device; + + /* build a device record */ + device = HIDBuildDevice(ioHIDDeviceObject); + if (!device) + return 0; + + /* Filter device list to non-keyboard/mouse stuff */ + if ((device->usagePage != kHIDPage_GenericDesktop) || + ((device->usage != kHIDUsage_GD_Joystick && + device->usage != kHIDUsage_GD_GamePad && + device->usage != kHIDUsage_GD_MultiAxisController))) { + + /* release memory for the device */ + HIDDisposeDevice(&device); + DisposePtr((Ptr) device); + return 0; + } + + /* We have to do some storage of the io_service_t for + * SDL_HapticOpenFromJoystick */ + if (FFIsForceFeedback(ioHIDDeviceObject) == FF_OK) { + device->ffservice = ioHIDDeviceObject; + } else { + device->ffservice = 0; + } + + device->send_open_event = 1; + s_bDeviceAdded = SDL_TRUE; + + /* Add device to the end of the list */ + if ( !gpDeviceList ) + { + gpDeviceList = device; + } + else + { + recDevice *curdevice; + + curdevice = gpDeviceList; + while ( curdevice->pNext ) + { + curdevice = curdevice->pNext; + } + curdevice->pNext = device; + } + + return 1; +} + + +/* Called by our IO port notifier on the master port when a HID device is inserted, we iterate + * and check for new joysticks + */ +void JoystickDeviceWasAddedCallback( void *refcon, io_iterator_t iterator ) +{ + io_object_t ioHIDDeviceObject = 0; + + while ( ( ioHIDDeviceObject = IOIteratorNext(iterator) ) ) + { + if ( ioHIDDeviceObject ) + { + AddDeviceHelper( ioHIDDeviceObject ); + } + } +} + + /* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 @@ -581,10 +726,8 @@ SDL_SYS_JoystickInit(void) mach_port_t masterPort = 0; io_iterator_t hidObjectIterator = 0; CFMutableDictionaryRef hidMatchDictionary = NULL; - recDevice *device, *lastDevice; io_object_t ioHIDDeviceObject = 0; - - SDL_numjoysticks = 0; + io_iterator_t portIterator = 0; if (gpDeviceList) { SDL_SetError("Joystick: Device list already inited."); @@ -629,70 +772,120 @@ SDL_SYS_JoystickInit(void) } if (!hidObjectIterator) { /* there are no joysticks */ gpDeviceList = NULL; - SDL_numjoysticks = 0; return 0; } /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ /* build flat linked list of devices from device iterator */ - gpDeviceList = lastDevice = NULL; + gpDeviceList = NULL; while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) { - /* build a device record */ - device = HIDBuildDevice(ioHIDDeviceObject); - if (!device) - continue; - - /* Filter device list to non-keyboard/mouse stuff */ - if ((device->usagePage != kHIDPage_GenericDesktop) || - ((device->usage != kHIDUsage_GD_Joystick && - device->usage != kHIDUsage_GD_GamePad && - device->usage != kHIDUsage_GD_MultiAxisController))) { - - /* release memory for the device */ - HIDDisposeDevice(&device); - DisposePtr((Ptr) device); - continue; - } - - /* We have to do some storage of the io_service_t for - * SDL_HapticOpenFromJoystick */ - if (FFIsForceFeedback(ioHIDDeviceObject) == FF_OK) { - device->ffservice = ioHIDDeviceObject; - } else { - device->ffservice = 0; - } - - /* Add device to the end of the list */ - if (lastDevice) - lastDevice->pNext = device; - else - gpDeviceList = device; - lastDevice = device; + AddDeviceHelper( ioHIDDeviceObject ); } result = IOObjectRelease(hidObjectIterator); /* release the iterator */ + + /* now connect notification for new devices */ + notificationPort = IONotificationPortCreate(masterPort); + hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); - /* Count the total number of devices we found */ - device = gpDeviceList; - while (device) { - SDL_numjoysticks++; + CFRunLoopAddSource(CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(notificationPort), + kCFRunLoopDefaultMode); + + // Register for notifications when a serial port is added to the system + result = IOServiceAddMatchingNotification(notificationPort, + kIOFirstMatchNotification, + hidMatchDictionary, + JoystickDeviceWasAddedCallback, + NULL, + &portIterator); + while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). + + return SDL_SYS_NumJoysticks(); +} + +/* Function to return the number of joystick devices plugged in right now */ +int +SDL_SYS_NumJoysticks() +{ + recDevice *device = gpDeviceList; + int nJoySticks = 0; + + while ( device ) + { + nJoySticks++; device = device->pNext; - } + } - return SDL_numjoysticks; + return nJoySticks; +} + +/* Function to cause any queued joystick insertions to be processed + */ +void +SDL_SYS_JoystickDetect() +{ + if ( s_bDeviceAdded ) + { + recDevice *device = gpDeviceList; + s_bDeviceAdded = SDL_FALSE; + int device_index = 0; + // send notifications + while ( device ) + { + if ( device->send_open_event ) + { + device->send_open_event = 0; +#if !SDL_EVENTS_DISABLED + SDL_Event event; + event.type = SDL_JOYDEVICEADDED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_index; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + } + device_index++; + device = device->pNext; + } + } +} + +SDL_bool +SDL_SYS_JoystickNeedsPolling() +{ + return s_bDeviceAdded; } /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { recDevice *device = gpDeviceList; - for (; index > 0; index--) + for (; device_index > 0; device_index--) device = device->pNext; - return device->product; + return device->product; +} + +/* Function to return the instance id of the joystick at device_index + */ +SDL_JoystickID +SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + recDevice *device = gpDeviceList; + int index; + + for (index = device_index; index > 0; index--) + device = device->pNext; + + return device->instance_id; } /* Function to open a joystick for use. @@ -701,25 +894,44 @@ SDL_SYS_JoystickName(int index) * It returns 0, or -1 if there is an error. */ int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { recDevice *device = gpDeviceList; int index; - for (index = joystick->index; index > 0; index--) + for (index = device_index; index > 0; index--) device = device->pNext; + joystick->instance_id = device->instance_id; joystick->hwdata = device; - joystick->name = device->product; - - joystick->naxes = device->axes; - joystick->nhats = device->hats; - joystick->nballs = 0; - joystick->nbuttons = device->buttons; + joystick->name = device->product; + joystick->naxes = device->axes; + joystick->nhats = device->hats; + joystick->nballs = 0; + joystick->nbuttons = device->buttons; return 0; } +/* Function to query if the joystick is currently attached + * It returns 1 if attached, 0 otherwise. + */ +SDL_bool +SDL_SYS_JoystickAttached(SDL_Joystick * joystick) +{ + recDevice *device = gpDeviceList; + + while ( device ) + { + if ( joystick->instance_id == device->instance_id ) + return SDL_TRUE; + + device = device->pNext; + } + + return SDL_FALSE; +} + /* 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 @@ -728,26 +940,49 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { - recDevice *device = joystick->hwdata; + recDevice *device = joystick->hwdata; recElement *element; SInt32 value, range; int i; + if ( !device ) + return; + if (device->removed) { /* device was unplugged; ignore it. */ - if (device->uncentered) { - device->uncentered = 0; - - /* Tell the app that everything is centered/unpressed... */ - for (i = 0; i < device->axes; i++) - SDL_PrivateJoystickAxis(joystick, i, 0); - - for (i = 0; i < device->buttons; i++) - SDL_PrivateJoystickButton(joystick, i, 0); - - for (i = 0; i < device->hats; i++) - SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); - } + recDevice *devicelist = gpDeviceList; + joystick->closed = 1; + joystick->uncentered = 1; + + if ( devicelist == device ) + { + gpDeviceList = device->pNext; + } + else + { + while ( devicelist->pNext != device ) + { + devicelist = devicelist->pNext; + } + + devicelist->pNext = device->pNext; + } + + DisposePtr((Ptr) device); + joystick->hwdata = NULL; +#if !SDL_EVENTS_DISABLED + SDL_Event event; + event.type = SDL_JOYDEVICEREMOVED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = joystick->instance_id; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return; } @@ -829,9 +1064,8 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) /* Function to close a joystick after use */ void SDL_SYS_JoystickClose(SDL_Joystick * joystick) -{ - /* Should we do anything here? */ - return; +{ + joystick->closed = 1; } /* Function to perform any system-specific joystick related cleanup */ @@ -840,6 +1074,29 @@ SDL_SYS_JoystickQuit(void) { while (NULL != gpDeviceList) gpDeviceList = HIDDisposeDevice(&gpDeviceList); + + if ( notificationPort ) + { + IONotificationPortDestroy( notificationPort ); + notificationPort = 0; + } +} + + +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + recDevice *device = gpDeviceList; + int index; + + for (index = device_index; index > 0; index--) + device = device->pNext; + + return device->guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick) +{ + return joystick->hwdata->guid; } #endif /* SDL_JOYSTICK_IOKIT */ diff --git a/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick_c.h b/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick_c.h old mode 100755 new mode 100644 index 65dd814bf..897779674 --- a/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick_c.h +++ b/src/eepp/helper/SDL2/src/joystick/darwin/SDL_sysjoystick_c.h @@ -25,6 +25,7 @@ #include #include +#include struct recElement @@ -58,7 +59,9 @@ struct joystick_hwdata { io_service_t ffservice; /* Interface for force feedback, 0 = no ff */ IOHIDDeviceInterface **interface; /* interface to device, NULL = no interface */ - + IONotificationPortRef notificationPort; /* port to be notified on joystick removal */ + io_iterator_t portIterator; /* iterator for removal callback */ + char product[256]; /* name of product */ long usage; /* usage page from IOUSBHID Parser.h which defines general usage */ long usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */ @@ -74,6 +77,10 @@ struct joystick_hwdata int removed; int uncentered; + + int instance_id; + SDL_JoystickGUID guid; + Uint8 send_open_event; /* 1 if we need to send an Added event for this device */ struct joystick_hwdata *pNext; /* next device */ }; diff --git a/src/eepp/helper/SDL2/src/joystick/dummy/SDL_sysjoystick.c b/src/eepp/helper/SDL2/src/joystick/dummy/SDL_sysjoystick.c old mode 100755 new mode 100644 index 02bd5d751..1bcf1ce93 --- a/src/eepp/helper/SDL2/src/joystick/dummy/SDL_sysjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/dummy/SDL_sysjoystick.c @@ -29,37 +29,60 @@ #include "../SDL_joystick_c.h" /* 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) { - SDL_numjoysticks = 0; return (0); } +int SDL_SYS_NumJoysticks() +{ + return 0; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; +} + /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { SDL_SetError("Logic error: No joysticks available"); return (NULL); } +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; +} + /* 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) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { SDL_SetError("Logic error: No joysticks available"); return (-1); } +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; +} + /* 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 @@ -85,6 +108,27 @@ SDL_SYS_JoystickQuit(void) return; } +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + #endif /* SDL_JOYSTICK_DUMMY || SDL_JOYSTICK_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/iphoneos/SDLUIAccelerationDelegate.h b/src/eepp/helper/SDL2/src/joystick/iphoneos/SDLUIAccelerationDelegate.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/joystick/iphoneos/SDLUIAccelerationDelegate.m b/src/eepp/helper/SDL2/src/joystick/iphoneos/SDLUIAccelerationDelegate.m old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/joystick/iphoneos/SDL_sysjoystick.m b/src/eepp/helper/SDL2/src/joystick/iphoneos/SDL_sysjoystick.m old mode 100755 new mode 100644 index 9b3d29944..291e96a1d --- a/src/eepp/helper/SDL2/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/src/eepp/helper/SDL2/src/joystick/iphoneos/SDL_sysjoystick.m @@ -37,21 +37,34 @@ const char *accelerometerName = "iPhone accelerometer"; int SDL_SYS_JoystickInit(void) { - SDL_numjoysticks = 1; return (1); } +int SDL_SYS_NumJoysticks() +{ + return 1; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; +} + /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - switch(index) { - case 0: - return accelerometerName; - default: - SDL_SetError("No joystick available with that index"); - return NULL; - } + return accelerometerName; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; } /* Function to open a joystick for use. @@ -60,22 +73,20 @@ SDL_SYS_JoystickName(int index) It returns 0, or -1 if there is an error. */ int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { - if (joystick->index == 0) { - joystick->naxes = 3; - joystick->nhats = 0; - joystick->nballs = 0; - joystick->nbuttons = 0; - joystick->name = accelerometerName; - [[SDLUIAccelerationDelegate sharedDelegate] startup]; - return 0; - } - else { - SDL_SetError("No joystick available with that index"); - return (-1); - } - + joystick->naxes = 3; + joystick->nhats = 0; + joystick->nballs = 0; + joystick->nbuttons = 0; + [[SDLUIAccelerationDelegate sharedDelegate] startup]; + return 0; +} + +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; } /* Function to update the state of a joystick - called as a device poll. @@ -107,7 +118,7 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { - if (joystick->index == 0 && [[SDLUIAccelerationDelegate sharedDelegate] isRunning]) { + if ([[SDLUIAccelerationDelegate sharedDelegate] isRunning]) { [[SDLUIAccelerationDelegate sharedDelegate] shutdown]; } SDL_SetError("No joystick open with that index"); @@ -121,4 +132,25 @@ SDL_SYS_JoystickQuit(void) { return; } + +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick.c b/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick.c old mode 100755 new mode 100644 index 934ca0549..b09cbe95a --- a/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick.c @@ -22,6 +22,10 @@ #ifdef SDL_JOYSTICK_LINUX +#ifndef SDL_INPUT_LINUXEV +#error SDL now requires a Linux 2.4+ kernel with /dev/input/event support. +#endif + /* This is the system specific header for the SDL joystick API */ #include @@ -31,349 +35,168 @@ #include /* For the definition of PATH_MAX */ #include +#include "SDL_assert.h" #include "SDL_joystick.h" +#include "SDL_endian.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" #include "SDL_sysjoystick_c.h" -/* Special joystick configurations */ -static struct -{ - const char *name; - int naxes; - int nhats; - int nballs; -} special_joysticks[] = { - { - "MadCatz Panther XL", 3, 2, 1}, /* We don't handle rudder (axis 8) */ - { - "SideWinder Precision Pro", 4, 1, 0}, { - "SideWinder 3D Pro", 4, 1, 0}, { - "Microsoft SideWinder 3D Pro", 4, 1, 0}, { - "Microsoft SideWinder Precision Pro", 4, 1, 0}, { - "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0}, { - "WingMan Interceptor", 3, 3, 0}, { - "WingMan Extreme Digital 3D", 4, 1, 0}, { - "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0}, { - "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0}, { - "Saitek Saitek X45", 6, 1, 0} -}; - -/* It looks like newer kernels have the logical mapping at the driver level */ -#define NO_LOGICAL_JOYSTICKS - -#ifndef NO_LOGICAL_JOYSTICKS +/* !!! FIXME: move this somewhere else. */ +#if !SDL_EVENTS_DISABLED +#include "../../events/SDL_events_c.h" +#endif /* - Some USB HIDs show up as a single joystick even though they actually - control 2 or more joysticks. -*/ -/* - This code handles the MP-8800 (Quad) and MP-8866 (Dual), which can - be identified by their transparent blue design. It's quite trivial - to add other joysticks with similar quirky behavior. - -id -*/ - -struct joystick_logical_mapping -{ - int njoy; - int nthing; -}; - -/* - {logical joy, logical axis}, - {logical joy, logical hat}, - {logical joy, logical ball}, - {logical joy, logical button} -*/ - -static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = { - {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5} -}; - -static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = { - {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, - {0, 9}, {0, 10}, {0, 11} -}; - -static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = { - {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {0, 3}, - {1, 2}, {1, 3}, {0, 4}, {0, 5}, {1, 4}, {1, 5} -}; - -static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = { - {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, - {0, 9}, {0, 10}, {0, 11}, - {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, - {1, 9}, {1, 10}, {1, 11} -}; - -static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = { - {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {0, 3}, - {1, 2}, {1, 3}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, - {0, 4}, {0, 5}, {1, 4}, {1, 5}, {2, 4}, {2, 5} -}; - -static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = { - {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, - {0, 9}, {0, 10}, {0, 11}, - {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, - {1, 9}, {1, 10}, {1, 11}, - {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, - {2, 9}, {2, 10}, {2, 11} -}; - -static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = { - {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {0, 3}, - {1, 2}, {1, 3}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, - {3, 0}, {3, 1}, {3, 2}, {3, 3}, {0, 4}, {0, 5}, - {1, 4}, {1, 5}, {2, 4}, {2, 5}, {3, 4}, {3, 5} -}; - -static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = { - {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, - {0, 9}, {0, 10}, {0, 11}, - {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, - {1, 9}, {1, 10}, {1, 11}, - {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, - {2, 9}, {2, 10}, {2, 11}, - {3, 0}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, - {3, 9}, {3, 10}, {3, 11} -}; - -struct joystick_logical_layout -{ - int naxes; - int nhats; - int nballs; - int nbuttons; -}; - -static struct joystick_logical_layout mp88xx_1_logical_layout[] = { - {6, 0, 0, 12} -}; - -static struct joystick_logical_layout mp88xx_2_logical_layout[] = { - {6, 0, 0, 12}, - {6, 0, 0, 12} -}; - -static struct joystick_logical_layout mp88xx_3_logical_layout[] = { - {6, 0, 0, 12}, - {6, 0, 0, 12}, - {6, 0, 0, 12} -}; - -static struct joystick_logical_layout mp88xx_4_logical_layout[] = { - {6, 0, 0, 12}, - {6, 0, 0, 12}, - {6, 0, 0, 12}, - {6, 0, 0, 12} -}; - -/* - This array sets up a means of mapping a single physical joystick to - multiple logical joysticks. (djm) - - njoys - the number of logical joysticks - - layouts - an array of layout structures, one to describe each logical joystick - - axes, hats, balls, buttons - arrays that map a physical thingy to a logical thingy + * !!! FIXME: move all the udev stuff to src/core/linux, so I can reuse it + * !!! FIXME: for audio hardware disconnects. */ -struct joystick_logicalmap +#ifdef HAVE_LIBUDEV_H +#define SDL_USE_LIBUDEV 1 +#include "SDL_loadso.h" +#include +#include +#include +#include + +/* we never link directly to libudev. */ +/* !!! FIXME: can we generalize this? ALSA, etc, do the same things. */ +static const char *udev_library = "libudev.so"; +static void *udev_handle = NULL; + +/* !!! FIXME: this is kinda ugly. */ +static SDL_bool +load_udev_sym(const char *fn, void **addr) { - const char *name; - int nbuttons; - int njoys; - struct joystick_logical_layout *layout; - struct joystick_logical_mapping *axismap; - struct joystick_logical_mapping *hatmap; - struct joystick_logical_mapping *ballmap; - struct joystick_logical_mapping *buttonmap; -}; - -static struct joystick_logicalmap joystick_logicalmap[] = { - { - "WiseGroup.,Ltd MP-8866 Dual USB Joypad", - 12, - 1, - mp88xx_1_logical_layout, - mp88xx_1_logical_axismap, - NULL, - NULL, - mp88xx_1_logical_buttonmap}, - { - "WiseGroup.,Ltd MP-8866 Dual USB Joypad", - 24, - 2, - mp88xx_2_logical_layout, - mp88xx_2_logical_axismap, - NULL, - NULL, - mp88xx_2_logical_buttonmap}, - { - "WiseGroup.,Ltd MP-8800 Quad USB Joypad", - 12, - 1, - mp88xx_1_logical_layout, - mp88xx_1_logical_axismap, - NULL, - NULL, - mp88xx_1_logical_buttonmap}, - { - "WiseGroup.,Ltd MP-8800 Quad USB Joypad", - 24, - 2, - mp88xx_2_logical_layout, - mp88xx_2_logical_axismap, - NULL, - NULL, - mp88xx_2_logical_buttonmap}, - { - "WiseGroup.,Ltd MP-8800 Quad USB Joypad", - 36, - 3, - mp88xx_3_logical_layout, - mp88xx_3_logical_axismap, - NULL, - NULL, - mp88xx_3_logical_buttonmap}, - { - "WiseGroup.,Ltd MP-8800 Quad USB Joypad", - 48, - 4, - mp88xx_4_logical_layout, - mp88xx_4_logical_axismap, - NULL, - NULL, - mp88xx_4_logical_buttonmap} -}; - -/* find the head of a linked list, given a point in it - */ -#define SDL_joylist_head(i, start)\ - for(i = start; SDL_joylist[i].fname == NULL;) i = SDL_joylist[i].prev; - -#define SDL_logical_joydecl(d) d - - -#else - -#define SDL_logical_joydecl(d) - -#endif /* USE_LOGICAL_JOYSTICKS */ - -/* The maximum number of joysticks we'll detect */ -#define MAX_JOYSTICKS 32 - -/* A list of available joysticks */ -static struct -{ - char *fname; -#ifndef NO_LOGICAL_JOYSTICKS - SDL_Joystick *joy; - struct joystick_logicalmap *map; - int prev; - int next; - int logicalno; -#endif /* USE_LOGICAL_JOYSTICKS */ -} SDL_joylist[MAX_JOYSTICKS]; - - -#ifndef NO_LOGICAL_JOYSTICKS - -static int -CountLogicalJoysticks(int max) -{ - register int i, j, k, ret, prev; - const char *name; - int nbuttons, fd; - unsigned char n; - - ret = 0; - - for (i = 0; i < max; i++) { - name = SDL_SYS_JoystickName(i); - - fd = open(SDL_joylist[i].fname, O_RDONLY, 0); - if (fd >= 0) { - if (ioctl(fd, JSIOCGBUTTONS, &n) < 0) { - nbuttons = -1; - } else { - nbuttons = n; - } - close(fd); - } else { - nbuttons = -1; - } - - if (name) { - for (j = 0; j < SDL_arraysize(joystick_logicalmap); j++) { - if (!SDL_strcmp(name, joystick_logicalmap[j].name) - && (nbuttons == -1 - || nbuttons == joystick_logicalmap[j].nbuttons)) { - prev = i; - SDL_joylist[prev].map = &(joystick_logicalmap[j]); - - for (k = 1; k < joystick_logicalmap[j].njoys; k++) { - SDL_joylist[prev].next = max + ret; - SDL_joylist[max + ret].prev = prev; - - prev = max + ret; - SDL_joylist[prev].logicalno = k; - SDL_joylist[prev].map = &(joystick_logicalmap[j]); - ret++; - } - - break; - } - } - } + *addr = SDL_LoadFunction(udev_handle, fn); + if (*addr == NULL) { + /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ + return SDL_FALSE; } - return ret; + return SDL_TRUE; +} + +/* libudev entry points... */ +static const char *(*UDEV_udev_device_get_action)(struct udev_device *) = NULL; +static const char *(*UDEV_udev_device_get_devnode)(struct udev_device *) = NULL; +static const char *(*UDEV_udev_device_get_property_value)(struct udev_device *, const char *) = NULL; +static struct udev_device *(*UDEV_udev_device_new_from_syspath)(struct udev *, const char *) = NULL; +static void (*UDEV_udev_device_unref)(struct udev_device *) = NULL; +static int (*UDEV_udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *) = NULL; +static int (*UDEV_udev_enumerate_add_match_subsystem)(struct udev_enumerate *, const char *) = NULL; +static struct udev_list_entry *(*UDEV_udev_enumerate_get_list_entry)(struct udev_enumerate *) = NULL; +static struct udev_enumerate *(*UDEV_udev_enumerate_new)(struct udev *) = NULL; +static int (*UDEV_udev_enumerate_scan_devices)(struct udev_enumerate *) = NULL; +static void (*UDEV_udev_enumerate_unref)(struct udev_enumerate *) = NULL; +static const char *(*UDEV_udev_list_entry_get_name)(struct udev_list_entry *) = NULL; +static struct udev_list_entry *(*UDEV_udev_list_entry_get_next)(struct udev_list_entry *) = NULL; +static int (*UDEV_udev_monitor_enable_receiving)(struct udev_monitor *) = NULL; +static int (*UDEV_udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor *, const char *, const char *) = NULL; +static int (*UDEV_udev_monitor_get_fd)(struct udev_monitor *) = NULL; +static struct udev_monitor *(*UDEV_udev_monitor_new_from_netlink)(struct udev *, const char *) = NULL; +static struct udev_device *(*UDEV_udev_monitor_receive_device)(struct udev_monitor *) = NULL; +static void (*UDEV_udev_monitor_unref)(struct udev_monitor *) = NULL; +static struct udev *(*UDEV_udev_new)(void) = NULL; +static void (*UDEV_udev_unref)(struct udev *) = NULL; + +static int +load_udev_syms(void) +{ + /* cast funcs to char* first, to please GCC's strict aliasing rules. */ + #define SDL_UDEV_SYM(x) \ + if (!load_udev_sym(#x, (void **) (char *) &UDEV_##x)) return -1 + + SDL_UDEV_SYM(udev_device_get_action); + SDL_UDEV_SYM(udev_device_get_devnode); + SDL_UDEV_SYM(udev_device_get_property_value); + SDL_UDEV_SYM(udev_device_new_from_syspath); + SDL_UDEV_SYM(udev_device_unref); + SDL_UDEV_SYM(udev_enumerate_add_match_property); + SDL_UDEV_SYM(udev_enumerate_add_match_subsystem); + SDL_UDEV_SYM(udev_enumerate_get_list_entry); + SDL_UDEV_SYM(udev_enumerate_new); + SDL_UDEV_SYM(udev_enumerate_scan_devices); + SDL_UDEV_SYM(udev_enumerate_unref); + SDL_UDEV_SYM(udev_list_entry_get_name); + SDL_UDEV_SYM(udev_list_entry_get_next); + SDL_UDEV_SYM(udev_monitor_enable_receiving); + SDL_UDEV_SYM(udev_monitor_filter_add_match_subsystem_devtype); + SDL_UDEV_SYM(udev_monitor_get_fd); + SDL_UDEV_SYM(udev_monitor_new_from_netlink); + SDL_UDEV_SYM(udev_monitor_receive_device); + SDL_UDEV_SYM(udev_monitor_unref); + SDL_UDEV_SYM(udev_new); + SDL_UDEV_SYM(udev_unref); + + #undef SDL_UDEV_SYM + + return 0; } static void -LogicalSuffix(int logicalno, char *namebuf, int len) +UnloadUDEVLibrary(void) { - register int slen; - const static char suffixs[] = - "01020304050607080910111213141516171819" "20212223242526272829303132"; - const char *suffix; - slen = SDL_strlen(namebuf); - suffix = NULL; - - if (logicalno * 2 < sizeof(suffixs)) - suffix = suffixs + (logicalno * 2); - - if (slen + 4 < len && suffix) { - namebuf[slen++] = ' '; - namebuf[slen++] = '#'; - namebuf[slen++] = suffix[0]; - namebuf[slen++] = suffix[1]; - namebuf[slen++] = 0; + if (udev_handle != NULL) { + SDL_UnloadObject(udev_handle); + udev_handle = NULL; } } -#endif /* USE_LOGICAL_JOYSTICKS */ +static int +LoadUDEVLibrary(void) +{ + int retval = 0; + if (udev_handle == NULL) { + udev_handle = SDL_LoadObject(udev_library); + if (udev_handle == NULL) { + retval = -1; + /* Don't call SDL_SetError(): SDL_LoadObject already did. */ + } else { + retval = load_udev_syms(); + if (retval < 0) { + UnloadUDEVLibrary(); + } + } + } + + return retval; +} + +static struct udev *udev = NULL; +static struct udev_monitor *udev_mon = NULL; +#endif + + +/* A linked list of available joysticks */ +typedef struct SDL_joylist_item +{ + int device_instance; + char *path; /* "/dev/input/event2" or whatever */ + char *name; /* "SideWinder 3D Pro" or whatever */ + SDL_JoystickGUID guid; + dev_t devnum; + struct joystick_hwdata *hwdata; + struct SDL_joylist_item *next; +} SDL_joylist_item; + +static SDL_joylist_item *SDL_joylist = NULL; +static SDL_joylist_item *SDL_joylist_tail = NULL; +static int numjoysticks = 0; +static int instance_counter = 0; -#if SDL_INPUT_LINUXEV #define test_bit(nr, addr) \ - (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0) + (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0) #define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1) static int -EV_IsJoystick(int fd) +IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *guid) { unsigned long evbit[NBITS(EV_MAX)] = { 0 }; unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + struct input_id inpid; + Uint16 *guid16 = (Uint16 *) ((char *) &guid->data); if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || @@ -385,33 +208,208 @@ EV_IsJoystick(int fd) test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit))) { return 0; } - return (1); + + if (ioctl(fd, EVIOCGNAME(namebuflen), namebuf) < 0) { + return 0; + } + + if (ioctl(fd, EVIOCGID, &inpid) < 0) { + return 0; + } + + /* We only need 16 bits for each of these; space them out to fill 128. */ + /* Byteswap so devices get same GUID on little/big endian platforms. */ + *(guid16++) = SDL_SwapLE16(inpid.bustype); + *(guid16++) = 0; + *(guid16++) = SDL_SwapLE16(inpid.vendor); + *(guid16++) = 0; + *(guid16++) = SDL_SwapLE16(inpid.product); + *(guid16++) = 0; + *(guid16++) = SDL_SwapLE16(inpid.version); + *(guid16++) = 0; + + return 1; } -#endif /* SDL_INPUT_LINUXEV */ -/* Function to scan the system for joysticks */ +/* !!! FIXME: I would love to dump this code and use libudev instead. */ +static int +MaybeAddDevice(const char *path) +{ + struct stat sb; + int fd = -1; + int isstick = 0; + char namebuf[128]; + SDL_JoystickGUID guid; + SDL_joylist_item *item; + + if (path == NULL) { + return -1; + } + + if (stat(path, &sb) == -1) { + return -1; + } + + /* Check to make sure it's not already in list. */ + for (item = SDL_joylist; item != NULL; item = item->next) { + if (sb.st_rdev == item->devnum) { + return -1; /* already have this one */ + } + } + + fd = open(path, O_RDONLY, 0); + if (fd < 0) { + return -1; + } + +#ifdef DEBUG_INPUT_EVENTS + printf("Checking %s\n", path); +#endif + + isstick = IsJoystick(fd, namebuf, sizeof (namebuf), &guid); + close(fd); + if (!isstick) { + return -1; + } + + item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item)); + if (item == NULL) { + return -1; + } + + SDL_zerop(item); + item->devnum = sb.st_rdev; + item->path = SDL_strdup(path); + item->name = SDL_strdup(namebuf); + item->guid = guid; + + if ( (item->path == NULL) || (item->name == NULL) ) { + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); + return -1; + } + + item->device_instance = instance_counter++; + if (SDL_joylist_tail == NULL) { + SDL_joylist = SDL_joylist_tail = item; + } else { + SDL_joylist_tail->next = item; + SDL_joylist_tail = item; + } + + return numjoysticks++; +} + +#if SDL_USE_LIBUDEV +/* !!! FIXME: I would love to dump this code and use libudev instead. */ +static int +MaybeRemoveDevice(const char *path) +{ + SDL_joylist_item *item; + SDL_joylist_item *prev = NULL; + + if (path == NULL) { + return -1; + } + + for (item = SDL_joylist; item != NULL; item = item->next) { + /* found it, remove it. */ + if (SDL_strcmp(path, item->path) == 0) { + const int retval = item->device_instance; + if (item->hwdata) { + item->hwdata->removed = SDL_TRUE; + } + if (prev != NULL) { + prev->next = item->next; + if (item == SDL_joylist_tail) { + SDL_joylist_tail = prev; + } + } else { + SDL_assert(!SDL_joylist); + SDL_assert(!SDL_joylist_tail); + SDL_joylist = SDL_joylist_tail = NULL; + } + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); + numjoysticks--; + return retval; + } + prev = item; + } + + return -1; +} +#endif + +static int +JoystickInitWithoutUdev(void) +{ + int i; + char path[PATH_MAX]; + + /* !!! FIXME: only finds sticks if they're called /dev/input/event[0..31] */ + /* !!! FIXME: we could at least readdir() through /dev/input...? */ + /* !!! FIXME: (or delete this and rely on libudev?) */ + for (i = 0; i < 32; i++) { + SDL_snprintf(path, SDL_arraysize(path), "/dev/input/event%d", i); + MaybeAddDevice(path); + } + + return numjoysticks; +} + + +#if SDL_USE_LIBUDEV +static int +JoystickInitWithUdev(void) +{ + struct udev_enumerate *enumerate = NULL; + struct udev_list_entry *devs = NULL; + struct udev_list_entry *item = NULL; + + SDL_assert(udev == NULL); + udev = UDEV_udev_new(); + if (udev == NULL) { + SDL_SetError("udev_new() failed"); + return -1; + } + + udev_mon = UDEV_udev_monitor_new_from_netlink(udev, "udev"); + if (udev_mon != NULL) { /* okay if it's NULL, we just lose hotplugging. */ + UDEV_udev_monitor_filter_add_match_subsystem_devtype(udev_mon, + "input", NULL); + UDEV_udev_monitor_enable_receiving(udev_mon); + } + + enumerate = UDEV_udev_enumerate_new(udev); + if (enumerate == NULL) { + SDL_SetError("udev_enumerate_new() failed"); + return -1; + } + + UDEV_udev_enumerate_add_match_subsystem(enumerate, "input"); + UDEV_udev_enumerate_add_match_property(enumerate, "ID_INPUT_JOYSTICK", "1"); + UDEV_udev_enumerate_scan_devices(enumerate); + devs = UDEV_udev_enumerate_get_list_entry(enumerate); + for (item = devs; item; item = UDEV_udev_list_entry_get_next(item)) { + const char *path = UDEV_udev_list_entry_get_name(item); + struct udev_device *dev = UDEV_udev_device_new_from_syspath(udev, path); + MaybeAddDevice(UDEV_udev_device_get_devnode(dev)); + UDEV_udev_device_unref(dev); + } + + UDEV_udev_enumerate_unref(enumerate); + + return numjoysticks; +} +#endif + int SDL_SYS_JoystickInit(void) { - /* The base path of the joystick devices */ - const char *joydev_pattern[] = { -#if SDL_INPUT_LINUXEV - "/dev/input/event%d", -#endif - "/dev/input/js%d", - "/dev/js%d" - }; - int numjoysticks; - int i, j; - int fd; - char path[PATH_MAX]; - dev_t dev_nums[MAX_JOYSTICKS]; /* major/minor device numbers */ - struct stat sb; - int n, duplicate; - - numjoysticks = 0; - /* First see if the user specified one or more joysticks to use */ if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) { char *envcopy, *envpath, *delim; @@ -422,123 +420,150 @@ SDL_SYS_JoystickInit(void) if (delim != NULL) { *delim++ = '\0'; } - if (stat(envpath, &sb) == 0) { - fd = open(envpath, O_RDONLY, 0); - if (fd >= 0) { - /* Assume the user knows what they're doing. */ - SDL_joylist[numjoysticks].fname = SDL_strdup(envpath); - if (SDL_joylist[numjoysticks].fname) { - dev_nums[numjoysticks] = sb.st_rdev; - ++numjoysticks; - } - close(fd); - } - } + MaybeAddDevice(envpath); envpath = delim; } SDL_free(envcopy); } - for (i = 0; i < SDL_arraysize(joydev_pattern); ++i) { - for (j = 0; j < MAX_JOYSTICKS; ++j) { - SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j); - - /* rcg06302000 replaced access(F_OK) call with stat(). - * stat() will fail if the file doesn't exist, so it's - * equivalent behaviour. - */ - if (stat(path, &sb) == 0) { - /* Check to make sure it's not already in list. - * This happens when we see a stick via symlink. - */ - duplicate = 0; - for (n = 0; (n < numjoysticks) && !duplicate; ++n) { - if (sb.st_rdev == dev_nums[n]) { - duplicate = 1; - } - } - if (duplicate) { - continue; - } - - fd = open(path, O_RDONLY, 0); - if (fd < 0) { - continue; - } -#if SDL_INPUT_LINUXEV -#ifdef DEBUG_INPUT_EVENTS - printf("Checking %s\n", path); +#if SDL_USE_LIBUDEV + if (LoadUDEVLibrary() == 0) { /* okay if this fails, FOR NOW. */ + return JoystickInitWithUdev(); + } #endif - if ((i == 0) && !EV_IsJoystick(fd)) { - close(fd); - continue; - } -#endif - close(fd); - /* We're fine, add this joystick */ - SDL_joylist[numjoysticks].fname = SDL_strdup(path); - if (SDL_joylist[numjoysticks].fname) { - dev_nums[numjoysticks] = sb.st_rdev; - ++numjoysticks; - } - } + return JoystickInitWithoutUdev(); +} + +int SDL_SYS_NumJoysticks() +{ + return numjoysticks; +} + +static SDL_bool +HotplugUpdateAvailable(void) +{ +#if SDL_USE_LIBUDEV + if (udev_mon != NULL) { + const int fd = UDEV_udev_monitor_get_fd(udev_mon); + fd_set fds; + struct timeval tv; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = 0; + if ((select(fd+1, &fds, NULL, NULL, &tv) > 0) && (FD_ISSET(fd, &fds))) { + return SDL_TRUE; + } + } +#endif + + return SDL_FALSE; +} + +void SDL_SYS_JoystickDetect() +{ +#if SDL_USE_LIBUDEV + struct udev_device *dev = NULL; + const char *devnode = NULL; + const char *action = NULL; + const char *val = NULL; + + while (HotplugUpdateAvailable()) { + dev = UDEV_udev_monitor_receive_device(udev_mon); + if (dev == NULL) { + break; + } + val = UDEV_udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); + if ((!val) || (SDL_strcmp(val, "1") != 0)) { + continue; } -#if SDL_INPUT_LINUXEV - /* This is a special case... - If the event devices are valid then the joystick devices - will be duplicates but without extra information about their - hats or balls. Unfortunately, the event devices can't - currently be calibrated, so it's a win-lose situation. - So : /dev/input/eventX = /dev/input/jsY = /dev/jsY - */ - if ((i == 0) && (numjoysticks > 0)) - break; -#endif - } -#ifndef NO_LOGICAL_JOYSTICKS - numjoysticks += CountLogicalJoysticks(numjoysticks); -#endif + action = UDEV_udev_device_get_action(dev); + devnode = UDEV_udev_device_get_devnode(dev); - return (numjoysticks); + if (SDL_strcmp(action, "add") == 0) { + const int device_index = MaybeAddDevice(devnode); + if (device_index != -1) { + /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */ + #if !SDL_EVENTS_DISABLED + SDL_Event event; + event.type = SDL_JOYDEVICEADDED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_index; + if ( (SDL_EventOK == NULL) || + (*SDL_EventOK) (SDL_EventOKParam, &event) ) { + SDL_PushEvent(&event); + } + } + #endif // !SDL_EVENTS_DISABLED + } + } else if (SDL_strcmp(action, "remove") == 0) { + const int inst = MaybeRemoveDevice(devnode); + if (inst != -1) { + /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */ + #if !SDL_EVENTS_DISABLED + SDL_Event event; + event.type = SDL_JOYDEVICEREMOVED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = inst; + if ( (SDL_EventOK == NULL) || + (*SDL_EventOK) (SDL_EventOKParam, &event) ) { + SDL_PushEvent(&event); + } + } + #endif // !SDL_EVENTS_DISABLED + } + } + UDEV_udev_device_unref(dev); + } +#endif +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + /* + * This results in a select() call, so technically we're polling to + * decide if we should poll, but I think this function is here because + * Windows has to do an enormous amount of work to detect new sticks, + * whereas libudev just needs to see if there's more data available on + * a socket...so this should be acceptable, I hope. + */ + return HotplugUpdateAvailable(); +} + +static SDL_joylist_item * +JoystickByDevIndex(int device_index) +{ + SDL_joylist_item *item = SDL_joylist; + + if ((device_index < 0) || (device_index >= numjoysticks)) { + return NULL; + } + + while (device_index > 0) { + SDL_assert(item != NULL); + device_index--; + item = item->next; + } + + return item; } /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - int fd; - static char namebuf[128]; - char *name; - SDL_logical_joydecl(int oindex = index); + return JoystickByDevIndex(device_index)->name; +} -#ifndef NO_LOGICAL_JOYSTICKS - SDL_joylist_head(index, index); -#endif - name = NULL; - fd = open(SDL_joylist[index].fname, O_RDONLY, 0); - if (fd >= 0) { - if ( -#if SDL_INPUT_LINUXEV - (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) && -#endif - (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0)) { - name = SDL_joylist[index].fname; - } else { - name = namebuf; - } - close(fd); - - -#ifndef NO_LOGICAL_JOYSTICKS - if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next - || index != oindex) { - LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128); - } -#endif - } - return name; +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return JoystickByDevIndex(device_index)->device_instance; } static int @@ -577,101 +602,8 @@ allocate_balldata(SDL_Joystick * joystick) return (0); } -static SDL_bool -JS_ConfigJoystick(SDL_Joystick * joystick, int fd) -{ - SDL_bool handled; - unsigned char n; - int old_axes, tmp_naxes, tmp_nhats, tmp_nballs; - const char *name; - char *env, env_name[128]; - int i; - - handled = SDL_FALSE; - - /* Default joystick device settings */ - if (ioctl(fd, JSIOCGAXES, &n) < 0) { - joystick->naxes = 2; - } else { - joystick->naxes = n; - } - if (ioctl(fd, JSIOCGBUTTONS, &n) < 0) { - joystick->nbuttons = 2; - } else { - joystick->nbuttons = n; - } - - name = SDL_SYS_JoystickName(joystick->index); - old_axes = joystick->naxes; - - /* Generic analog joystick support */ - if (SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat")) { - if (SDL_sscanf(name, "Analog %d-axis %*d-button %d-hat", - &tmp_naxes, &tmp_nhats) == 2) { - - joystick->naxes = tmp_naxes; - joystick->nhats = tmp_nhats; - - handled = SDL_TRUE; - } - } - - /* Special joystick support */ - for (i = 0; i < SDL_arraysize(special_joysticks); ++i) { - if (SDL_strcmp(name, special_joysticks[i].name) == 0) { - - joystick->naxes = special_joysticks[i].naxes; - joystick->nhats = special_joysticks[i].nhats; - joystick->nballs = special_joysticks[i].nballs; - - handled = SDL_TRUE; - break; - } - } - - /* User environment joystick support */ - if ((env = SDL_getenv("SDL_LINUX_JOYSTICK"))) { - *env_name = '\0'; - if (*env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1) - env += SDL_strlen(env_name) + 2; - else if (SDL_sscanf(env, "%s", env_name) == 1) - env += SDL_strlen(env_name); - - if (SDL_strcmp(name, env_name) == 0) { - - if (SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats, - &tmp_nballs) == 3) { - - joystick->naxes = tmp_naxes; - joystick->nhats = tmp_nhats; - joystick->nballs = tmp_nballs; - - handled = SDL_TRUE; - } - } - } - - /* Remap hats and balls */ - if (handled) { - if (joystick->nhats > 0) { - if (allocate_hatdata(joystick) < 0) { - joystick->nhats = 0; - } - } - if (joystick->nballs > 0) { - if (allocate_balldata(joystick) < 0) { - joystick->nballs = 0; - } - } - } - - return (handled); -} - -#if SDL_INPUT_LINUXEV - -static SDL_bool -EV_ConfigJoystick(SDL_Joystick * joystick, int fd) +static void +ConfigJoystick(SDL_Joystick * joystick, int fd) { int i, t; unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; @@ -682,7 +614,6 @@ EV_ConfigJoystick(SDL_Joystick * joystick, int fd) if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) && (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) { - joystick->hwdata->is_hid = SDL_TRUE; /* Get the number of buttons, axes, and other thingamajigs */ for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) { @@ -764,27 +695,8 @@ EV_ConfigJoystick(SDL_Joystick * joystick, int fd) } } } - return (joystick->hwdata->is_hid); } -#endif /* SDL_INPUT_LINUXEV */ - -#ifndef NO_LOGICAL_JOYSTICKS -static void -ConfigLogicalJoystick(SDL_Joystick * joystick) -{ - struct joystick_logical_layout *layout; - - layout = SDL_joylist[joystick->index].map->layout + - SDL_joylist[joystick->index].logicalno; - - joystick->nbuttons = layout->nbuttons; - joystick->nhats = layout->nhats; - joystick->naxes = layout->naxes; - joystick->nballs = layout->nballs; -} -#endif - /* Function to open a joystick for use. The joystick to open is specified by the index field of the joystick. @@ -792,147 +704,64 @@ ConfigLogicalJoystick(SDL_Joystick * joystick) It returns 0, or -1 if there is an error. */ int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { - int fd; - char *fname; - SDL_logical_joydecl(int realindex); - SDL_logical_joydecl(SDL_Joystick * realjoy = NULL); + SDL_joylist_item *item = JoystickByDevIndex(device_index); + char *fname = NULL; + int fd = -1; - /* Open the joystick and set the joystick file descriptor */ -#ifndef NO_LOGICAL_JOYSTICKS - if (SDL_joylist[joystick->index].fname == NULL) { - SDL_joylist_head(realindex, joystick->index); - realjoy = SDL_JoystickOpen(realindex); - - if (realjoy == NULL) - return (-1); - - fd = realjoy->hwdata->fd; - fname = realjoy->hwdata->fname; - - } else { - fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); - fname = SDL_joylist[joystick->index].fname; + if (item == NULL) { + SDL_SetError("No such device"); + return -1; } - SDL_joylist[joystick->index].joy = joystick; -#else - fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); - fname = SDL_joylist[joystick->index].fname; -#endif + fname = item->path; + fd = open(fname, O_RDONLY, 0); if (fd < 0) { - SDL_SetError("Unable to open %s\n", SDL_joylist[joystick->index]); - return (-1); + SDL_SetError("Unable to open %s", fname); + return -1; } + + joystick->instance_id = device_index; joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); if (joystick->hwdata == NULL) { - SDL_OutOfMemory(); close(fd); + SDL_OutOfMemory(); return (-1); } SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + joystick->hwdata->removed = SDL_FALSE; + joystick->hwdata->device_instance = item->device_instance; + joystick->hwdata->guid = item->guid; joystick->hwdata->fd = fd; - joystick->hwdata->fname = fname; + joystick->hwdata->fname = SDL_strdup(item->path); + if (joystick->hwdata->fname == NULL) { + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + close(fd); + SDL_OutOfMemory(); + return (-1); + } + + SDL_assert(item->hwdata == NULL); + item->hwdata = joystick->hwdata; /* Set the joystick to non-blocking read mode */ fcntl(fd, F_SETFL, O_NONBLOCK); /* Get the number of buttons and axes on the joystick */ -#ifndef NO_LOGICAL_JOYSTICKS - if (realjoy) - ConfigLogicalJoystick(joystick); - else -#endif -#if SDL_INPUT_LINUXEV - if (!EV_ConfigJoystick(joystick, fd)) -#endif - JS_ConfigJoystick(joystick, fd); + ConfigJoystick(joystick, fd); return (0); } -#ifndef NO_LOGICAL_JOYSTICKS - -static SDL_Joystick * -FindLogicalJoystick(SDL_Joystick * joystick, - struct joystick_logical_mapping *v) +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) { - SDL_Joystick *logicaljoy; - register int i; - - i = joystick->index; - logicaljoy = NULL; - - /* get the fake joystick that will receive the event - */ - for (;;) { - - if (SDL_joylist[i].logicalno == v->njoy) { - logicaljoy = SDL_joylist[i].joy; - break; - } - - if (SDL_joylist[i].next == 0) - break; - - i = SDL_joylist[i].next; - - } - - return logicaljoy; + return !joystick->closed && !joystick->hwdata->removed; } -static int -LogicalJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) -{ - struct joystick_logical_mapping *buttons; - SDL_Joystick *logicaljoy = NULL; - - /* if there's no map then this is just a regular joystick - */ - if (SDL_joylist[joystick->index].map == NULL) - return 0; - - /* get the logical joystick that will receive the event - */ - buttons = SDL_joylist[joystick->index].map->buttonmap + button; - logicaljoy = FindLogicalJoystick(joystick, buttons); - - if (logicaljoy == NULL) - return 1; - - SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state); - - return 1; -} - -static int -LogicalJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) -{ - struct joystick_logical_mapping *axes; - SDL_Joystick *logicaljoy = NULL; - - /* if there's no map then this is just a regular joystick - */ - if (SDL_joylist[joystick->index].map == NULL) - return 0; - - /* get the logical joystick that will receive the event - */ - axes = SDL_joylist[joystick->index].map->axismap + axis; - logicaljoy = FindLogicalJoystick(joystick, axes); - - if (logicaljoy == NULL) - return 1; - - SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value); - - return 1; -} -#endif /* USE_LOGICAL_JOYSTICKS */ - static __inline__ void HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value) { @@ -942,8 +771,6 @@ HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value) {SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT}, {SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN} }; - SDL_logical_joydecl(SDL_Joystick * logicaljoy = NULL); - SDL_logical_joydecl(struct joystick_logical_mapping *hats = NULL); the_hat = &stick->hwdata->hats[hat]; if (value < 0) { @@ -955,24 +782,6 @@ HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value) } if (value != the_hat->axis[axis]) { the_hat->axis[axis] = value; - -#ifndef NO_LOGICAL_JOYSTICKS - /* if there's no map then this is just a regular joystick - */ - if (SDL_joylist[stick->index].map != NULL) { - - /* get the fake joystick that will receive the event - */ - hats = SDL_joylist[stick->index].map->hatmap + hat; - logicaljoy = FindLogicalJoystick(stick, hats); - } - - if (logicaljoy) { - stick = logicaljoy; - hat = hats->nthing; - } -#endif /* USE_LOGICAL_JOYSTICKS */ - SDL_PrivateJoystickHat(stick, hat, position_map[the_hat-> axis[1]][the_hat->axis[0]]); @@ -985,77 +794,9 @@ HandleBall(SDL_Joystick * stick, Uint8 ball, int axis, int value) stick->hwdata->balls[ball].axis[axis] += value; } -/* 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. - */ -static __inline__ void -JS_HandleEvents(SDL_Joystick * joystick) -{ - struct js_event events[32]; - int i, len; - Uint8 other_axis; -#ifndef NO_LOGICAL_JOYSTICKS - if (SDL_joylist[joystick->index].fname == NULL) { - SDL_joylist_head(i, joystick->index); - JS_HandleEvents(SDL_joylist[i].joy); - return; - } -#endif - - while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) { - len /= sizeof(events[0]); - for (i = 0; i < len; ++i) { - switch (events[i].type & ~JS_EVENT_INIT) { - case JS_EVENT_AXIS: - if (events[i].number < joystick->naxes) { -#ifndef NO_LOGICAL_JOYSTICKS - if (!LogicalJoystickAxis(joystick, - events[i].number, - events[i].value)) -#endif - SDL_PrivateJoystickAxis(joystick, - events[i].number, - events[i].value); - break; - } - events[i].number -= joystick->naxes; - other_axis = (events[i].number / 2); - if (other_axis < joystick->nhats) { - HandleHat(joystick, other_axis, - events[i].number % 2, events[i].value); - break; - } - events[i].number -= joystick->nhats * 2; - other_axis = (events[i].number / 2); - if (other_axis < joystick->nballs) { - HandleBall(joystick, other_axis, - events[i].number % 2, events[i].value); - break; - } - break; - case JS_EVENT_BUTTON: -#ifndef NO_LOGICAL_JOYSTICKS - if (!LogicalJoystickButton(joystick, - events[i].number, events[i].value)) -#endif - SDL_PrivateJoystickButton(joystick, - events[i].number, - events[i].value); - break; - default: - /* ?? */ - break; - } - } - } -} - -#if SDL_INPUT_LINUXEV static __inline__ int -EV_AxisCorrect(SDL_Joystick * joystick, int which, int value) +AxisCorrect(SDL_Joystick * joystick, int which, int value) { struct axis_correct *correct; @@ -1083,19 +824,12 @@ EV_AxisCorrect(SDL_Joystick * joystick, int which, int value) } static __inline__ void -EV_HandleEvents(SDL_Joystick * joystick) +HandleInputEvents(SDL_Joystick * joystick) { struct input_event events[32]; int i, len; int code; -#ifndef NO_LOGICAL_JOYSTICKS - if (SDL_joylist[joystick->index].fname == NULL) { - SDL_joylist_head(i, joystick->index); - return EV_HandleEvents(SDL_joylist[i].joy); - } -#endif - while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) { len /= sizeof(events[0]); for (i = 0; i < len; ++i) { @@ -1104,16 +838,9 @@ EV_HandleEvents(SDL_Joystick * joystick) case EV_KEY: if (code >= BTN_MISC) { code -= BTN_MISC; -#ifndef NO_LOGICAL_JOYSTICKS - if (!LogicalJoystickButton(joystick, - joystick-> - hwdata->key_map[code], - events[i].value)) -#endif - SDL_PrivateJoystickButton(joystick, - joystick-> - hwdata->key_map[code], - events[i].value); + SDL_PrivateJoystickButton(joystick, + joystick->hwdata->key_map[code], + events[i].value); } break; case EV_ABS: @@ -1135,16 +862,10 @@ EV_HandleEvents(SDL_Joystick * joystick) break; default: events[i].value = - EV_AxisCorrect(joystick, code, events[i].value); -#ifndef NO_LOGICAL_JOYSTICKS - if (!LogicalJoystickAxis(joystick, - joystick->hwdata->abs_map[code], - events[i].value)) -#endif - SDL_PrivateJoystickAxis(joystick, - joystick-> - hwdata->abs_map[code], - events[i].value); + AxisCorrect(joystick, code, events[i].value); + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value); break; } break; @@ -1165,19 +886,13 @@ EV_HandleEvents(SDL_Joystick * joystick) } } } -#endif /* SDL_INPUT_LINUXEV */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { int i; -#if SDL_INPUT_LINUXEV - if (joystick->hwdata->is_hid) - EV_HandleEvents(joystick); - else -#endif - JS_HandleEvents(joystick); + HandleInputEvents(joystick); /* Deliver ball motion updates */ for (i = 0; i < joystick->nballs; ++i) { @@ -1197,43 +912,59 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { -#ifndef NO_LOGICAL_JOYSTICKS - register int i; - if (SDL_joylist[joystick->index].fname == NULL) { - SDL_joylist_head(i, joystick->index); - SDL_JoystickClose(SDL_joylist[i].joy); - } -#endif - if (joystick->hwdata) { -#ifndef NO_LOGICAL_JOYSTICKS - if (SDL_joylist[joystick->index].fname != NULL) -#endif - close(joystick->hwdata->fd); - if (joystick->hwdata->hats) { - SDL_free(joystick->hwdata->hats); - } - if (joystick->hwdata->balls) { - SDL_free(joystick->hwdata->balls); - } + close(joystick->hwdata->fd); + SDL_free(joystick->hwdata->hats); + SDL_free(joystick->hwdata->balls); + SDL_free(joystick->hwdata->fname); SDL_free(joystick->hwdata); joystick->hwdata = NULL; } + joystick->closed = 1; } /* Function to perform any system-specific joystick related cleanup */ void SDL_SYS_JoystickQuit(void) { - int i; + SDL_joylist_item *item = NULL; + SDL_joylist_item *next = NULL; - for (i = 0; SDL_joylist[i].fname; ++i) { - if (SDL_joylist[i].fname) { - SDL_free(SDL_joylist[i].fname); - SDL_joylist[i].fname = NULL; - } + for (item = SDL_joylist; item; item = next) { + next = item->next; + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); } + + SDL_joylist = SDL_joylist_tail = NULL; + + numjoysticks = 0; + instance_counter = 0; + +#if SDL_USE_LIBUDEV + if (udev_mon != NULL) { + UDEV_udev_monitor_unref(udev_mon); + udev_mon = NULL; + } + if (udev != NULL) { + UDEV_udev_unref(udev); + udev = NULL; + } + UnloadUDEVLibrary(); +#endif +} + +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + return JoystickByDevIndex(device_index)->guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + return joystick->hwdata->guid; } #endif /* SDL_JOYSTICK_LINUX */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick_c.h b/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick_c.h old mode 100755 new mode 100644 index a6c382f0e..90dcfe4de --- a/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick_c.h +++ b/src/eepp/helper/SDL2/src/joystick/linux/SDL_sysjoystick_c.h @@ -19,14 +19,16 @@ 3. This notice may not be removed or altered from any source distribution. */ -#if SDL_INPUT_LINUXEV #include -#endif /* The private structure used to keep track of a joystick */ struct joystick_hwdata { int fd; + int device_instance; + SDL_bool removed; + + SDL_JoystickGUID guid; char *fname; /* Used in haptic subsystem */ /* The current linux joystick driver maps hats to two axes */ @@ -41,8 +43,6 @@ struct joystick_hwdata } *balls; /* Support for the Linux 2.4 unified input interface */ -#if SDL_INPUT_LINUXEV - SDL_bool is_hid; Uint8 key_map[KEY_MAX - BTN_MISC]; Uint8 abs_map[ABS_MAX]; struct axis_correct @@ -50,5 +50,4 @@ struct joystick_hwdata int used; int coef[3]; } abs_correct[ABS_MAX]; -#endif }; diff --git a/src/eepp/helper/SDL2/src/joystick/nds/SDL_sysjoystick.c b/src/eepp/helper/SDL2/src/joystick/nds/SDL_sysjoystick.c old mode 100755 new mode 100644 index 703734f57..a304473fb --- a/src/eepp/helper/SDL2/src/joystick/nds/SDL_sysjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/nds/SDL_sysjoystick.c @@ -36,25 +36,38 @@ #include "../../video/nds/SDL_ndsevents_c.h" /* 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) { - SDL_numjoysticks = 1; return (1); } +int SDL_SYS_NumJoysticks() +{ + return 1; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; +} + /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - if (!index) - return "NDS builtin joypad"; - SDL_SetError("No joystick available with that index"); - return (NULL); + return "NDS builtin joypad"; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; } /* Function to open a joystick for use. @@ -63,7 +76,7 @@ SDL_SYS_JoystickName(int index) It returns 0, or -1 if there is an error. */ int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { joystick->nbuttons = 8; joystick->nhats = 0; @@ -72,6 +85,11 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) return 0; } +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; +} /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, @@ -168,4 +186,24 @@ SDL_SYS_JoystickQuit(void) { } +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + #endif /* SDL_JOYSTICK_NDS */ diff --git a/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick.c b/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick.c old mode 100755 new mode 100644 index d73f66416..f63bdc41d --- a/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick.c @@ -29,17 +29,22 @@ * 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 + * with polled devices, and it's fine to call IDirectInputDevice8_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" - +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_mutex.h" +#include "SDL_events.h" +#if !SDL_EVENTS_DISABLED +#include "../../events/SDL_events_c.h" +#endif #ifndef DIDFT_OPTIONAL #define DIDFT_OPTIONAL 0x80000000 @@ -47,7 +52,7 @@ #define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ -#define MAX_JOYSTICKS 8 +#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 */ @@ -58,16 +63,66 @@ extern HWND SDL_HelperWindow; /* local variables */ static SDL_bool coinitialized = SDL_FALSE; -static LPDIRECTINPUT dinput = NULL; +static LPDIRECTINPUT8 dinput = NULL; +static SDL_bool s_bDeviceAdded = SDL_FALSE; +static SDL_bool s_bDeviceRemoved = SDL_FALSE; +static int s_nInstanceID = -1; +static GUID *s_pKnownJoystickGUIDs = NULL; +static SDL_cond *s_condJoystickThread = NULL; +static SDL_mutex *s_mutexJoyStickEnum = NULL; +static SDL_Thread *s_threadJoystick = NULL; +static SDL_bool s_bJoystickThreadQuit = SDL_FALSE; +static HANDLE s_pXInputDLL = 0; + 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 char *SYS_JoystickNames[MAX_JOYSTICKS]; -static int SYS_NumJoysticks; -static HINSTANCE DInputDLL = NULL; +struct JoyStick_DeviceData_ +{ + SDL_JoystickGUID guid; + DIDEVICEINSTANCE dxdevice; + char *joystickname; + Uint8 send_add_event; + int nInstanceID; + SDL_bool bXInputDevice; + Uint8 XInputUserId; + struct JoyStick_DeviceData_ *pNext; +}; +/* Forward decl's for XInput API's we load dynamically and use if available */ +typedef DWORD (WINAPI *XInputGetState_t) + ( + DWORD dwUserIndex, // [in] Index of the gamer associated with the device + XINPUT_STATE_EX* pState // [out] Receives the current state + ); + +typedef DWORD (WINAPI *XInputSetState_t) + ( + DWORD dwUserIndex, // [in] Index of the gamer associated with the device + XINPUT_VIBRATION* pVibration // [in, out] The vibration information to send to the controller + ); + +typedef DWORD (WINAPI *XInputGetCapabilities_t) + ( + DWORD dwUserIndex, // [in] Index of the gamer associated with the device + DWORD dwFlags, // [in] Input flags that identify the device type + XINPUT_CAPABILITIES* pCapabilities // [out] Receives the capabilities + ); + +XInputGetState_t PC_XInputGetState; +XInputSetState_t PC_XInputSetState; +XInputGetCapabilities_t PC_XInputGetCapabilities; + +#define XINPUTGETSTATE PC_XInputGetState +#define XINPUTSETSTATE PC_XInputSetState +#define XINPUTGETCAPABILITIES PC_XInputGetCapabilities +#define INVALID_XINPUT_USERID 255 + +typedef struct JoyStick_DeviceData_ JoyStick_DeviceData; + +static JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ + /* local prototypes */ static void SetDIerror(const char *function, HRESULT code); static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * @@ -83,7 +138,7 @@ static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, Uint8 state); -/* Taken from Wine - Thanks! */ +// 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}, @@ -273,6 +328,293 @@ SetDIerror(const char *function, HRESULT code) } +#define SAFE_RELEASE(p) \ +{ \ + if (p) { \ + (p)->lpVtbl->Release((p)); \ + (p) = 0; \ + } \ +} + + +DEFINE_GUID(CLSID_WbemLocator, 0x4590f811,0x1d3a,0x11d0,0x89,0x1F,0x00,0xaa,0x00,0x4b,0x2e,0x24); +DEFINE_GUID(IID_IWbemLocator, 0xdc12a687,0x737f,0x11cf,0x88,0x4d,0x00,0xaa,0x00,0x4b,0x2e,0x24); + +//----------------------------------------------------------------------------- +// +// code from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx +// +// Enum each PNP device using WMI and check each device ID to see if it contains +// "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device +// Unfortunately this information can not be found by just using DirectInput +//----------------------------------------------------------------------------- +BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput ) +{ + IWbemLocator* pIWbemLocator = NULL; + IEnumWbemClassObject* pEnumDevices = NULL; + IWbemClassObject* pDevices[20]; + IWbemServices* pIWbemServices = NULL; + DWORD uReturned = 0; + BSTR bstrNamespace = NULL; + BSTR bstrDeviceID = NULL; + BSTR bstrClassName = NULL; + SDL_bool bIsXinputDevice= SDL_FALSE; + UINT iDevice = 0; + VARIANT var; + HRESULT hr; + DWORD bCleanupCOM; + + SDL_memset( pDevices, 0x0, sizeof(pDevices) ); + + // CoInit if needed + hr = CoInitialize(NULL); + bCleanupCOM = SUCCEEDED(hr); + + // Create WMI + hr = CoCreateInstance( &CLSID_WbemLocator, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IWbemLocator, + (LPVOID*) &pIWbemLocator); + if( FAILED(hr) || pIWbemLocator == NULL ) + goto LCleanup; + + bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup; + bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; + bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; + + // Connect to WMI + hr = IWbemLocator_ConnectServer( pIWbemLocator, bstrNamespace, NULL, NULL, 0L, + 0L, NULL, NULL, &pIWbemServices ); + if( FAILED(hr) || pIWbemServices == NULL ) + goto LCleanup; + + // Switch security level to IMPERSONATE. + CoSetProxyBlanket( (IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); + + hr = IWbemServices_CreateInstanceEnum( pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices ); + if( FAILED(hr) || pEnumDevices == NULL ) + goto LCleanup; + + // Loop over all devices + for( ;; ) + { + // Get 20 at a time + hr = IEnumWbemClassObject_Next( pEnumDevices, 10000, 20, pDevices, &uReturned ); + if( FAILED(hr) ) + goto LCleanup; + if( uReturned == 0 ) + break; + + for( iDevice=0; iDeviceData1 ) + { + bIsXinputDevice = SDL_TRUE; + } + } + if ( pDeviceString ) + SDL_free( pDeviceString ); + + if ( bIsXinputDevice ) + break; + } + SAFE_RELEASE( pDevices[iDevice] ); + } + } + +LCleanup: + + for( iDevice=0; iDevice<20; iDevice++ ) + SAFE_RELEASE( pDevices[iDevice] ); + SAFE_RELEASE( pEnumDevices ); + SAFE_RELEASE( pIWbemLocator ); + SAFE_RELEASE( pIWbemServices ); + + if ( bstrNamespace ) + SysFreeString( bstrNamespace ); + if ( bstrClassName ) + SysFreeString( bstrClassName ); + if ( bstrDeviceID ) + SysFreeString( bstrDeviceID ); + + if( bCleanupCOM ) + CoUninitialize(); + + return bIsXinputDevice; +} + + +static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE; + +/* windowproc for our joystick detect thread message only window, to detect any usb device addition/removal + */ +LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { + switch (message) { + case WM_DEVICECHANGE: + switch (wParam) { + case DBT_DEVICEARRIVAL: + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + s_bWindowsDeviceChanged = SDL_TRUE; + } + break; + case DBT_DEVICEREMOVECOMPLETE: + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + s_bWindowsDeviceChanged = SDL_TRUE; + } + break; + } + return 0; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} + + +DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, \ + 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +/* Function/thread to scan the system for joysticks. + */ +static int +SDL_JoystickThread(void *_data) +{ + HRESULT result = S_OK; + HWND messageWindow = 0; + HDEVNOTIFY hNotify = 0; + DEV_BROADCAST_DEVICEINTERFACE dbh; + SDL_bool bOpenedXInputDevices[4]; + WNDCLASSEX wincl; + + SDL_memset( bOpenedXInputDevices, 0x0, sizeof(bOpenedXInputDevices) ); + + result = WIN_CoInitialize(); + + SDL_memset( &wincl, 0x0, sizeof(wincl) ); + wincl.hInstance = GetModuleHandle( NULL ); + wincl.lpszClassName = L"Message"; + wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; // This function is called by windows + wincl.cbSize = sizeof (WNDCLASSEX); + + if (!RegisterClassEx (&wincl)) + { + SDL_SetError("Failed to create register class for joystick autodetect.", + GetLastError()); + return -1; + } + + messageWindow = (HWND)CreateWindowEx( 0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); + if ( !messageWindow ) + { + SDL_SetError("Failed to create message window for joystick autodetect.", + GetLastError()); + return -1; + } + + SDL_memset(&dbh, 0x0, sizeof(dbh)); + + dbh.dbcc_size = sizeof(dbh); + dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + dbh.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; + + hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); + if ( !hNotify ) + { + SDL_SetError("Failed to create notify device for joystick autodetect.", + GetLastError()); + return -1; + } + + SDL_LockMutex( s_mutexJoyStickEnum ); + while ( s_bJoystickThreadQuit == SDL_FALSE ) + { + MSG messages; + Uint8 userId; + int nCurrentOpenedXInputDevices = 0; + int nNewOpenedXInputDevices = 0; + SDL_CondWaitTimeout( s_condJoystickThread, s_mutexJoyStickEnum, 300 ); + + while ( s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) ) + { + if ( GetMessage(&messages, messageWindow, 0, 0) != 0 ) { + TranslateMessage(&messages); + DispatchMessage(&messages); + } + } + + // scan for any change in XInput devices + for ( userId = 0; userId < 4; userId++ ) + { + XINPUT_CAPABILITIES capabilities; + DWORD result; + + if ( bOpenedXInputDevices[userId] == SDL_TRUE ) + nCurrentOpenedXInputDevices++; + + result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); + if ( result == ERROR_SUCCESS ) + { + bOpenedXInputDevices[userId] = SDL_TRUE; + nNewOpenedXInputDevices++; + } + else + { + bOpenedXInputDevices[userId] = SDL_FALSE; + } + } + + + if ( s_pKnownJoystickGUIDs && ( s_bWindowsDeviceChanged || nNewOpenedXInputDevices != nCurrentOpenedXInputDevices ) ) + { + SDL_Delay( 300 ); // wait for direct input to find out about this device + + s_bDeviceRemoved = SDL_TRUE; + s_bDeviceAdded = SDL_TRUE; + s_bWindowsDeviceChanged = SDL_FALSE; + } + } + SDL_UnlockMutex( s_mutexJoyStickEnum ); + + if ( hNotify ) + UnregisterDeviceNotification( hNotify ); + + if ( messageWindow ) + DestroyWindow( messageWindow ); + + UnregisterClass( wincl.lpszClassName, wincl.hInstance ); + messageWindow = 0; + WIN_CoUninitialize(); + return 1; +} + + /* 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. @@ -284,8 +626,6 @@ SDL_SYS_JoystickInit(void) HRESULT result; HINSTANCE instance; - SYS_NumJoysticks = 0; - result = WIN_CoInitialize(); if (FAILED(result)) { SetDIerror("CoInitialize", result); @@ -294,8 +634,8 @@ SDL_SYS_JoystickInit(void) coinitialized = SDL_TRUE; - result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectInput, (LPVOID)&dinput); + result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, + &IID_IDirectInput8, (LPVOID)&dinput); if (FAILED(result)) { SDL_SYS_JoystickQuit(); @@ -311,7 +651,7 @@ SDL_SYS_JoystickInit(void) GetLastError()); return (-1); } - result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); + result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION); if (FAILED(result)) { SDL_SYS_JoystickQuit(); @@ -319,34 +659,255 @@ SDL_SYS_JoystickInit(void) return (-1); } - /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ - result = IDirectInput_EnumDevices(dinput, - DIDEVTYPE_JOYSTICK, - EnumJoysticksCallback, - NULL, DIEDFL_ATTACHEDONLY); + s_mutexJoyStickEnum = SDL_CreateMutex(); + s_condJoystickThread = SDL_CreateCond(); + s_bDeviceAdded = SDL_TRUE; // force a scan of the system for joysticks this first time + SDL_SYS_JoystickDetect(); - return SYS_NumJoysticks; + // try to load XInput support if available + s_pXInputDLL = LoadLibrary( L"XInput1_3.dll" ); + if ( !s_pXInputDLL ) + s_pXInputDLL = LoadLibrary( L"bin\\XInput1_3.dll" ); + if ( s_pXInputDLL ) + { + // 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think... + PC_XInputGetState = (XInputGetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, (LPCSTR)100 ); + PC_XInputSetState = (XInputSetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputSetState" ); + PC_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputGetCapabilities" ); + if ( !PC_XInputGetState || !PC_XInputSetState || !PC_XInputGetCapabilities ) + { + SDL_SYS_JoystickQuit(); + SDL_SetError("GetProcAddress() failed when loading XInput.", GetLastError()); + return (-1); + } + } + + + if ( !s_threadJoystick ) + { + s_bJoystickThreadQuit = SDL_FALSE; + /* spin up the thread to detect hotplug of devices */ +#if defined(__WIN32__) && !defined(HAVE_LIBC) +#undef SDL_CreateThread + s_threadJoystick= SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL ); +#else + s_threadJoystick = SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL ); +#endif + } + return SDL_SYS_NumJoysticks(); } -static BOOL CALLBACK -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +/* return the number of joysticks that are connected right now */ +int SDL_SYS_NumJoysticks() { - SDL_memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, - sizeof(DIDEVICEINSTANCE)); - SYS_JoystickNames[SYS_NumJoysticks] = WIN_StringToUTF8(pdidInstance->tszProductName); - SYS_NumJoysticks++; + int nJoysticks = 0; + JoyStick_DeviceData *device = SYS_Joystick; + while ( device ) + { + nJoysticks++; + device = device->pNext; + } - if (SYS_NumJoysticks >= MAX_JOYSTICKS) - return DIENUM_STOP; + return nJoysticks; +} - return DIENUM_CONTINUE; +static int s_iNewGUID = 0; + +/* helper function for direct input, gets called for each connected joystick */ +static BOOL CALLBACK + EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +{ + JoyStick_DeviceData *pNewJoystick; + JoyStick_DeviceData *pPrevJoystick = NULL; + SDL_bool bXInputDevice; + pNewJoystick = *(JoyStick_DeviceData **)pContext; + while ( pNewJoystick ) + { + if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) ) + { + /* if we are replacing the front of the list then update it */ + if ( pNewJoystick == *(JoyStick_DeviceData **)pContext ) + { + *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; + } + else if ( pPrevJoystick ) + { + pPrevJoystick->pNext = pNewJoystick->pNext; + } + + pNewJoystick->pNext = SYS_Joystick; + SYS_Joystick = pNewJoystick; + + s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance; + s_iNewGUID++; + if ( s_iNewGUID < MAX_JOYSTICKS ) + return DIENUM_CONTINUE; // already have this joystick loaded, just keep going + else + return DIENUM_STOP; + } + + pPrevJoystick = pNewJoystick; + pNewJoystick = pNewJoystick->pNext; + } + + s_bDeviceAdded = SDL_TRUE; + + bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct ); + + pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) ); + + if ( bXInputDevice ) + { + pNewJoystick->bXInputDevice = SDL_TRUE; + pNewJoystick->XInputUserId = INVALID_XINPUT_USERID; + } + else + { + pNewJoystick->bXInputDevice = SDL_FALSE; + } + + SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance, + sizeof(DIDEVICEINSTANCE)); + + pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); + pNewJoystick->send_add_event = 1; + pNewJoystick->nInstanceID = ++s_nInstanceID; + SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) ); + pNewJoystick->pNext = NULL; + + if ( SYS_Joystick ) + { + pNewJoystick->pNext = SYS_Joystick; + } + SYS_Joystick = pNewJoystick; + + s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance; + s_iNewGUID++; + + if ( s_iNewGUID < MAX_JOYSTICKS ) + return DIENUM_CONTINUE; // already have this joystick loaded, just keep going + else + return DIENUM_STOP; +} + +/* detect any new joysticks being inserted into the system */ +void SDL_SYS_JoystickDetect() +{ + HRESULT result; + JoyStick_DeviceData *pCurList = NULL; + /* only enum the devices if the joystick thread told us something changed */ + if ( s_bDeviceAdded || s_bDeviceRemoved ) + { + s_bDeviceAdded = SDL_FALSE; + s_bDeviceRemoved = SDL_FALSE; + + pCurList = SYS_Joystick; + SYS_Joystick = NULL; + s_iNewGUID = 0; + SDL_mutexP( s_mutexJoyStickEnum ); + + if ( !s_pKnownJoystickGUIDs ) + s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS ); + + SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS ); + + /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ + result = IDirectInput8_EnumDevices(dinput, + DI8DEVCLASS_GAMECTRL, + EnumJoysticksCallback, + &pCurList, DIEDFL_ATTACHEDONLY); + + SDL_mutexV( s_mutexJoyStickEnum ); + } + + if ( pCurList ) + { + while ( pCurList ) + { + JoyStick_DeviceData *pListNext = NULL; +#if !SDL_EVENTS_DISABLED + SDL_Event event; + event.type = SDL_JOYDEVICEREMOVED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = pCurList->nInstanceID; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + SDL_PushEvent(&event); + } + } +#endif // !SDL_EVENTS_DISABLED + + pListNext = pCurList->pNext; + SDL_free(pCurList->joystickname); + SDL_free( pCurList ); + pCurList = pListNext; + } + + } + + if ( s_bDeviceAdded ) + { + JoyStick_DeviceData *pNewJoystick; + int device_index = 0; + s_bDeviceAdded = SDL_FALSE; + pNewJoystick = SYS_Joystick; + while ( pNewJoystick ) + { + if ( pNewJoystick->send_add_event ) + { +#if !SDL_EVENTS_DISABLED + SDL_Event event; + event.type = SDL_JOYDEVICEADDED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_index; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + pNewJoystick->send_add_event = 0; + } + device_index++; + pNewJoystick = pNewJoystick->pNext; + } + } +} + +/* we need to poll if we have pending hotplug device changes or connected devices */ +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + /* we have a new device or one was pulled, we need to think this frame please */ + if ( s_bDeviceAdded || s_bDeviceRemoved ) + return SDL_TRUE; + + return SDL_FALSE; } /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - return SYS_JoystickNames[index]; + JoyStick_DeviceData *device = SYS_Joystick; + + for (; device_index > 0; device_index--) + device = device->pNext; + + return device->joystickname; +} + +/* Function to perform the mapping between current device instance and this joysticks instance id */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) + device = device->pNext; + + return device->nInstanceID; } /* Function to open a joystick for use. @@ -355,18 +916,22 @@ SDL_SYS_JoystickName(int index) It returns 0, or -1 if there is an error. */ int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { HRESULT result; - LPDIRECTINPUTDEVICE device; + LPDIRECTINPUTDEVICE8 device; DIPROPDWORD dipdw; + JoyStick_DeviceData *joystickdevice = SYS_Joystick; + + for (; device_index > 0; device_index--) + joystickdevice = joystickdevice->pNext; SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD)); dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - /* allocate memory for system specific hardware data */ + joystick->instance_id = joystickdevice->nInstanceID; joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata)); if (joystick->hwdata == NULL) { @@ -375,140 +940,204 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) } SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata)); joystick->hwdata->buffered = 1; + joystick->hwdata->removed = 0; joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); + joystick->hwdata->guid = joystickdevice->guid; - result = - IDirectInput_CreateDevice(dinput, - &SYS_Joystick[joystick->index]. - guidInstance, &device, NULL); - if (FAILED(result)) { - SetDIerror("IDirectInput::CreateDevice", result); - return (-1); - } + if ( joystickdevice->bXInputDevice ) + { + XINPUT_CAPABILITIES capabilities; + Uint8 userId = 0; + DWORD result; + JoyStick_DeviceData *joysticklist = SYS_Joystick; + // scan the opened joysticks and pick the next free xinput userid for this one + for( ; joysticklist; joysticklist = joysticklist->pNext) + { + if ( joysticklist->bXInputDevice && joysticklist->XInputUserId == userId ) + userId++; + } - /* 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 ( XINPUTGETCAPABILITIES ) + { + result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); + if ( result == ERROR_SUCCESS ) + { + SDL_bool bIsSupported = SDL_FALSE; + // Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. + bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD ); - if (FAILED(result)) { - SetDIerror("IDirectInputDevice::QueryInterface", result); - return (-1); - } + if ( !bIsSupported ) + { + joystickdevice->bXInputDevice = SDL_FALSE; + } + else + { + // valid + joystick->hwdata->bXInputDevice = SDL_TRUE; + SDL_memset( joystick->hwdata->XInputState, 0x0, sizeof(joystick->hwdata->XInputState) ); + joystickdevice->XInputUserId = userId; + joystick->hwdata->userid = userId; + joystick->hwdata->currentXInputSlot = 0; + // The XInput API has a hard coded button/axis mapping, so we just match it + joystick->naxes = 6; + joystick->nbuttons = 15; + joystick->nballs = 0; + joystick->nhats = 0; + } + } + else + { + joystickdevice->bXInputDevice = SDL_FALSE; + } + } + else + { + joystickdevice->bXInputDevice = SDL_FALSE; + } + } - /* 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); - } + if ( joystickdevice->bXInputDevice == SDL_FALSE ) + { + joystick->hwdata->bXInputDevice = SDL_FALSE; - /* Use the extended data structure: DIJOYSTATE2. */ - result = - IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice, - &c_dfDIJoystick2); - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SetDataFormat", result); - return (-1); - } + result = + IDirectInput8_CreateDevice(dinput, + &(joystickdevice->dxdevice.guidInstance), &device, NULL); + if (FAILED(result)) { + SetDIerror("IDirectInput::CreateDevice", result); + return (-1); + } - /* Get device capabilities */ - result = - IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice, - &joystick->hwdata->Capabilities); + /* Now get the IDirectInputDevice8 interface, instead. */ + result = IDirectInputDevice8_QueryInterface(device, + &IID_IDirectInputDevice8, + (LPVOID *) & joystick-> + hwdata->InputDevice); + /* We are done with this object. Use the stored one from now on. */ + IDirectInputDevice8_Release(device); - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::GetCapabilities", result); - return (-1); - } + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::QueryInterface", result); + return (-1); + } - /* Force capable? */ - if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + /* Aquire shared access. Exclusive access is required for forces, + * though. */ + result = + IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata-> + InputDevice, SDL_HelperWindow, + DISCL_NONEXCLUSIVE | + DISCL_BACKGROUND); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result); + return (-1); + } - result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + /* Use the extended data structure: DIJOYSTATE2. */ + result = + IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice, + &c_dfDIJoystick2); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::SetDataFormat", result); + return (-1); + } - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::Acquire", result); - return (-1); - } + /* Get device capabilities */ + result = + IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice, + &joystick->hwdata->Capabilities); - /* reset all accuators. */ - result = - IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata-> - InputDevice, - DISFFC_RESET); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::GetCapabilities", result); + return (-1); + } - /* Not necessarily supported, ignore if not supported. - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand", - result); - return (-1); - } - */ + /* Force capable? */ + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { - result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice); + result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::Unacquire", result); - return (-1); - } + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::Acquire", 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; + /* reset all accuators. */ + result = + IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata-> + InputDevice, + DISFFC_RESET); - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_AUTOCENTER, &dipdw.diph); + /* Not necessarily supported, ignore if not supported. + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", + result); + return (-1); + } + */ - /* Not necessarily supported, ignore if not supported. - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SetProperty", result); - return (-1); - } - */ - } + result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); - /* What buttons and axes does it have? */ - IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice, - EnumDevObjectsCallback, joystick, - DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::Unacquire", result); + return (-1); + } - /* Reorder the input objects. Some devices do not report the X axis as - * the first axis, for example. */ - SortDevObjects(joystick); + /* Turn on auto-centering for a ForceFeedback device (until told + * otherwise). */ + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DIPROPAUTOCENTER_ON; - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = INPUT_QSIZE; + result = + IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, + DIPROP_AUTOCENTER, &dipdw.diph); - /* Set the buffer size */ - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_BUFFERSIZE, &dipdw.diph); + /* Not necessarily supported, ignore if not supported. + if (FAILED(result)) { + SetDIerror("IDirectInputDevice8::SetProperty", result); + return (-1); + } + */ + } - 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); - } + /* What buttons and axes does it have? */ + IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice, + EnumDevObjectsCallback, joystick, + DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + /* Reorder the input objects. Some devices do not report the X axis as + * the first axis, for example. */ + SortDevObjects(joystick); + + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = INPUT_QSIZE; + + /* Set the buffer size */ + result = + IDirectInputDevice8_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("IDirectInputDevice8::SetProperty", result); + return (-1); + } + } return (0); } +/* return true if this joystick is plugged in right now */ +SDL_bool SDL_SYS_JoystickAttached( SDL_Joystick * joystick ) +{ + return joystick->closed == 0 && joystick->hwdata->removed == 0; +} + + /* Sort using the data offset into the DInput struct. * This gives a reasonable ordering for the inputs. */ static int @@ -565,15 +1194,15 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID 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; + in->ofs = DIJOFS_BUTTON( in->num ); joystick->nbuttons++; } else if (dev->dwType & DIDFT_POV) { in->type = HAT; in->num = joystick->nhats; + in->ofs = DIJOFS_POV( in->num ); joystick->nhats++; } else if (dev->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; @@ -581,16 +1210,38 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) in->type = AXIS; in->num = joystick->naxes; + // work our the axis this guy maps too, thanks for the code icculus! + if ( !SDL_memcmp( &dev->guidType, &GUID_XAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_X; + else if ( !SDL_memcmp( &dev->guidType, &GUID_YAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_Y; + else if ( !SDL_memcmp( &dev->guidType, &GUID_ZAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_Z; + else if ( !SDL_memcmp( &dev->guidType, &GUID_RxAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_RX; + else if ( !SDL_memcmp( &dev->guidType, &GUID_RyAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_RY; + else if ( !SDL_memcmp( &dev->guidType, &GUID_RzAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_RZ; + else if ( !SDL_memcmp( &dev->guidType, &GUID_Slider, sizeof(dev->guidType) ) ) + { + in->ofs = DIJOFS_SLIDER( joystick->hwdata->NumSliders ); + ++joystick->hwdata->NumSliders; + } + else + { + return DIENUM_CONTINUE; // not an axis we can grok + } diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = dev->dwOfs; - diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.diph.dwObj = dev->dwType; + diprg.diph.dwHow = DIPH_BYID; diprg.lMin = AXIS_MIN; diprg.lMax = AXIS_MAX; result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, DIPROP_RANGE, &diprg.diph); if (FAILED(result)) { return DIENUM_CONTINUE; /* don't use this axis */ @@ -599,11 +1250,11 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) /* 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.diph.dwObj = dev->dwType; + dilong.diph.dwHow = DIPH_BYID; dilong.dwData = 0; result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, DIPROP_DEADZONE, &dilong.diph); if (FAILED(result)) { return DIENUM_CONTINUE; /* don't use this axis */ @@ -637,15 +1288,22 @@ SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) int i; result = - IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, + IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, sizeof(DIJOYSTATE2), &state); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = - IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, + IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, sizeof(DIJOYSTATE2), &state); } + if ( result != DI_OK ) + { + joystick->hwdata->send_remove_event = 1; + joystick->hwdata->removed = 1; + return; + } + /* Set each known axis, button and POV. */ for (i = 0; i < joystick->hwdata->NumInputs; ++i) { const input_t *in = &joystick->hwdata->Inputs[i]; @@ -718,20 +1376,24 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) numevents = INPUT_QSIZE; result = - IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, + IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = - IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, + IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); } /* Handle the events or punt */ if (FAILED(result)) + { + joystick->hwdata->send_remove_event = 1; + joystick->hwdata->removed = 1; return; + } for (i = 0; i < (int) numevents; ++i) { int j; @@ -764,6 +1426,82 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) } +/* Function to return > 0 if a bit array of buttons differs after applying a mask +*/ +int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask ) +{ + return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask ); +} + +/* Function to update the state of a XInput style joystick. +*/ +void +SDL_SYS_JoystickUpdate_XInput(SDL_Joystick * joystick) +{ + HRESULT result; + + if ( !XINPUTGETSTATE ) + return; + + result = XINPUTGETSTATE( joystick->hwdata->userid, &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot] ); + if ( result == ERROR_DEVICE_NOT_CONNECTED ) + { + joystick->hwdata->send_remove_event = 1; + joystick->hwdata->removed = 1; + return; + } + + // only fire events if the data changed from last time + if ( joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != 0 + && joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot^1].dwPacketNumber ) + { + XINPUT_STATE_EX *pXInputState = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot]; + XINPUT_STATE_EX *pXInputStatePrev = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot ^ 1]; + + SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX ); + SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) ); + SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX ); + SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) ); + SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) ); + SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) ); + + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) ) + SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) ) + SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) ) + SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) ) + SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) ) + SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) ) + SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) ) + SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) ) + SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) ) + SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) ) + SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) ) + SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) ) + SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) ) + SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) ) + SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, 0x400 ) ) + SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED : SDL_RELEASED ); // 0x400 is the undocumented code for the guide button + + joystick->hwdata->currentXInputSlot ^= 1; + + } +} + + static Uint8 TranslatePOV(DWORD value) { @@ -824,46 +1562,97 @@ 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->closed || !joystick->hwdata ) + return; - if (joystick->hwdata->buffered) - SDL_SYS_JoystickUpdate_Buffered(joystick); - else - SDL_SYS_JoystickUpdate_Polled(joystick); + if (joystick->hwdata->bXInputDevice) + { + SDL_SYS_JoystickUpdate_XInput(joystick); + } + else + { + result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); + } + + if (joystick->hwdata->buffered) + SDL_SYS_JoystickUpdate_Buffered(joystick); + else + SDL_SYS_JoystickUpdate_Polled(joystick); + } + + if ( joystick->hwdata->removed ) + { + joystick->closed = 1; + joystick->uncentered = 1; + } } /* 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->bXInputDevice ) + { + JoyStick_DeviceData *joysticklist = SYS_Joystick; + // scan the opened joysticks and clear the userid for this instance + for( ; joysticklist; joysticklist = joysticklist->pNext) + { + if ( joysticklist->bXInputDevice && joysticklist->nInstanceID == joystick->instance_id ) + { + joysticklist->XInputUserId = INVALID_XINPUT_USERID; + } + } + + } + else + { + IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Release(joystick->hwdata->InputDevice); + } if (joystick->hwdata != NULL) { /* free system specific hardware data */ SDL_free(joystick->hwdata); } + + joystick->closed = 1; } /* Function to perform any system-specific joystick related cleanup */ void SDL_SYS_JoystickQuit(void) { - int i; + JoyStick_DeviceData *device = SYS_Joystick; - for (i = 0; i < SDL_arraysize(SYS_JoystickNames); ++i) { - if (SYS_JoystickNames[i]) { - SDL_free(SYS_JoystickNames[i]); - SYS_JoystickNames[i] = NULL; - } - } + while ( device ) + { + JoyStick_DeviceData *device_next = device->pNext; + SDL_free(device->joystickname); + SDL_free(device); + device = device_next; + } + SYS_Joystick = NULL; + + if ( s_threadJoystick ) + { + SDL_LockMutex( s_mutexJoyStickEnum ); + s_bJoystickThreadQuit = SDL_TRUE; + SDL_CondBroadcast( s_condJoystickThread ); // signal the joystick thread to quit + SDL_UnlockMutex( s_mutexJoyStickEnum ); + SDL_WaitThread( s_threadJoystick, NULL ); // wait for it to bugger off + + SDL_DestroyMutex( s_mutexJoyStickEnum ); + SDL_DestroyCond( s_condJoystickThread ); + s_condJoystickThread= NULL; + s_mutexJoyStickEnum = NULL; + s_threadJoystick = NULL; + } if (dinput != NULL) { - IDirectInput_Release(dinput); + IDirectInput8_Release(dinput); dinput = NULL; } @@ -871,6 +1660,48 @@ SDL_SYS_JoystickQuit(void) WIN_CoUninitialize(); coinitialized = SDL_FALSE; } + + if ( s_pKnownJoystickGUIDs ) + { + SDL_free( s_pKnownJoystickGUIDs ); + s_pKnownJoystickGUIDs = NULL; + } + + if ( s_pXInputDLL ) + { + FreeLibrary( s_pXInputDLL ); + s_pXInputDLL = NULL; + } +} + + +/* return the stable device guid for this device index */ +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) + device = device->pNext; + + return device->guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + return joystick->hwdata->guid; +} + +/* return SDL_TRUE if this device is using XInput */ +SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) + device = device->pNext; + + return device->bXInputDevice; } #endif /* SDL_JOYSTICK_DINPUT */ diff --git a/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick_c.h b/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick_c.h old mode 100755 new mode 100644 index 1aa993486..08e6cf1af --- a/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick_c.h +++ b/src/eepp/helper/SDL2/src/joystick/windows/SDL_dxjoystick_c.h @@ -34,9 +34,14 @@ #include "../../core/windows/SDL_windows.h" -#define DIRECTINPUT_VERSION 0x0700 /* Need version 7 for force feedback. */ +#define DIRECTINPUT_VERSION 0x0800 /* Need version 7 for force feedback. Need verison 8 so IDirectInput8_EnumDevices doesn't leak like a sieve... */ #include - +#define COBJMACROS +#include +#include +#include +#include +#include #define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ @@ -57,15 +62,42 @@ typedef struct input_t Uint8 num; } input_t; +/* typedef's for XInput structs we use */ +typedef struct +{ + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; + DWORD dwPaddingReserved; +} XINPUT_GAMEPAD_EX; + +typedef struct +{ + DWORD dwPacketNumber; + XINPUT_GAMEPAD_EX Gamepad; +} XINPUT_STATE_EX; + /* The private structure used to keep track of a joystick */ struct joystick_hwdata { - LPDIRECTINPUTDEVICE2 InputDevice; + LPDIRECTINPUTDEVICE8 InputDevice; DIDEVCAPS Capabilities; int buffered; + SDL_JoystickGUID guid; input_t Inputs[MAX_INPUTS]; int NumInputs; + int NumSliders; + Uint8 removed; + Uint8 send_remove_event; + Uint8 bXInputDevice; // 1 if this device supports using the xinput API rather than DirectInput + Uint8 userid; // XInput userid index for this joystick + Uint8 currentXInputSlot; // the current position to write to in XInputState below, used so we can compare old and new values + XINPUT_STATE_EX XInputState[2]; }; #endif /* SDL_JOYSTICK_DINPUT_H */ diff --git a/src/eepp/helper/SDL2/src/joystick/windows/SDL_mmjoystick.c b/src/eepp/helper/SDL2/src/joystick/windows/SDL_mmjoystick.c old mode 100755 new mode 100644 index 5298c537b..a7093601f --- a/src/eepp/helper/SDL2/src/joystick/windows/SDL_mmjoystick.c +++ b/src/eepp/helper/SDL2/src/joystick/windows/SDL_mmjoystick.c @@ -135,6 +135,8 @@ GetJoystickName(int index, const char *szRegKey) return (name); } +static int SDL_SYS_numjoysticks = 0; + /* 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. @@ -145,7 +147,6 @@ SDL_SYS_JoystickInit(void) { int i; int maxdevs; - int numdevs; JOYINFOEX joyinfo; JOYCAPS joycaps; MMRESULT result; @@ -157,9 +158,9 @@ SDL_SYS_JoystickInit(void) } /* Loop over all potential joystick devices */ - numdevs = 0; + SDL_SYS_numjoysticks = 0; maxdevs = joyGetNumDevs(); - for (i = JOYSTICKID1; i < maxdevs && numdevs < MAX_JOYSTICKS; ++i) { + for (i = JOYSTICKID1; i < maxdevs && SDL_SYS_numjoysticks < MAX_JOYSTICKS; ++i) { joyinfo.dwSize = sizeof(joyinfo); joyinfo.dwFlags = JOY_RETURNALL; @@ -167,35 +168,55 @@ SDL_SYS_JoystickInit(void) if (result == JOYERR_NOERROR) { result = joyGetDevCaps(i, &joycaps, sizeof(joycaps)); if (result == JOYERR_NOERROR) { - SYS_JoystickID[numdevs] = i; - SYS_Joystick[numdevs] = joycaps; - SYS_JoystickName[numdevs] = + SYS_JoystickID[SDL_SYS_numjoysticks] = i; + SYS_Joystick[SDL_SYS_numjoysticks] = joycaps; + SYS_JoystickName[SDL_SYS_numjoysticks] = GetJoystickName(i, joycaps.szRegKey); - numdevs++; + SDL_SYS_numjoysticks++; } } } - return (numdevs); + return (SDL_SYS_numjoysticks); +} + +int SDL_SYS_NumJoysticks() +{ + return SDL_SYS_numjoysticks; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; } /* Function to get the device-dependent name of a joystick */ const char * -SDL_SYS_JoystickName(int index) +SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - if (SYS_JoystickName[index] != NULL) { - return (SYS_JoystickName[index]); + if (SYS_JoystickName[device_index] != NULL) { + return (SYS_JoystickName[device_index]); } else { - return (SYS_Joystick[index].szPname); + return (SYS_Joystick[device_index].szPname); } } +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; +} + /* 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) +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { int index, i; int caps_flags[MAX_AXES - 2] = @@ -204,7 +225,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) /* shortcut */ - index = joystick->index; + index = device_index; axis_min[0] = SYS_Joystick[index].wXmin; axis_max[0] = SYS_Joystick[index].wXmax; axis_min[1] = SYS_Joystick[index].wYmin; @@ -219,6 +240,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) axis_max[5] = SYS_Joystick[index].wVmax; /* allocate memory for system specific hardware data */ + joystick->instance_id = device_index; joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); if (joystick->hwdata == NULL) { @@ -251,6 +273,12 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) return (0); } +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; +} + static Uint8 TranslatePOV(DWORD value) { @@ -377,6 +405,26 @@ SDL_SYS_JoystickQuit(void) } } +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +{ + SDL_JoystickGUID guid; + // the GUID is just the first 16 chars of the name for now + const char *name = joystick->name; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + /* implementation functions */ void @@ -423,4 +471,5 @@ SetMMerror(char *function, int code) } #endif /* SDL_JOYSTICK_WINMM */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/loadso/beos/SDL_sysloadso.c b/src/eepp/helper/SDL2/src/loadso/beos/SDL_sysloadso.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/loadso/dlopen/SDL_sysloadso.c b/src/eepp/helper/SDL2/src/loadso/dlopen/SDL_sysloadso.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/loadso/dummy/SDL_sysloadso.c b/src/eepp/helper/SDL2/src/loadso/dummy/SDL_sysloadso.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/loadso/windows/SDL_sysloadso.c b/src/eepp/helper/SDL2/src/loadso/windows/SDL_sysloadso.c old mode 100755 new mode 100644 index 8b465a5e1..f07752cb8 --- a/src/eepp/helper/SDL2/src/loadso/windows/SDL_sysloadso.c +++ b/src/eepp/helper/SDL2/src/loadso/windows/SDL_sysloadso.c @@ -49,14 +49,7 @@ SDL_LoadObject(const char *sofile) void * SDL_LoadFunction(void *handle, const char *name) { -#ifdef _WIN32_WCE - LPTSTR tstr = WIN_UTF8ToString(name); - void *symbol = (void *) GetProcAddress((HMODULE) handle, tstr); - SDL_free(tstr); -#else void *symbol = (void *) GetProcAddress((HMODULE) handle, name); -#endif - if (symbol == NULL) { char errbuf[512]; SDL_strlcpy(errbuf, "Failed loading ", SDL_arraysize(errbuf)); diff --git a/src/eepp/helper/SDL2/src/main/android/SDL_android_main.cpp b/src/eepp/helper/SDL2/src/main/android/SDL_android_main.cpp index 2c5aa5d09..0755683e0 100644 --- a/src/eepp/helper/SDL2/src/main/android/SDL_android_main.cpp +++ b/src/eepp/helper/SDL2/src/main/android/SDL_android_main.cpp @@ -5,7 +5,6 @@ /* Include the SDL main definition header */ #include "SDL_main.h" -#include /******************************************************************************* Functions called by JNI @@ -15,24 +14,20 @@ // Called before SDL_main() to initialize JNI bindings in SDL library extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls); -// Library init -extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - AL_SetJavaVM( vm ); - - return JNI_VERSION_1_4; -} - // Start up the SDL app -extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) +extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jstring apkPath) { /* This interface could expand with ABI negotiation, calbacks, etc. */ SDL_Android_Init(env, cls); + const char* str; + jboolean isCopy; + str = env->GetStringUTFChars(apkPath, &isCopy); + /* Run the application code! */ int status; char *argv[2]; - argv[0] = strdup("SDL_app"); + argv[0] = strdup(str); argv[1] = NULL; status = SDL_main(1, argv); diff --git a/src/eepp/helper/SDL2/src/main/beos/SDL_BApp.h b/src/eepp/helper/SDL2/src/main/beos/SDL_BApp.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/main/beos/SDL_BeApp.cc b/src/eepp/helper/SDL2/src/main/beos/SDL_BeApp.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/main/beos/SDL_BeApp.h b/src/eepp/helper/SDL2/src/main/beos/SDL_BeApp.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/main/windows/SDL_windows_main.c b/src/eepp/helper/SDL2/src/main/windows/SDL_windows_main.c index 4d60e2d4e..f4f78f68c 100644 --- a/src/eepp/helper/SDL2/src/main/windows/SDL_windows_main.c +++ b/src/eepp/helper/SDL2/src/main/windows/SDL_windows_main.c @@ -18,23 +18,16 @@ #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 == '\\') { + if (*arg == '"' && (last != NULL && *last == '\\')) { char *c_curr = arg; char *c_last = last; @@ -130,7 +123,7 @@ OutOfMemory(void) return FALSE; } -#if defined(_MSC_VER) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) /* The VC++ compiler needs main defined */ #define console_main main #endif @@ -153,42 +146,22 @@ console_main(int argc, char *argv[]) /* This is where execution begins [windowed apps] */ int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int sw) +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR 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); + TCHAR *text = GetCommandLine(); +#if UNICODE + cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR)); +#else + cmdline = SDL_strdup(text); +#endif if (cmdline == NULL) { return OutOfMemory(); } - SDL_strlcpy(cmdline, bufp, nLen); -#endif /* Parse it into argv and argc */ argc = ParseCommandLine(cmdline, NULL); @@ -201,6 +174,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int sw) /* Run the main program */ console_main(argc, argv); + SDL_free(cmdline); + /* Hush little compiler, don't you cry... */ return 0; } diff --git a/src/eepp/helper/SDL2/src/power/SDL_power.c b/src/eepp/helper/SDL2/src/power/SDL_power.c old mode 100755 new mode 100644 index 9c6d62b47..ce7725c7c --- a/src/eepp/helper/SDL2/src/power/SDL_power.c +++ b/src/eepp/helper/SDL2/src/power/SDL_power.c @@ -36,6 +36,7 @@ SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_BeOS(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_NintendoDS(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *, int *, int *); +SDL_bool SDL_GetPowerInfo_Android(SDL_PowerState *, int *, int *); #ifndef SDL_POWER_DISABLED #ifdef SDL_POWER_HARDWIRED @@ -73,6 +74,9 @@ static SDL_GetPowerInfo_Impl implementations[] = { #ifdef SDL_POWER_BEOS /* handles BeOS, Zeta, with euc.jp apm driver. */ SDL_GetPowerInfo_BeOS, #endif +#ifdef SDL_POWER_ANDROID /* handles Android. */ + SDL_GetPowerInfo_Android, +#endif #ifdef SDL_POWER_HARDWIRED SDL_GetPowerInfo_Hardwired, #endif diff --git a/src/eepp/helper/SDL2/src/power/beos/SDL_syspower.c b/src/eepp/helper/SDL2/src/power/beos/SDL_syspower.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/power/linux/SDL_syspower.c b/src/eepp/helper/SDL2/src/power/linux/SDL_syspower.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/power/macosx/SDL_syspower.c b/src/eepp/helper/SDL2/src/power/macosx/SDL_syspower.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/power/nds/SDL_syspower.c b/src/eepp/helper/SDL2/src/power/nds/SDL_syspower.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/power/uikit/SDL_syspower.h b/src/eepp/helper/SDL2/src/power/uikit/SDL_syspower.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/power/uikit/SDL_syspower.m b/src/eepp/helper/SDL2/src/power/uikit/SDL_syspower.m old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/power/windows/SDL_syspower.c b/src/eepp/helper/SDL2/src/power/windows/SDL_syspower.c old mode 100755 new mode 100644 index 0ebb56aec..f3c75957a --- a/src/eepp/helper/SDL2/src/power/windows/SDL_syspower.c +++ b/src/eepp/helper/SDL2/src/power/windows/SDL_syspower.c @@ -30,19 +30,11 @@ SDL_bool SDL_GetPowerInfo_Windows(SDL_PowerState * state, int *seconds, int *percent) { -#ifdef _WIN32_WCE - SYSTEM_POWER_STATUS_EX status; -#else SYSTEM_POWER_STATUS status; -#endif SDL_bool need_details = SDL_FALSE; - /* This API should exist back to Win95 and Windows CE. */ -#ifdef _WIN32_WCE - if (!GetSystemPowerStatusEx(&status, FALSE)) -#else + /* This API should exist back to Win95. */ if (!GetSystemPowerStatus(&status)) -#endif { /* !!! FIXME: push GetLastError() into SDL_GetError() */ *state = SDL_POWERSTATE_UNKNOWN; diff --git a/src/eepp/helper/SDL2/src/render/SDL_render.c b/src/eepp/helper/SDL2/src/render/SDL_render.c old mode 100755 new mode 100644 index 168ad61df..01b4aa13b --- a/src/eepp/helper/SDL2/src/render/SDL_render.c +++ b/src/eepp/helper/SDL2/src/render/SDL_render.c @@ -70,6 +70,8 @@ static const SDL_RenderDriver *render_drivers[] = { static char renderer_magic; static char texture_magic; +static int UpdateLogicalSize(SDL_Renderer *renderer); + int SDL_GetNumRenderDrivers(void) { @@ -101,28 +103,30 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) } if (event->window.event == SDL_WINDOWEVENT_RESIZED) { - /* Try to keep the previous viewport centered */ - int w, h; - SDL_Rect viewport; - - SDL_GetWindowSize(window, &w, &h); - if (renderer->target) { - renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2; - renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2; + if (renderer->logical_w) { + /* We'll update the renderer in the SIZE_CHANGED event */ } else { - viewport.x = (w - renderer->viewport.w) / 2; - viewport.y = (h - renderer->viewport.h) / 2; - viewport.w = renderer->viewport.w; - viewport.h = renderer->viewport.h; - SDL_RenderSetViewport(renderer, &viewport); + /* Try to keep the previous viewport centered */ + int w, h; + + SDL_GetWindowSize(window, &w, &h); + if (renderer->target) { + renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2; + renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2; + } else { + renderer->viewport.x = (w - renderer->viewport.w) / 2; + renderer->viewport.y = (h - renderer->viewport.h) / 2; + renderer->UpdateViewport(renderer); + } } renderer->resized = SDL_TRUE; } else if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - int w, h; - SDL_Rect viewport; - - if (!renderer->resized) { + if (renderer->logical_w) { + UpdateLogicalSize(renderer); + } else if (!renderer->resized) { /* Window was programmatically resized, reset viewport */ + int w, h; + SDL_GetWindowSize(window, &w, &h); if (renderer->target) { renderer->viewport_backup.x = 0; @@ -130,14 +134,14 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) renderer->viewport_backup.w = w; renderer->viewport_backup.h = h; } else { - viewport.x = 0; - viewport.y = 0; - viewport.w = w; - viewport.h = h; - SDL_RenderSetViewport(renderer, &viewport); + renderer->viewport.x = 0; + renderer->viewport.y = 0; + renderer->viewport.w = w; + renderer->viewport.h = h; + renderer->UpdateViewport(renderer); } - renderer->resized = SDL_FALSE; } + renderer->resized = SDL_FALSE; } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) { renderer->hidden = SDL_TRUE; } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) { @@ -152,6 +156,21 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) } } } + } else if (event->type == SDL_MOUSEMOTION) { + if (renderer->logical_w) { + event->motion.x -= renderer->viewport.x; + event->motion.y -= renderer->viewport.y; + event->motion.x = (int)(event->motion.x / renderer->scale.x); + event->motion.y = (int)(event->motion.y / renderer->scale.y); + } + } else if (event->type == SDL_MOUSEBUTTONDOWN || + event->type == SDL_MOUSEBUTTONUP) { + if (renderer->logical_w) { + event->button.x -= renderer->viewport.x; + event->button.y -= renderer->viewport.y; + event->button.x = (int)(event->button.x / renderer->scale.x); + event->button.y = (int)(event->button.y / renderer->scale.y); + } } return 0; } @@ -247,6 +266,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) if (renderer) { renderer->magic = &renderer_magic; renderer->window = window; + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED)) { renderer->hidden = SDL_TRUE; @@ -276,6 +297,8 @@ SDL_CreateSoftwareRenderer(SDL_Surface * surface) if (renderer) { renderer->magic = &renderer_magic; + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; SDL_RenderSetViewport(renderer, NULL); } @@ -393,6 +416,19 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int return NULL; } + /* Swap textures to have texture before texture->native in the list */ + texture->native->next = texture->next; + if (texture->native->next) { + texture->native->next->prev = texture->native; + } + texture->prev = texture->native->prev; + if (texture->prev) { + texture->prev->next = texture; + } + texture->native->prev = texture; + texture->next = texture->native; + renderer->textures = texture; + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { texture->yuv = SDL_SW_CreateYUVTexture(format, w, h); if (!texture->yuv) { @@ -546,11 +582,8 @@ int SDL_GetTextureColorMod(SDL_Texture * texture, Uint8 * r, Uint8 * g, Uint8 * b) { - SDL_Renderer *renderer; - CHECK_TEXTURE_MAGIC(texture, -1); - renderer = texture->renderer; if (r) { *r = texture->r; } @@ -863,8 +896,6 @@ SDL_RenderTargetSupported(SDL_Renderer *renderer) int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - SDL_Rect viewport; - if (!SDL_RenderTargetSupported(renderer)) { SDL_Unsupported(); return -1; @@ -881,7 +912,7 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) SDL_SetError("Texture was not created with this renderer"); return -1; } - if (!(texture->access & SDL_TEXTUREACCESS_TARGET)) { + if (texture->access != SDL_TEXTUREACCESS_TARGET) { SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET"); return -1; } @@ -894,6 +925,9 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) if (texture && !renderer->target) { /* Make a backup of the viewport */ renderer->viewport_backup = renderer->viewport; + renderer->scale_backup = renderer->scale; + renderer->logical_w_backup = renderer->logical_w; + renderer->logical_h_backup = renderer->logical_h; } renderer->target = texture; @@ -902,14 +936,21 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) } if (texture) { - viewport.x = 0; - viewport.y = 0; - viewport.w = texture->w; - viewport.h = texture->h; + renderer->viewport.x = 0; + renderer->viewport.y = 0; + renderer->viewport.w = texture->w; + renderer->viewport.h = texture->h; + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; + renderer->logical_w = 0; + renderer->logical_h = 0; } else { - viewport = renderer->viewport_backup; + renderer->viewport = renderer->viewport_backup; + renderer->scale = renderer->scale_backup; + renderer->logical_w = renderer->logical_w_backup; + renderer->logical_h = renderer->logical_h_backup; } - if (SDL_RenderSetViewport(renderer, &viewport) < 0) { + if (renderer->UpdateViewport(renderer) < 0) { return -1; } @@ -917,17 +958,115 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) return 0; } +SDL_Texture * +SDL_GetRenderTarget(SDL_Renderer *renderer) +{ + return renderer->target; +} + +static int +UpdateLogicalSize(SDL_Renderer *renderer) +{ + int w, h; + float want_aspect; + float real_aspect; + float scale; + SDL_Rect viewport; + + if (renderer->target) { + SDL_QueryTexture(renderer->target, NULL, NULL, &w, &h); + } else if (renderer->window) { + SDL_GetWindowSize(renderer->window, &w, &h); + } else { + /* FIXME */ + SDL_SetError("Internal error: No way to get output resolution"); + return -1; + } + + want_aspect = (float)renderer->logical_w / renderer->logical_h; + real_aspect = (float)w / h; + + /* Clear the scale because we're setting viewport in output coordinates */ + SDL_RenderSetScale(renderer, 1.0f, 1.0f); + + if (SDL_fabs(want_aspect-real_aspect) < 0.0001) { + /* The aspect ratios are the same, just scale appropriately */ + scale = (float)w / renderer->logical_w; + SDL_RenderSetViewport(renderer, NULL); + } else if (want_aspect > real_aspect) { + /* We want a wider aspect ratio than is available - letterbox it */ + scale = (float)w / renderer->logical_w; + viewport.x = 0; + viewport.w = w; + viewport.h = (int)SDL_ceil(renderer->logical_h * scale); + viewport.y = (h - viewport.h) / 2; + SDL_RenderSetViewport(renderer, &viewport); + } else { + /* We want a narrower aspect ratio than is available - use side-bars */ + scale = (float)h / renderer->logical_h; + viewport.y = 0; + viewport.h = h; + viewport.w = (int)SDL_ceil(renderer->logical_w * scale); + viewport.x = (w - viewport.w) / 2; + SDL_RenderSetViewport(renderer, &viewport); + } + + /* Set the new scale */ + SDL_RenderSetScale(renderer, scale, scale); + + return 0; +} + +int +SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!w || !h) { + /* Clear any previous logical resolution */ + renderer->logical_w = 0; + renderer->logical_h = 0; + SDL_RenderSetViewport(renderer, NULL); + SDL_RenderSetScale(renderer, 1.0f, 1.0f); + return 0; + } + + renderer->logical_w = w; + renderer->logical_h = h; + + return UpdateLogicalSize(renderer); +} + +void +SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h) +{ + CHECK_RENDERER_MAGIC(renderer, ); + + if (w) { + *w = renderer->logical_w; + } + if (h) { + *h = renderer->logical_h; + } +} + int SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect) { CHECK_RENDERER_MAGIC(renderer, -1); if (rect) { - renderer->viewport = *rect; + renderer->viewport.x = (int)SDL_floor(rect->x * renderer->scale.x); + renderer->viewport.y = (int)SDL_floor(rect->y * renderer->scale.y); + renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x); + renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y); } else { renderer->viewport.x = 0; renderer->viewport.y = 0; - if (renderer->window) { + if (renderer->target) { + SDL_QueryTexture(renderer->target, NULL, NULL, + &renderer->viewport.w, &renderer->viewport.h); + } else if (renderer->window) { SDL_GetWindowSize(renderer->window, &renderer->viewport.w, &renderer->viewport.h); } else { @@ -944,7 +1083,35 @@ SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect) { CHECK_RENDERER_MAGIC(renderer, ); - *rect = renderer->viewport; + if (rect) { + rect->x = (int)(renderer->viewport.x / renderer->scale.x); + rect->y = (int)(renderer->viewport.y / renderer->scale.y); + rect->w = (int)(renderer->viewport.w / renderer->scale.x); + rect->h = (int)(renderer->viewport.h / renderer->scale.y); + } +} + +int +SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + renderer->scale.x = scaleX; + renderer->scale.y = scaleY; + return 0; +} + +void +SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY) +{ + CHECK_RENDERER_MAGIC(renderer, ); + + if (scaleX) { + *scaleX = renderer->scale.x; + } + if (scaleY) { + *scaleY = renderer->scale.y; + } } int @@ -1021,10 +1188,41 @@ SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y) return SDL_RenderDrawPoints(renderer, &point, 1); } +static int +RenderDrawPointsWithRects(SDL_Renderer * renderer, + const SDL_Point * points, int count) +{ + SDL_FRect *frects; + int i; + int status; + + frects = SDL_stack_alloc(SDL_FRect, count); + if (!frects) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + frects[i].x = points[i].x * renderer->scale.x; + frects[i].y = points[i].y * renderer->scale.y; + frects[i].w = renderer->scale.x; + frects[i].h = renderer->scale.y; + } + + status = renderer->RenderFillRects(renderer, frects, count); + + SDL_stack_free(frects); + + return status; +} + int SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { + SDL_FPoint *fpoints; + int i; + int status; + CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { @@ -1038,7 +1236,26 @@ SDL_RenderDrawPoints(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } - return renderer->RenderDrawPoints(renderer, points, count); + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + return RenderDrawPointsWithRects(renderer, points, count); + } + + fpoints = SDL_stack_alloc(SDL_FPoint, count); + if (!fpoints) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + fpoints[i].x = points[i].x * renderer->scale.x; + fpoints[i].y = points[i].y * renderer->scale.y; + } + + status = renderer->RenderDrawPoints(renderer, fpoints, count); + + SDL_stack_free(fpoints); + + return status; } int @@ -1053,10 +1270,71 @@ SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) return SDL_RenderDrawLines(renderer, points, 2); } +static int +RenderDrawLinesWithRects(SDL_Renderer * renderer, + const SDL_Point * points, int count) +{ + SDL_FRect *frect; + SDL_FRect *frects; + SDL_FPoint fpoints[2]; + int i, nrects; + int status; + + frects = SDL_stack_alloc(SDL_FRect, count-1); + if (!frects) { + SDL_OutOfMemory(); + return -1; + } + + status = 0; + nrects = 0; + for (i = 0; i < count-1; ++i) { + if (points[i].x == points[i+1].x) { + int minY = SDL_min(points[i].y, points[i+1].y); + int maxY = SDL_max(points[i].y, points[i+1].y); + + frect = &frects[nrects++]; + frect->x = points[i].x * renderer->scale.x; + frect->y = minY * renderer->scale.y; + frect->w = renderer->scale.x; + frect->h = (maxY - minY + 1) * renderer->scale.y; + } else if (points[i].y == points[i+1].y) { + int minX = SDL_min(points[i].x, points[i+1].x); + int maxX = SDL_max(points[i].x, points[i+1].x); + + frect = &frects[nrects++]; + frect->x = minX * renderer->scale.x; + frect->y = points[i].y * renderer->scale.y; + frect->w = (maxX - minX + 1) * renderer->scale.x; + frect->h = renderer->scale.y; + } else { + /* FIXME: We can't use a rect for this line... */ + frects[0].x = points[i].x * renderer->scale.x; + frects[0].y = points[i].y * renderer->scale.y; + frects[1].x = points[i+1].x * renderer->scale.x; + frects[1].y = points[i+1].y * renderer->scale.y; + status += renderer->RenderDrawLines(renderer, fpoints, 2); + } + } + + status += renderer->RenderFillRects(renderer, frects, nrects); + + SDL_stack_free(frects); + + if (status < 0) { + status = -1; + } + return status; +} + int SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { + SDL_FPoint *fpoints; + int i; + int status; + CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { @@ -1070,7 +1348,26 @@ SDL_RenderDrawLines(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } - return renderer->RenderDrawLines(renderer, points, count); + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + return RenderDrawLinesWithRects(renderer, points, count); + } + + fpoints = SDL_stack_alloc(SDL_FPoint, count); + if (!fpoints) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + fpoints[i].x = points[i].x * renderer->scale.x; + fpoints[i].y = points[i].y * renderer->scale.y; + } + + status = renderer->RenderDrawLines(renderer, fpoints, count); + + SDL_stack_free(fpoints); + + return status; } int @@ -1083,10 +1380,9 @@ SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect) /* If 'rect' == NULL, then outline the whole surface */ if (!rect) { + SDL_RenderGetViewport(renderer, &full_rect); full_rect.x = 0; full_rect.y = 0; - full_rect.w = renderer->viewport.w; - full_rect.h = renderer->viewport.h; rect = &full_rect; } @@ -1140,10 +1436,9 @@ SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect) /* If 'rect' == NULL, then outline the whole surface */ if (!rect) { + SDL_RenderGetViewport(renderer, &full_rect); full_rect.x = 0; full_rect.y = 0; - full_rect.w = renderer->viewport.w; - full_rect.h = renderer->viewport.h; rect = &full_rect; } return SDL_RenderFillRects(renderer, rect, 1); @@ -1153,6 +1448,10 @@ int SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) { + SDL_FRect *frects; + int i; + int status; + CHECK_RENDERER_MAGIC(renderer, -1); if (!rects) { @@ -1166,16 +1465,33 @@ SDL_RenderFillRects(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } - return renderer->RenderFillRects(renderer, rects, count); + + frects = SDL_stack_alloc(SDL_FRect, count); + if (!frects) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + frects[i].x = rects[i].x * renderer->scale.x; + frects[i].y = rects[i].y * renderer->scale.y; + frects[i].w = rects[i].w * renderer->scale.x; + frects[i].h = rects[i].h * renderer->scale.y; + } + + status = renderer->RenderFillRects(renderer, frects, count); + + SDL_stack_free(frects); + + return status; } int SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { - SDL_Window *window; - SDL_Rect real_srcrect; - SDL_Rect real_dstrect; + SDL_Rect real_srcrect = { 0, 0, 0, 0 }; + SDL_Rect real_dstrect = { 0, 0, 0, 0 }; + SDL_FRect frect; CHECK_RENDERER_MAGIC(renderer, -1); CHECK_TEXTURE_MAGIC(texture, -1); @@ -1184,7 +1500,6 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, SDL_SetError("Texture was not created with this renderer"); return -1; } - window = renderer->window; real_srcrect.x = 0; real_srcrect.y = 0; @@ -1196,10 +1511,9 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, } } + SDL_RenderGetViewport(renderer, &real_dstrect); real_dstrect.x = 0; real_dstrect.y = 0; - real_dstrect.w = renderer->viewport.w; - real_dstrect.h = renderer->viewport.h; if (dstrect) { if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) { return 0; @@ -1227,8 +1541,13 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, if (renderer->hidden) { return 0; } - return renderer->RenderCopy(renderer, texture, &real_srcrect, - &real_dstrect); + + frect.x = real_dstrect.x * renderer->scale.x; + frect.y = real_dstrect.y * renderer->scale.y; + frect.w = real_dstrect.w * renderer->scale.x; + frect.h = real_dstrect.h * renderer->scale.y; + + return renderer->RenderCopy(renderer, texture, &real_srcrect, &frect); } @@ -1237,9 +1556,11 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect, const double angle, const SDL_Point *center, const SDL_RendererFlip flip) { - SDL_Window *window; - SDL_Rect real_srcrect, real_dstrect; + SDL_Rect real_srcrect = { 0, 0, 0, 0 }; + SDL_Rect real_dstrect = { 0, 0, 0, 0 }; SDL_Point real_center; + SDL_FRect frect; + SDL_FPoint fcenter; CHECK_RENDERER_MAGIC(renderer, -1); CHECK_TEXTURE_MAGIC(texture, -1); @@ -1253,8 +1574,6 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } - window = renderer->window; - real_srcrect.x = 0; real_srcrect.y = 0; real_srcrect.w = texture->w; @@ -1266,12 +1585,12 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, } /* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */ - if (dstrect) real_dstrect = *dstrect; - else { - real_srcrect.x = 0; - real_srcrect.y = 0; - real_srcrect.w = renderer->viewport.w; - real_srcrect.h = renderer->viewport.h; + if (dstrect) { + real_dstrect = *dstrect; + } else { + SDL_RenderGetViewport(renderer, &real_dstrect); + real_dstrect.x = 0; + real_dstrect.y = 0; } if (texture->native) { @@ -1284,14 +1603,21 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, real_center.y = real_dstrect.h/2; } - return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip); + frect.x = real_dstrect.x * renderer->scale.x; + frect.y = real_dstrect.y * renderer->scale.y; + frect.w = real_dstrect.w * renderer->scale.x; + frect.h = real_dstrect.h * renderer->scale.y; + + fcenter.x = real_center.x * renderer->scale.x; + fcenter.y = real_center.y * renderer->scale.y; + + return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &frect, angle, &fcenter, flip); } int SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { - SDL_Window *window; SDL_Rect real_rect; CHECK_RENDERER_MAGIC(renderer, -1); @@ -1300,10 +1626,9 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_Unsupported(); return -1; } - window = renderer->window; if (!format) { - format = SDL_GetWindowPixelFormat(window); + format = SDL_GetWindowPixelFormat(renderer->window); } real_rect.x = renderer->viewport.x; @@ -1383,7 +1708,9 @@ SDL_DestroyRenderer(SDL_Renderer * renderer) SDL_DestroyTexture(renderer->textures); } - SDL_SetWindowData(renderer->window, SDL_WINDOWRENDERDATA, NULL); + if (renderer->window) { + SDL_SetWindowData(renderer->window, SDL_WINDOWRENDERDATA, NULL); + } /* It's no longer magical... */ renderer->magic = NULL; @@ -1392,4 +1719,32 @@ SDL_DestroyRenderer(SDL_Renderer * renderer) renderer->DestroyRenderer(renderer); } +int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, -1); + renderer = texture->renderer; + if (renderer && renderer->GL_BindTexture) { + return renderer->GL_BindTexture(renderer, texture, texw, texh); + } + + SDL_Unsupported(); + return -1; +} + +int SDL_GL_UnbindTexture(SDL_Texture *texture) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, -1); + renderer = texture->renderer; + if (renderer && renderer->GL_UnbindTexture) { + return renderer->GL_UnbindTexture(renderer, texture); + } + + SDL_Unsupported(); + return -1; +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/render/SDL_sysrender.h b/src/eepp/helper/SDL2/src/render/SDL_sysrender.h old mode 100755 new mode 100644 index 0a54ff72b..dff297f5e --- a/src/eepp/helper/SDL2/src/render/SDL_sysrender.h +++ b/src/eepp/helper/SDL2/src/render/SDL_sysrender.h @@ -31,6 +31,20 @@ typedef struct SDL_RenderDriver SDL_RenderDriver; +typedef struct +{ + float x; + float y; +} SDL_FPoint; + +typedef struct +{ + float x; + float y; + float w; + float h; +} SDL_FRect; + /* Define the SDL texture structure */ struct SDL_Texture { @@ -80,17 +94,17 @@ struct SDL_Renderer int (*SetRenderTarget) (SDL_Renderer * renderer, SDL_Texture * texture); int (*UpdateViewport) (SDL_Renderer * renderer); int (*RenderClear) (SDL_Renderer * renderer); - int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points, + int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_FPoint * points, int count); - int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_Point * points, + int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_FPoint * points, int count); - int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect * rects, + int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_FRect * rects, int count); int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); int (*RenderCopyEx) (SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); + const SDL_Rect * srcquad, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); void (*RenderPresent) (SDL_Renderer * renderer); @@ -98,6 +112,9 @@ struct SDL_Renderer void (*DestroyRenderer) (SDL_Renderer * renderer); + int (*GL_BindTexture) (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh); + int (*GL_UnbindTexture) (SDL_Renderer * renderer, SDL_Texture *texture); + /* The current renderer info */ SDL_RendererInfo info; @@ -106,10 +123,20 @@ struct SDL_Renderer SDL_bool hidden; SDL_bool resized; + /* The logical resolution for rendering */ + int logical_w; + int logical_h; + int logical_w_backup; + int logical_h_backup; + /* The drawable area within the window */ SDL_Rect viewport; SDL_Rect viewport_backup; + /* The render output coordinate scale */ + SDL_FPoint scale; + SDL_FPoint scale_backup; + /* The list of textures */ SDL_Texture *textures; SDL_Texture *target; diff --git a/src/eepp/helper/SDL2/src/render/SDL_yuv_mmx.c b/src/eepp/helper/SDL2/src/render/SDL_yuv_mmx.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/SDL_yuv_sw.c b/src/eepp/helper/SDL2/src/render/SDL_yuv_sw.c old mode 100755 new mode 100644 index 2f8172d13..bde5de11b --- a/src/eepp/helper/SDL2/src/render/SDL_yuv_sw.c +++ b/src/eepp/helper/SDL2/src/render/SDL_yuv_sw.c @@ -1044,6 +1044,7 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) case SDL_PIXELFORMAT_YVYU: break; default: + SDL_SW_DestroyYUVTexture(swdata); SDL_SetError("Unsupported YUV format"); return NULL; } diff --git a/src/eepp/helper/SDL2/src/render/SDL_yuv_sw_c.h b/src/eepp/helper/SDL2/src/render/SDL_yuv_sw_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/direct3d/SDL_render_d3d.c b/src/eepp/helper/SDL2/src/render/direct3d/SDL_render_d3d.c old mode 100755 new mode 100644 index b0d8b4bc2..0ebb7474f --- a/src/eepp/helper/SDL2/src/render/direct3d/SDL_render_d3d.c +++ b/src/eepp/helper/SDL2/src/render/direct3d/SDL_render_d3d.c @@ -188,16 +188,16 @@ static int D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int D3D_UpdateViewport(SDL_Renderer * renderer); static int D3D_RenderClear(SDL_Renderer * renderer); static int D3D_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int D3D_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int D3D_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip); static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); static void D3D_RenderPresent(SDL_Renderer * renderer); @@ -682,8 +682,6 @@ static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - D3DFORMAT display_format = renderdata->pparams.BackBufferFormat; D3D_TextureData *data; D3DPOOL pool; DWORD usage; @@ -731,7 +729,6 @@ 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; RECT d3drect; D3DLOCKED_RECT locked; const Uint8 *src; @@ -966,7 +963,7 @@ D3D_SetBlendMode(D3D_RenderData * data, int blendMode) } static int -D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; @@ -993,8 +990,8 @@ D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, 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].x = points[i].x; + vertices[i].y = points[i].y; vertices[i].z = 0.0f; vertices[i].color = color; vertices[i].u = 0.0f; @@ -1012,7 +1009,7 @@ D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, } static int -D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; @@ -1039,8 +1036,8 @@ D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, 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].x = points[i].x; + vertices[i].y = points[i].y; vertices[i].z = 0.0f; vertices[i].color = color; vertices[i].u = 0.0f; @@ -1054,8 +1051,8 @@ D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, so we need to close the endpoint of the line */ if (count == 2 || 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; + vertices[0].x = points[count-1].x; + vertices[0].y = points[count-1].y; result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices)); } @@ -1068,7 +1065,7 @@ D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, } static int -D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, +D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; @@ -1095,12 +1092,12 @@ D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); for (i = 0; i < count; ++i) { - const SDL_Rect *rect = &rects[i]; + const SDL_FRect *rect = &rects[i]; - minx = (float) rect->x; - miny = (float) rect->y; - maxx = (float) rect->x + rect->w; - maxy = (float) rect->y + rect->h; + minx = rect->x; + miny = rect->y; + maxx = rect->x + rect->w; + maxy = rect->y + rect->h; vertices[0].x = minx; vertices[0].y = miny; @@ -1143,7 +1140,7 @@ D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; @@ -1158,10 +1155,10 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } - 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; + minx = dstrect->x - 0.5f; + miny = dstrect->y - 0.5f; + maxx = dstrect->x + dstrect->w - 0.5f; + maxy = dstrect->y + dstrect->h - 0.5f; minu = (float) srcrect->x / texture->w; maxu = (float) (srcrect->x + srcrect->w) / texture->w; @@ -1242,8 +1239,8 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, static int D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; @@ -1259,25 +1256,25 @@ D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } - centerx = (float)center->x; - centery = (float)center->y; + centerx = center->x; + centery = center->y; if (flip & SDL_FLIP_HORIZONTAL) { - minx = (float) dstrect->w - centerx - 0.5f; - maxx = (float) -centerx - 0.5f; + minx = dstrect->w - centerx - 0.5f; + maxx = -centerx - 0.5f; } else { - minx = (float) -centerx - 0.5f; - maxx = (float) dstrect->w - centerx - 0.5f; + minx = -centerx - 0.5f; + maxx = dstrect->w - centerx - 0.5f; } if (flip & SDL_FLIP_VERTICAL) { - miny = (float) dstrect->h - centery - 0.5f; - maxy = (float) -centery - 0.5f; + miny = dstrect->h - centery - 0.5f; + maxy = -centery - 0.5f; } else { - miny = (float) -centery - 0.5f; - maxy = (float) dstrect->h - centery - 0.5f; + miny = -centery - 0.5f; + maxy = dstrect->h - centery - 0.5f; } minu = (float) srcrect->x / texture->w; @@ -1320,7 +1317,7 @@ D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, // Rotate and translate ID3DXMatrixStack_Push(data->matrixStack); ID3DXMatrixStack_LoadIdentity(data->matrixStack); - ID3DXMatrixStack_RotateYawPitchRoll(data->matrixStack, 0.0, 0.0, M_PI * (float) angle / 180.0f); + ID3DXMatrixStack_RotateYawPitchRoll(data->matrixStack, 0.0, 0.0, (float)(M_PI * (float) angle / 180.0f)); ID3DXMatrixStack_Translate(data->matrixStack, (float)dstrect->x + centerx, (float)dstrect->y + centery, (float)0.0); IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)ID3DXMatrixStack_GetTop(data->matrixStack)); diff --git a/src/eepp/helper/SDL2/src/render/nds/SDL_ndsrender.c b/src/eepp/helper/SDL2/src/render/nds/SDL_ndsrender.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/opengl/SDL_glfuncs.h b/src/eepp/helper/SDL2/src/render/opengl/SDL_glfuncs.h index ea3644ac1..03ee6b932 100644 --- a/src/eepp/helper/SDL2/src/render/opengl/SDL_glfuncs.h +++ b/src/eepp/helper/SDL2/src/render/opengl/SDL_glfuncs.h @@ -322,10 +322,10 @@ SDL_PROC(void, glReadPixels, SDL_PROC_UNUSED(void, glRectd, (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) SDL_PROC_UNUSED(void, glRectdv, (const GLdouble * v1, const GLdouble * v2)) -SDL_PROC_UNUSED(void, glRectf, +SDL_PROC(void, glRectf, (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) SDL_PROC_UNUSED(void, glRectfv, (const GLfloat * v1, const GLfloat * v2)) -SDL_PROC(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2)) +SDL_PROC_UNUSED(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2)) SDL_PROC_UNUSED(void, glRectiv, (const GLint * v1, const GLint * v2)) SDL_PROC_UNUSED(void, glRects, (GLshort x1, GLshort y1, GLshort x2, GLshort y2)) diff --git a/src/eepp/helper/SDL2/src/render/opengl/SDL_render_gl.c b/src/eepp/helper/SDL2/src/render/opengl/SDL_render_gl.c old mode 100755 new mode 100644 index 34c4b0c2d..9ec7115a0 --- a/src/eepp/helper/SDL2/src/render/opengl/SDL_render_gl.c +++ b/src/eepp/helper/SDL2/src/render/opengl/SDL_render_gl.c @@ -58,22 +58,23 @@ static int GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int GL_UpdateViewport(SDL_Renderer * renderer); static int GL_RenderClear(SDL_Renderer * renderer); static int GL_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GL_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GL_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); static void GL_RenderPresent(SDL_Renderer * renderer); static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); static void GL_DestroyRenderer(SDL_Renderer * renderer); - +static int GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh); +static int GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture); SDL_RenderDriver GL_RenderDriver = { GL_CreateRenderer, @@ -149,43 +150,53 @@ typedef struct GL_FBOList *fbo; } GL_TextureData; - -static void -GL_SetError(const char *prefix, GLenum result) +static __inline__ const char* +GL_TranslateError (GLenum error) { - const char *error; - - switch (result) { - case GL_NO_ERROR: - error = "GL_NO_ERROR"; - break; - case GL_INVALID_ENUM: - error = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - error = "GL_INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - error = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - error = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - error = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - error = "GL_OUT_OF_MEMORY"; - break; - case GL_TABLE_TOO_LARGE: - error = "GL_TABLE_TOO_LARGE"; - break; +#define GL_ERROR_TRANSLATE(e) case e: return #e; + switch (error) { + GL_ERROR_TRANSLATE(GL_INVALID_ENUM) + GL_ERROR_TRANSLATE(GL_INVALID_VALUE) + GL_ERROR_TRANSLATE(GL_INVALID_OPERATION) + GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY) + GL_ERROR_TRANSLATE(GL_NO_ERROR) + GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW) + GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW) + GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE) default: - error = "UNKNOWN"; - break; - } - SDL_SetError("%s: %s", prefix, error); + return "UNKNOWN"; } +#undef GL_ERROR_TRANSLATE +} + +static __inline__ int +GL_CheckAllErrors (const char *prefix, SDL_Renderer * renderer, const char *file, int line, const char *function) +{ + GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + int ret = 0; + /* check gl errors (can return multiple errors) */ + for (;;) { + GLenum error = data->glGetError(); + if (error != GL_NO_ERROR) { + if (prefix == NULL || prefix[0] == '\0') { + prefix = "generic"; + } + SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error); + ret++; + } else { + break; + } + } + return ret; +} + +#if 0 +#define GL_CheckError(prefix, renderer) +#elif defined(_MSC_VER) +#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __FUNCTION__) +#else +#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#endif static int GL_LoadFunctions(GL_RenderData * data) @@ -249,6 +260,8 @@ GL_ResetState(SDL_Renderer *renderer) data->glMatrixMode(GL_MODELVIEW); data->glLoadIdentity(); + + GL_CheckError("", renderer); } @@ -322,6 +335,8 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderPresent = GL_RenderPresent; renderer->DestroyTexture = GL_DestroyTexture; renderer->DestroyRenderer = GL_DestroyRenderer; + renderer->GL_BindTexture = GL_BindTexture; + renderer->GL_UnbindTexture = GL_UnbindTexture; renderer->info = GL_RenderDriver.info; renderer->info.flags = SDL_RENDERER_ACCELERATED; renderer->driverdata = data; @@ -358,14 +373,16 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } - data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); - renderer->info.max_texture_width = value; - data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); - renderer->info.max_texture_height = value; - if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) { data->GL_ARB_texture_rectangle_supported = SDL_TRUE; + data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value); + renderer->info.max_texture_width = value; + renderer->info.max_texture_height = value; + } else { + data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + renderer->info.max_texture_width = value; + renderer->info.max_texture_height = value; } /* Check for multitexture support */ @@ -478,7 +495,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLenum format, type; int texture_w, texture_h; GLenum scaleMode; - GLenum result; GL_ActivateRenderer(renderer); @@ -520,7 +536,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->fbo = NULL; } - renderdata->glGetError(); + GL_CheckError("", renderer); renderdata->glGenTextures(1, &data->texture); if ((renderdata->GL_ARB_texture_rectangle_supported) /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){ @@ -588,9 +604,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture_h, 0, format, type, NULL); } renderdata->glDisable(data->type); - result = renderdata->glGetError(); - if (result != GL_NO_ERROR) { - GL_SetError("glTexImage2D()", result); + if (GL_CheckError("glTexImage2D()", renderer) > 0) { return -1; } @@ -628,6 +642,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) renderdata->glDisable(data->type); } + + GL_CheckError("", renderer); return 0; } @@ -637,11 +653,10 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, { GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; GL_TextureData *data = (GL_TextureData *) texture->driverdata; - GLenum result; GL_ActivateRenderer(renderer); - renderdata->glGetError(); + GL_CheckError("", renderer); renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->texture); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -676,9 +691,7 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, data->format, data->formattype, pixels); } renderdata->glDisable(data->type); - result = renderdata->glGetError(); - if (result != GL_NO_ERROR) { - GL_SetError("glTexSubImage2D()", result); + if (GL_CheckError("glTexSubImage2D()", renderer) > 0) { return -1; } return 0; @@ -749,6 +762,11 @@ GL_UpdateViewport(SDL_Renderer * renderer) return 0; } + if (!renderer->viewport.w || !renderer->viewport.h) { + /* The viewport isn't set up yet, ignore it */ + return -1; + } + data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h); @@ -767,6 +785,7 @@ GL_UpdateViewport(SDL_Renderer * renderer) (GLdouble) 0, 0.0, 1.0); } + GL_CheckError("", renderer); return 0; } @@ -857,7 +876,7 @@ GL_RenderClear(SDL_Renderer * renderer) } static int -GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; @@ -875,7 +894,7 @@ GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, } static int -GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; @@ -934,12 +953,13 @@ GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, #endif data->glEnd(); } + GL_CheckError("", renderer); return 0; } static int -GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) +GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; int i; @@ -947,21 +967,22 @@ GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) GL_SetDrawingState(renderer); for (i = 0; i < count; ++i) { - const SDL_Rect *rect = &rects[i]; + const SDL_FRect *rect = &rects[i]; - data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); + data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); } + GL_CheckError("", renderer); return 0; } static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - int minx, miny, maxx, maxy; + GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; GL_ActivateRenderer(renderer); @@ -1008,24 +1029,26 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, data->glBegin(GL_TRIANGLE_STRIP); data->glTexCoord2f(minu, minv); - data->glVertex2f((GLfloat) minx, (GLfloat) miny); + data->glVertex2f(minx, miny); data->glTexCoord2f(maxu, minv); - data->glVertex2f((GLfloat) maxx, (GLfloat) miny); + data->glVertex2f(maxx, miny); data->glTexCoord2f(minu, maxv); - data->glVertex2f((GLfloat) minx, (GLfloat) maxy); + data->glVertex2f(minx, maxy); data->glTexCoord2f(maxu, maxv); - data->glVertex2f((GLfloat) maxx, (GLfloat) maxy); + data->glVertex2f(maxx, maxy); data->glEnd(); data->glDisable(texturedata->type); + GL_CheckError("", renderer); + return 0; } static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; @@ -1060,25 +1083,25 @@ GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GL_SetShader(data, SHADER_RGB); } - centerx = (GLfloat)center->x; - centery = (GLfloat)center->y; + centerx = center->x; + centery = center->y; if (flip & SDL_FLIP_HORIZONTAL) { - minx = (GLfloat) dstrect->w - centerx; + minx = dstrect->w - centerx; maxx = -centerx; } else { minx = -centerx; - maxx = (GLfloat) dstrect->w - centerx; + maxx = dstrect->w - centerx; } if (flip & SDL_FLIP_VERTICAL) { - miny = (GLfloat) dstrect->h - centery; + miny = dstrect->h - centery; maxy = -centery; } else { miny = -centery; - maxy = (GLfloat) dstrect->h - centery; + maxy = dstrect->h - centery; } minu = (GLfloat) srcrect->x / texture->w; @@ -1109,6 +1132,8 @@ GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, data->glDisable(texturedata->type); + GL_CheckError("", renderer); + return 0; } @@ -1147,6 +1172,8 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, format, type, temp_pixels); + GL_CheckError("", renderer); + /* Flip the rows to be top-down */ length = rect->w * SDL_BYTESPERPIXEL(temp_format); src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; @@ -1217,6 +1244,7 @@ GL_DestroyRenderer(SDL_Renderer * renderer) GL_FBOList *nextnode = data->framebuffers->next; /* delete the framebuffer object */ data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO); + GL_CheckError("", renderer); SDL_free(data->framebuffers); data->framebuffers = nextnode; } @@ -1228,6 +1256,49 @@ GL_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } +static int GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) { + GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; + GL_ActivateRenderer(renderer); + + data->glEnable(texturedata->type); + if (texturedata->yuv) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + data->glBindTexture(texturedata->type, texturedata->vtexture); + + data->glActiveTextureARB(GL_TEXTURE1_ARB); + data->glBindTexture(texturedata->type, texturedata->utexture); + + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } + data->glBindTexture(texturedata->type, texturedata->texture); + + if(texw) *texw = (float)texturedata->texw; + if(texh) *texh = (float)texturedata->texh; + + return 0; +} + +static int GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) { + GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; + GL_ActivateRenderer(renderer); + + if (texturedata->yuv) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + data->glDisable(texturedata->type); + + data->glActiveTextureARB(GL_TEXTURE1_ARB); + data->glDisable(texturedata->type); + + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } + + data->glDisable(texturedata->type); + + return 0; +} + #endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/render/opengl/SDL_shaders_gl.c b/src/eepp/helper/SDL2/src/render/opengl/SDL_shaders_gl.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/opengl/SDL_shaders_gl.h b/src/eepp/helper/SDL2/src/render/opengl/SDL_shaders_gl.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/opengles/SDL_glesfuncs.h b/src/eepp/helper/SDL2/src/render/opengles/SDL_glesfuncs.h index aab15a18a..aade01229 100644 --- a/src/eepp/helper/SDL2/src/render/opengles/SDL_glesfuncs.h +++ b/src/eepp/helper/SDL2/src/render/opengles/SDL_glesfuncs.h @@ -7,7 +7,7 @@ SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *)) SDL_PROC(void, glDisable, (GLenum)) SDL_PROC(void, glDisableClientState, (GLenum array)) SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei)) -SDL_PROC(void, glDrawTexiOES, (GLint, GLint, GLint, GLint, GLint)) +SDL_PROC(void, glDrawTexfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) SDL_PROC(void, glEnable, (GLenum)) SDL_PROC(void, glEnableClientState, (GLenum)) SDL_PROC(void, glFinish, (void)) diff --git a/src/eepp/helper/SDL2/src/render/opengles/SDL_render_gles.c b/src/eepp/helper/SDL2/src/render/opengles/SDL_render_gles.c old mode 100755 new mode 100644 index 51a12e8dc..e2612f366 --- a/src/eepp/helper/SDL2/src/render/opengles/SDL_render_gles.c +++ b/src/eepp/helper/SDL2/src/render/opengles/SDL_render_gles.c @@ -61,23 +61,25 @@ static int GLES_SetRenderTarget(SDL_Renderer * renderer, static int GLES_UpdateViewport(SDL_Renderer * renderer); static int GLES_RenderClear(SDL_Renderer * renderer); static int GLES_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GLES_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GLES_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, - const SDL_Rect * dstrect); + const SDL_FRect * dstrect); +static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); -static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); static void GLES_RenderPresent(SDL_Renderer * renderer); static void GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); static void GLES_DestroyRenderer(SDL_Renderer * renderer); +static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh); +static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture); typedef struct GLES_FBOList GLES_FBOList; @@ -269,6 +271,7 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) GLint value; Uint32 windowFlags; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); @@ -306,11 +309,13 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderDrawLines = GLES_RenderDrawLines; renderer->RenderFillRects = GLES_RenderFillRects; renderer->RenderCopy = GLES_RenderCopy; - renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderCopyEx = GLES_RenderCopyEx; + renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderPresent = GLES_RenderPresent; renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyRenderer = GLES_DestroyRenderer; + renderer->GL_BindTexture = GLES_BindTexture; + renderer->GL_UnbindTexture = GLES_UnbindTexture; renderer->info = GLES_RenderDriver.info; renderer->info.flags = SDL_RENDERER_ACCELERATED; renderer->driverdata = data; @@ -727,43 +732,28 @@ GLES_RenderClear(SDL_Renderer * renderer) } static int -GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - int i; - GLshort *vertices; GLES_SetDrawingState(renderer); - vertices = SDL_stack_alloc(GLshort, count*2); - for (i = 0; i < count; ++i) { - vertices[2*i+0] = (GLshort)points[i].x; - vertices[2*i+1] = (GLshort)points[i].y; - } - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, points); data->glDrawArrays(GL_POINTS, 0, count); - SDL_stack_free(vertices); return 0; } static int -GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - int i; - GLshort *vertices; GLES_SetDrawingState(renderer); - vertices = SDL_stack_alloc(GLshort, count*2); - for (i = 0; i < count; ++i) { - vertices[2*i+0] = (GLshort)points[i].x; - vertices[2*i+1] = (GLshort)points[i].y; - } - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, points); if (count > 2 && points[0].x == points[count-1].x && points[0].y == points[count-1].y) { /* GL_LINE_LOOP takes care of the final segment */ @@ -774,13 +764,12 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, /* We need to close the endpoint of the line */ data->glDrawArrays(GL_POINTS, count-1, 1); } - SDL_stack_free(vertices); return 0; } static int -GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, +GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; @@ -789,12 +778,12 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, GLES_SetDrawingState(renderer); for (i = 0; i < count; ++i) { - const SDL_Rect *rect = &rects[i]; - GLshort minx = rect->x; - GLshort maxx = rect->x + rect->w; - GLshort miny = rect->y; - GLshort maxy = rect->y + rect->h; - GLshort vertices[8]; + const SDL_FRect *rect = &rects[i]; + GLfloat minx = rect->x; + GLfloat maxx = rect->x + rect->w; + GLfloat miny = rect->y; + GLfloat maxy = rect->y + rect->h; + GLfloat vertices[8]; vertices[0] = minx; vertices[1] = miny; vertices[2] = maxx; @@ -804,7 +793,7 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, vertices[6] = maxx; vertices[7] = maxy; - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, vertices); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -813,12 +802,12 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - int minx, miny, maxx, maxy; + GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; GLES_ActivateRenderer(renderer); @@ -851,7 +840,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, cropRect[3] = srcrect->h; data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - data->glDrawTexiOES(renderer->viewport.x + dstrect->x, renderer->viewport.y + dstrect->y, 0, + data->glDrawTexfOES(renderer->viewport.x + dstrect->x, renderer->viewport.y + dstrect->y, 0, dstrect->w, dstrect->h); } else { cropRect[0] = srcrect->x; @@ -860,7 +849,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, cropRect[3] = -srcrect->h; data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - data->glDrawTexiOES(renderer->viewport.x + dstrect->x, + data->glDrawTexfOES(renderer->viewport.x + dstrect->x, h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0, dstrect->w, dstrect->h); } @@ -880,7 +869,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; maxv *= texturedata->texh; - GLshort vertices[8]; + GLfloat vertices[8]; GLfloat texCoords[8]; vertices[0] = minx; @@ -901,7 +890,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, texCoords[6] = maxu; texCoords[7] = maxv; - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, vertices); data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -910,6 +899,96 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } +static int +GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) +{ + + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; + GLfloat minx, miny, maxx, maxy; + GLfloat minu, maxu, minv, maxv; + GLfloat centerx, centery; + + GLES_ActivateRenderer(renderer); + + data->glEnable(GL_TEXTURE_2D); + + data->glBindTexture(texturedata->type, texturedata->texture); + + if (texture->modMode) { + GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a); + } else { + GLES_SetColor(data, 255, 255, 255, 255); + } + + GLES_SetBlendMode(data, texture->blendMode); + + GLES_SetTexCoords(data, SDL_TRUE); + + centerx = center->x; + centery = center->y; + + // Rotate and translate + data->glPushMatrix(); + data->glTranslatef(dstrect->x + centerx, dstrect->y + centery, 0.0f); + data->glRotatef((GLfloat)angle, 0.0f, 0.0f, 1.0f); + + if (flip & SDL_FLIP_HORIZONTAL) { + minx = dstrect->w - centerx; + maxx = -centerx; + } else { + minx = -centerx; + maxx = dstrect->w - centerx; + } + + if (flip & SDL_FLIP_VERTICAL) { + miny = dstrect->h - centery; + maxy = -centery; + } else { + miny = -centery; + maxy = dstrect->h - centery; + } + + minu = (GLfloat) srcrect->x / texture->w; + minu *= texturedata->texw; + maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; + maxu *= texturedata->texw; + minv = (GLfloat) srcrect->y / texture->h; + minv *= texturedata->texh; + maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; + maxv *= texturedata->texh; + + GLfloat vertices[8]; + GLfloat texCoords[8]; + + vertices[0] = minx; + vertices[1] = miny; + vertices[2] = maxx; + vertices[3] = miny; + vertices[4] = minx; + vertices[5] = maxy; + vertices[6] = maxx; + vertices[7] = maxy; + + texCoords[0] = minu; + texCoords[1] = minv; + texCoords[2] = maxu; + texCoords[3] = minv; + texCoords[4] = minu; + texCoords[5] = maxv; + texCoords[6] = maxu; + texCoords[7] = maxv; + data->glVertexPointer(2, GL_FLOAT, 0, vertices); + data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + data->glPopMatrix(); + data->glDisable(GL_TEXTURE_2D); + + return 0; +} + static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) @@ -962,98 +1041,6 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return status; } -static int -GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip) -{ - - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - int minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat centerx, centery; - - GLES_ActivateRenderer(renderer); - - data->glEnable(GL_TEXTURE_2D); - - data->glBindTexture(texturedata->type, texturedata->texture); - - if (texture->modMode) { - GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a); - } else { - GLES_SetColor(data, 255, 255, 255, 255); - } - - GLES_SetBlendMode(data, texture->blendMode); - - GLES_SetTexCoords(data, SDL_TRUE); - - centerx = (GLfloat)center->x; - centery = (GLfloat)center->y; - - // Rotate and translate - data->glPushMatrix(); - data->glTranslatef((GLfloat)dstrect->x + centerx, (GLfloat)dstrect->y + centery, (GLfloat)0.0); - data->glRotatef((GLfloat)angle, (GLfloat)0.0, (GLfloat)0.0, (GLfloat)1.0); - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = (GLfloat) dstrect->w - centerx; - maxx = -centerx; - } - else { - minx = -centerx; - maxx = dstrect->w - centerx; - } - - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->h - centery; - maxy = -centery; - } - else { - miny = -centery; - maxy = dstrect->h - centery; - } - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - GLshort vertices[8]; - GLfloat texCoords[8]; - - vertices[0] = minx; - vertices[1] = miny; - vertices[2] = maxx; - vertices[3] = miny; - vertices[4] = minx; - vertices[5] = maxy; - vertices[6] = maxx; - vertices[7] = maxy; - - texCoords[0] = minu; - texCoords[1] = minv; - texCoords[2] = maxu; - texCoords[3] = minv; - texCoords[4] = minu; - texCoords[5] = maxv; - texCoords[6] = maxu; - texCoords[7] = maxv; - data->glVertexPointer(2, GL_SHORT, 0, vertices); - data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - data->glPopMatrix(); - data->glDisable(GL_TEXTURE_2D); - - return 0; -} - static void GLES_RenderPresent(SDL_Renderer * renderer) { @@ -1104,6 +1091,30 @@ GLES_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } +static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; + GLES_ActivateRenderer(renderer); + + data->glEnable(GL_TEXTURE_2D); + data->glBindTexture(texturedata->type, texturedata->texture); + + if(texw) *texw = (float)texturedata->texw; + if(texh) *texh = (float)texturedata->texh; + + return 0; +} + +static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) { + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; + GLES_ActivateRenderer(renderer); + data->glDisable(texturedata->type); + + return 0; +} + + #endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/render/opengles2/SDL_render_gles2.c b/src/eepp/helper/SDL2/src/render/opengles2/SDL_render_gles2.c old mode 100755 new mode 100644 index 946f1eeca..69b0aab8c --- a/src/eepp/helper/SDL2/src/render/opengles2/SDL_render_gles2.c +++ b/src/eepp/helper/SDL2/src/render/opengles2/SDL_render_gles2.c @@ -833,7 +833,7 @@ GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendM break; case GLES2_IMAGESOURCE_TEXTURE_ABGR: ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC; - break; + break; case GLES2_IMAGESOURCE_TEXTURE_ARGB: ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC; break; @@ -906,15 +906,23 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer) projection[0][2] = 0.0f; projection[0][3] = 0.0f; projection[1][0] = 0.0f; - projection[1][1] = -2.0f / renderer->viewport.h; + if (renderer->target) { + projection[1][1] = 2.0f / renderer->viewport.h; + } else { + projection[1][1] = -2.0f / renderer->viewport.h; + } projection[1][2] = 0.0f; projection[1][3] = 0.0f; projection[2][0] = 0.0f; projection[2][1] = 0.0f; - projection[2][2] = 1.0f; + projection[2][2] = 0.0f; projection[2][3] = 0.0f; projection[3][0] = -1.0f; - projection[3][1] = 1.0f; + if (renderer->target) { + projection[3][1] = -1.0f; + } else { + projection[3][1] = 1.0f; + } projection[3][2] = 0.0f; projection[3][3] = 1.0f; @@ -937,16 +945,16 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer) static const float inv255f = 1.0f / 255.0f; static int GLES2_RenderClear(SDL_Renderer *renderer); -static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count); -static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count); -static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count); +static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count); +static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count); +static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count); static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, - const SDL_Rect *dstrect); + const SDL_FRect *dstrect); static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); static int GLES2_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static void GLES2_RenderPresent(SDL_Renderer *renderer); @@ -1027,16 +1035,26 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) /* Select the color to draw with */ locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR]; - rdata->glUniform4f(locColor, - renderer->r * inv255f, - renderer->g * inv255f, - renderer->b * inv255f, - renderer->a * inv255f); + if (renderer->target && + (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || + renderer->target->format == SDL_PIXELFORMAT_RGB888)) { + rdata->glUniform4f(locColor, + renderer->b * inv255f, + renderer->g * inv255f, + renderer->r * inv255f, + renderer->a * inv255f); + } else { + rdata->glUniform4f(locColor, + renderer->r * inv255f, + renderer->g * inv255f, + renderer->b * inv255f, + renderer->a * inv255f); + } return 0; } static int -GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count) +GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat *vertices; @@ -1050,8 +1068,8 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun vertices = SDL_stack_alloc(GLfloat, count * 2); for (idx = 0; idx < count; ++idx) { - GLfloat x = (GLfloat)points[idx].x + 0.5f; - GLfloat y = (GLfloat)points[idx].y + 0.5f; + GLfloat x = points[idx].x + 0.5f; + GLfloat y = points[idx].y + 0.5f; vertices[idx * 2] = x; vertices[(idx * 2) + 1] = y; @@ -1069,7 +1087,7 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun } static int -GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count) +GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat *vertices; @@ -1083,8 +1101,8 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count vertices = SDL_stack_alloc(GLfloat, count * 2); for (idx = 0; idx < count; ++idx) { - GLfloat x = (GLfloat)points[idx].x + 0.5f; - GLfloat y = (GLfloat)points[idx].y + 0.5f; + GLfloat x = points[idx].x + 0.5f; + GLfloat y = points[idx].y + 0.5f; vertices[idx * 2] = x; vertices[(idx * 2) + 1] = y; @@ -1108,7 +1126,7 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count } static int -GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) +GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat vertices[8]; @@ -1121,12 +1139,12 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) /* Emit a line loop for each rectangle */ rdata->glGetError(); for (idx = 0; idx < count; ++idx) { - const SDL_Rect *rect = &rects[idx]; + const SDL_FRect *rect = &rects[idx]; - GLfloat xMin = (GLfloat)rect->x; - GLfloat xMax = (GLfloat)(rect->x + rect->w); - GLfloat yMin = (GLfloat)rect->y; - GLfloat yMax = (GLfloat)(rect->y + rect->h); + GLfloat xMin = rect->x; + GLfloat xMax = (rect->x + rect->w); + GLfloat yMin = rect->y; + GLfloat yMax = (rect->y + rect->h); vertices[0] = xMin; vertices[1] = yMin; @@ -1149,7 +1167,7 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, - const SDL_Rect *dstrect) + const SDL_FRect *dstrect) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1162,175 +1180,6 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s GLES2_ActivateRenderer(renderer); - /* Activate an appropriate shader and set the projection matrix */ - blendMode = texture->blendMode; - if (renderer->target) { - /* Check if we need to do color mapping between the source and render target textures */ - if (renderer->target->format != texture->format) { - switch (texture->format) - { - case SDL_PIXELFORMAT_ABGR8888: - switch (renderer->target->format) - { - case SDL_PIXELFORMAT_ARGB8888: - case SDL_PIXELFORMAT_RGB888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - case SDL_PIXELFORMAT_BGR888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; - break; - } - break; - case SDL_PIXELFORMAT_ARGB8888: - switch (renderer->target->format) - { - case SDL_PIXELFORMAT_ABGR8888: - case SDL_PIXELFORMAT_BGR888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - case SDL_PIXELFORMAT_RGB888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; - break; - } - break; - case SDL_PIXELFORMAT_BGR888: - switch (renderer->target->format) - { - case SDL_PIXELFORMAT_ABGR8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; - break; - case SDL_PIXELFORMAT_ARGB8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; - break; - case SDL_PIXELFORMAT_RGB888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - } - break; - case SDL_PIXELFORMAT_RGB888: - switch (renderer->target->format) - { - case SDL_PIXELFORMAT_ABGR8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - case SDL_PIXELFORMAT_ARGB8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; - break; - case SDL_PIXELFORMAT_BGR888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - } - break; - } - } - else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; // Texture formats match, use the non color mapping shader (even if the formats are not ABGR) - } - else { - switch (texture->format) - { - case SDL_PIXELFORMAT_ABGR8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; - break; - case SDL_PIXELFORMAT_ARGB8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - case SDL_PIXELFORMAT_BGR888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; - break; - case SDL_PIXELFORMAT_RGB888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; - break; - } - } - if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0) - return -1; - - /* Select the target texture */ - locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE]; - rdata->glGetError(); - rdata->glActiveTexture(GL_TEXTURE0); - rdata->glBindTexture(tdata->texture_type, tdata->texture); - rdata->glUniform1i(locTexture, 0); - - /* Configure color modulation */ - locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION]; - rdata->glUniform4f(locModulation, - texture->r * inv255f, - texture->g * inv255f, - texture->b * inv255f, - texture->a * inv255f); - - /* Configure texture blending */ - GLES2_SetBlendMode(rdata, blendMode); - - GLES2_SetTexCoords(rdata, SDL_TRUE); - - /* Emit the textured quad */ - if (renderer->target) { - // Flip the texture vertically to compensate for the inversion it'll be subjected to later when it's rendered to the screen - vertices[0] = (GLfloat)dstrect->x; - vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y; - vertices[2] = (GLfloat)(dstrect->x + dstrect->w); - vertices[3] = (GLfloat)renderer->viewport.h-dstrect->y; - vertices[4] = (GLfloat)dstrect->x; - vertices[5] = (GLfloat)renderer->viewport.h-(dstrect->y + dstrect->h); - vertices[6] = (GLfloat)(dstrect->x + dstrect->w); - vertices[7] = (GLfloat)renderer->viewport.h-(dstrect->y + dstrect->h); - } - else { - vertices[0] = (GLfloat)dstrect->x; - vertices[1] = (GLfloat)dstrect->y; - vertices[2] = (GLfloat)(dstrect->x + dstrect->w); - vertices[3] = (GLfloat)dstrect->y; - vertices[4] = (GLfloat)dstrect->x; - vertices[5] = (GLfloat)(dstrect->y + dstrect->h); - vertices[6] = (GLfloat)(dstrect->x + dstrect->w); - vertices[7] = (GLfloat)(dstrect->y + dstrect->h); - } - rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); - texCoords[0] = srcrect->x / (GLfloat)texture->w; - texCoords[1] = srcrect->y / (GLfloat)texture->h; - texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; - texCoords[3] = srcrect->y / (GLfloat)texture->h; - texCoords[4] = srcrect->x / (GLfloat)texture->w; - texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; - texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; - texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; - rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); - rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - if (rdata->glGetError() != GL_NO_ERROR) - { - SDL_SetError("Failed to render texture"); - return -1; - } - return 0; -} - -static int -GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, - const SDL_Rect *dstrect, const double angle, const SDL_Point *center, const SDL_RendererFlip flip) -{ - GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; - GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; - GLES2_ImageSource sourceType; - SDL_BlendMode blendMode; - GLfloat vertices[8]; - GLfloat texCoords[8]; - GLuint locTexture; - GLuint locModulation; - GLfloat translate[8]; - GLfloat fAngle[4]; - GLfloat tmp; - - GLES2_ActivateRenderer(renderer); - - rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER); - rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE); - fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (GLfloat)angle; - /* Calculate the center of rotation */ - translate[0] = translate[2] = translate[4] = translate[6] = (GLfloat)(center->x + dstrect->x); - translate[1] = translate[3] = translate[5] = translate[7] = (GLfloat)(center->y + dstrect->y); - /* Activate an appropriate shader and set the projection matrix */ blendMode = texture->blendMode; if (renderer->target) { @@ -1423,11 +1272,21 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect /* Configure color modulation */ locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION]; - rdata->glUniform4f(locModulation, - texture->r * inv255f, - texture->g * inv255f, - texture->b * inv255f, - texture->a * inv255f); + if (renderer->target && + (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || + renderer->target->format == SDL_PIXELFORMAT_RGB888)) { + rdata->glUniform4f(locModulation, + texture->b * inv255f, + texture->g * inv255f, + texture->r * inv255f, + texture->a * inv255f); + } else { + rdata->glUniform4f(locModulation, + texture->r * inv255f, + texture->g * inv255f, + texture->b * inv255f, + texture->a * inv255f); + } /* Configure texture blending */ GLES2_SetBlendMode(rdata, blendMode); @@ -1435,27 +1294,180 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect GLES2_SetTexCoords(rdata, SDL_TRUE); /* Emit the textured quad */ + vertices[0] = dstrect->x; + vertices[1] = dstrect->y; + vertices[2] = (dstrect->x + dstrect->w); + vertices[3] = dstrect->y; + vertices[4] = dstrect->x; + vertices[5] = (dstrect->y + dstrect->h); + vertices[6] = (dstrect->x + dstrect->w); + vertices[7] = (dstrect->y + dstrect->h); + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + texCoords[0] = srcrect->x / (GLfloat)texture->w; + texCoords[1] = srcrect->y / (GLfloat)texture->h; + texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; + texCoords[3] = srcrect->y / (GLfloat)texture->h; + texCoords[4] = srcrect->x / (GLfloat)texture->w; + texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; + texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; + texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); + rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (rdata->glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to render texture"); + return -1; + } + return 0; +} + +static int +GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, + const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + GLES2_ImageSource sourceType; + SDL_BlendMode blendMode; + GLfloat vertices[8]; + GLfloat texCoords[8]; + GLuint locTexture; + GLuint locModulation; + GLfloat translate[8]; + GLfloat fAngle[4]; + GLfloat tmp; + + GLES2_ActivateRenderer(renderer); + + rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER); + rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE); + fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (GLfloat)angle; + /* Calculate the center of rotation */ + translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x); + translate[1] = translate[3] = translate[5] = translate[7] = (center->y + dstrect->y); + + /* Activate an appropriate shader and set the projection matrix */ + blendMode = texture->blendMode; if (renderer->target) { - // Flip the texture vertically to compensate for the inversion it'll be subjected to later when it's rendered to the screen - vertices[0] = (GLfloat)dstrect->x; - vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y; - vertices[2] = (GLfloat)(dstrect->x + dstrect->w); - vertices[3] = (GLfloat)renderer->viewport.h-dstrect->y; - vertices[4] = (GLfloat)dstrect->x; - vertices[5] = (GLfloat)renderer->viewport.h-(dstrect->y + dstrect->h); - vertices[6] = (GLfloat)(dstrect->x + dstrect->w); - vertices[7] = (GLfloat)renderer->viewport.h-(dstrect->y + dstrect->h); + /* Check if we need to do color mapping between the source and render target textures */ + if (renderer->target->format != texture->format) { + switch (texture->format) + { + case SDL_PIXELFORMAT_ABGR8888: + switch (renderer->target->format) + { + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_RGB888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + case SDL_PIXELFORMAT_BGR888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; + break; + } + break; + case SDL_PIXELFORMAT_ARGB8888: + switch (renderer->target->format) + { + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_BGR888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + case SDL_PIXELFORMAT_RGB888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; + break; + } + break; + case SDL_PIXELFORMAT_BGR888: + switch (renderer->target->format) + { + case SDL_PIXELFORMAT_ABGR8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; + break; + case SDL_PIXELFORMAT_ARGB8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; + break; + case SDL_PIXELFORMAT_RGB888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + } + break; + case SDL_PIXELFORMAT_RGB888: + switch (renderer->target->format) + { + case SDL_PIXELFORMAT_ABGR8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + case SDL_PIXELFORMAT_ARGB8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; + break; + case SDL_PIXELFORMAT_BGR888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + } + break; + } + } + else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; // Texture formats match, use the non color mapping shader (even if the formats are not ABGR) } else { - vertices[0] = (GLfloat)dstrect->x; - vertices[1] = (GLfloat)dstrect->y; - vertices[2] = (GLfloat)(dstrect->x + dstrect->w); - vertices[3] = (GLfloat)dstrect->y; - vertices[4] = (GLfloat)dstrect->x; - vertices[5] = (GLfloat)(dstrect->y + dstrect->h); - vertices[6] = (GLfloat)(dstrect->x + dstrect->w); - vertices[7] = (GLfloat)(dstrect->y + dstrect->h); + switch (texture->format) + { + case SDL_PIXELFORMAT_ABGR8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; + break; + case SDL_PIXELFORMAT_ARGB8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + case SDL_PIXELFORMAT_BGR888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; + break; + case SDL_PIXELFORMAT_RGB888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; + break; + } } + if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0) + return -1; + + /* Select the target texture */ + locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE]; + rdata->glGetError(); + rdata->glActiveTexture(GL_TEXTURE0); + rdata->glBindTexture(tdata->texture_type, tdata->texture); + rdata->glUniform1i(locTexture, 0); + + /* Configure color modulation */ + locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION]; + if (renderer->target && + (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || + renderer->target->format == SDL_PIXELFORMAT_RGB888)) { + rdata->glUniform4f(locModulation, + texture->b * inv255f, + texture->g * inv255f, + texture->r * inv255f, + texture->a * inv255f); + } else { + rdata->glUniform4f(locModulation, + texture->r * inv255f, + texture->g * inv255f, + texture->b * inv255f, + texture->a * inv255f); + } + + /* Configure texture blending */ + GLES2_SetBlendMode(rdata, blendMode); + + GLES2_SetTexCoords(rdata, SDL_TRUE); + + /* Emit the textured quad */ + vertices[0] = dstrect->x; + vertices[1] = dstrect->y; + vertices[2] = (dstrect->x + dstrect->w); + vertices[3] = dstrect->y; + vertices[4] = dstrect->x; + vertices[5] = (dstrect->y + dstrect->h); + vertices[6] = (dstrect->x + dstrect->w); + vertices[7] = (dstrect->y + dstrect->h); if (flip & SDL_FLIP_HORIZONTAL) { tmp = vertices[0]; vertices[0] = vertices[4] = vertices[2]; @@ -1552,6 +1564,39 @@ GLES2_RenderPresent(SDL_Renderer *renderer) SDL_GL_SwapWindow(renderer->window); } + +/************************************************************************************************* + * Bind/unbinding of textures + *************************************************************************************************/ +static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh); +static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture); + +static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) { + GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata; + GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata; + GLES2_ActivateRenderer(renderer); + + data->glActiveTexture(GL_TEXTURE0); + data->glBindTexture(texturedata->texture_type, texturedata->texture); + + if(texw) *texw = 1.0; + if(texh) *texh = 1.0; + + return 0; +} + +static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) { + GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata; + GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata; + GLES2_ActivateRenderer(renderer); + + data->glActiveTexture(GL_TEXTURE0); + data->glDisable(texturedata->texture_type); + + return 0; +} + + /************************************************************************************************* * Renderer instantiation * *************************************************************************************************/ @@ -1588,6 +1633,7 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) Uint32 windowFlags; GLint window_framebuffer; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); @@ -1699,6 +1745,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->RenderPresent = &GLES2_RenderPresent; renderer->DestroyTexture = &GLES2_DestroyTexture; renderer->DestroyRenderer = &GLES2_DestroyRenderer; + renderer->GL_BindTexture = &GLES2_BindTexture; + renderer->GL_UnbindTexture = &GLES2_UnbindTexture; GLES2_ResetState(renderer); diff --git a/src/eepp/helper/SDL2/src/render/opengles2/SDL_shaders_gles2.c b/src/eepp/helper/SDL2/src/render/opengles2/SDL_shaders_gles2.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/opengles2/SDL_shaders_gles2.h b/src/eepp/helper/SDL2/src/render/opengles2/SDL_shaders_gles2.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_blendfillrect.c b/src/eepp/helper/SDL2/src/render/software/SDL_blendfillrect.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_blendfillrect.h b/src/eepp/helper/SDL2/src/render/software/SDL_blendfillrect.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_blendline.c b/src/eepp/helper/SDL2/src/render/software/SDL_blendline.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_blendline.h b/src/eepp/helper/SDL2/src/render/software/SDL_blendline.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_blendpoint.c b/src/eepp/helper/SDL2/src/render/software/SDL_blendpoint.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_blendpoint.h b/src/eepp/helper/SDL2/src/render/software/SDL_blendpoint.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_draw.h b/src/eepp/helper/SDL2/src/render/software/SDL_draw.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_drawline.c b/src/eepp/helper/SDL2/src/render/software/SDL_drawline.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_drawline.h b/src/eepp/helper/SDL2/src/render/software/SDL_drawline.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_drawpoint.c b/src/eepp/helper/SDL2/src/render/software/SDL_drawpoint.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_drawpoint.h b/src/eepp/helper/SDL2/src/render/software/SDL_drawpoint.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_render_sw.c b/src/eepp/helper/SDL2/src/render/software/SDL_render_sw.c old mode 100755 new mode 100644 index 6cac41d6e..785b6ef7b --- a/src/eepp/helper/SDL2/src/render/software/SDL_render_sw.c +++ b/src/eepp/helper/SDL2/src/render/software/SDL_render_sw.c @@ -56,16 +56,16 @@ static int SW_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int SW_UpdateViewport(SDL_Renderer * renderer); static int SW_RenderClear(SDL_Renderer * renderer); static int SW_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int SW_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int SW_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip); static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); static void SW_RenderPresent(SDL_Renderer * renderer); @@ -344,28 +344,35 @@ SW_RenderClear(SDL_Renderer * renderer) } static int -SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); - SDL_Point *temp = NULL; - int status; + SDL_Point *final_points; + int i, status; if (!surface) { return -1; } + final_points = SDL_stack_alloc(SDL_Point, count); + if (!final_points) { + SDL_OutOfMemory(); + return -1; + } if (renderer->viewport.x || renderer->viewport.y) { - int i; int x = renderer->viewport.x; int y = renderer->viewport.y; - temp = SDL_stack_alloc(SDL_Point, count); for (i = 0; i < count; ++i) { - temp[i].x = x + points[i].x; - temp[i].y = y + points[i].x; + final_points[i].x = (int)(x + points[i].x); + final_points[i].y = (int)(y + points[i].y); + } + } else { + for (i = 0; i < count; ++i) { + final_points[i].x = (int)points[i].x; + final_points[i].y = (int)points[i].y; } - points = temp; } /* Draw the points! */ @@ -374,43 +381,48 @@ SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, renderer->r, renderer->g, renderer->b, renderer->a); - status = SDL_DrawPoints(surface, points, count, color); + status = SDL_DrawPoints(surface, final_points, count, color); } else { - status = SDL_BlendPoints(surface, points, count, + status = SDL_BlendPoints(surface, final_points, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } + SDL_stack_free(final_points); - if (temp) { - SDL_stack_free(temp); - } return status; } static int -SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); - SDL_Point *temp = NULL; - int status; + SDL_Point *final_points; + int i, status; if (!surface) { return -1; } + final_points = SDL_stack_alloc(SDL_Point, count); + if (!final_points) { + SDL_OutOfMemory(); + return -1; + } if (renderer->viewport.x || renderer->viewport.y) { - int i; int x = renderer->viewport.x; int y = renderer->viewport.y; - temp = SDL_stack_alloc(SDL_Point, count); for (i = 0; i < count; ++i) { - temp[i].x = x + points[i].x; - temp[i].y = y + points[i].y; + final_points[i].x = (int)(x + points[i].x); + final_points[i].y = (int)(y + points[i].y); + } + } else { + for (i = 0; i < count; ++i) { + final_points[i].x = (int)points[i].x; + final_points[i].y = (int)points[i].y; } - points = temp; } /* Draw the lines! */ @@ -419,80 +431,91 @@ SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, renderer->r, renderer->g, renderer->b, renderer->a); - status = SDL_DrawLines(surface, points, count, color); + status = SDL_DrawLines(surface, final_points, count, color); } else { - status = SDL_BlendLines(surface, points, count, + status = SDL_BlendLines(surface, final_points, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } + SDL_stack_free(final_points); - if (temp) { - SDL_stack_free(temp); - } return status; } static int -SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) +SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); - SDL_Rect *temp = NULL; - int status; + SDL_Rect *final_rects; + int i, status; if (!surface) { return -1; } + final_rects = SDL_stack_alloc(SDL_Rect, count); + if (!final_rects) { + SDL_OutOfMemory(); + return -1; + } if (renderer->viewport.x || renderer->viewport.y) { - int i; int x = renderer->viewport.x; int y = renderer->viewport.y; - temp = SDL_stack_alloc(SDL_Rect, count); for (i = 0; i < count; ++i) { - temp[i].x = x + rects[i].x; - temp[i].y = y + rects[i].y; - temp[i].w = rects[i].w; - temp[i].h = rects[i].h; + final_rects[i].x = (int)(x + rects[i].x); + final_rects[i].y = (int)(y + rects[i].y); + final_rects[i].w = SDL_max((int)rects[i].w, 1); + final_rects[i].h = SDL_max((int)rects[i].h, 1); + } + } else { + for (i = 0; i < count; ++i) { + final_rects[i].x = (int)rects[i].x; + final_rects[i].y = (int)rects[i].y; + final_rects[i].w = SDL_max((int)rects[i].w, 1); + final_rects[i].h = SDL_max((int)rects[i].h, 1); } - rects = temp; } if (renderer->blendMode == SDL_BLENDMODE_NONE) { Uint32 color = SDL_MapRGBA(surface->format, renderer->r, renderer->g, renderer->b, renderer->a); - status = SDL_FillRects(surface, rects, count, color); + status = SDL_FillRects(surface, final_rects, count, color); } else { - status = SDL_BlendFillRects(surface, rects, count, + status = SDL_BlendFillRects(surface, final_rects, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } + SDL_stack_free(final_rects); - if (temp) { - SDL_stack_free(temp); - } return status; } static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; - SDL_Rect final_rect = *dstrect; + SDL_Rect final_rect; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { - final_rect.x += renderer->viewport.x; - final_rect.y += renderer->viewport.y; + final_rect.x = (int)(renderer->viewport.x + dstrect->x); + final_rect.y = (int)(renderer->viewport.y + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; } + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; + if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) { return SDL_BlitSurface(src, srcrect, surface, &final_rect); } else { @@ -514,14 +537,13 @@ GetScaleQuality(void) static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; - SDL_Rect final_rect = *dstrect, tmp_rect; + SDL_Rect final_rect, tmp_rect; SDL_Surface *surface_rotated, *surface_scaled; - SDL_Point final_rect_center; Uint32 colorkey; int retval, dstwidth, dstheight, abscenterx, abscentery; double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; @@ -531,27 +553,33 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, } if (renderer->viewport.x || renderer->viewport.y) { - final_rect.x += renderer->viewport.x; - final_rect.y += renderer->viewport.y; + final_rect.x = (int)(renderer->viewport.x + dstrect->x); + final_rect.y = (int)(renderer->viewport.y + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; } + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; surface_scaled = SDL_CreateRGBSurface(SDL_SWSURFACE, final_rect.w, final_rect.h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask ); - SDL_GetColorKey(src, &colorkey); - SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey); - tmp_rect = final_rect; - tmp_rect.x = 0; - tmp_rect.y = 0; if (surface_scaled) { + SDL_GetColorKey(src, &colorkey); + SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey); + tmp_rect = final_rect; + tmp_rect.x = 0; + tmp_rect.y = 0; + retval = SDL_BlitScaled(src, srcrect, surface_scaled, &tmp_rect); if (!retval) { _rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, -angle, &dstwidth, &dstheight, &cangle, &sangle); surface_rotated = _rotateSurface(surface_scaled, -angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); if(surface_rotated) { /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ - abscenterx = final_rect.x + center->x; - abscentery = final_rect.y + center->y; + abscenterx = final_rect.x + (int)center->x; + abscentery = final_rect.y + (int)center->y; /* Compensate the angle inversion to match the behaviour of the other backends */ sangle = -sangle; diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_render_sw_c.h b/src/eepp/helper/SDL2/src/render/software/SDL_render_sw_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_rotate.c b/src/eepp/helper/SDL2/src/render/software/SDL_rotate.c index b64f137ab..2eae0393f 100644 --- a/src/eepp/helper/SDL2/src/render/software/SDL_rotate.c +++ b/src/eepp/helper/SDL2/src/render/software/SDL_rotate.c @@ -272,7 +272,7 @@ Assumes dst surface was allocated with the correct dimensions. */ void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) { - int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; + int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay; tColorY *pc, *sp; int gap; @@ -283,8 +283,6 @@ void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int yd = ((src->h - dst->h) << 15); ax = (cx << 16) - (icos * cx); ay = (cy << 16) - (isin * cx); - sw = src->w - 1; - sh = src->h - 1; pc = (tColorY*) dst->pixels; gap = dst->pitch - dst->w; /* diff --git a/src/eepp/helper/SDL2/src/render/software/SDL_rotate.h b/src/eepp/helper/SDL2/src/render/software/SDL_rotate.h index 6a5a174da..26bb8ad1c 100644 --- a/src/eepp/helper/SDL2/src/render/software/SDL_rotate.h +++ b/src/eepp/helper/SDL2/src/render/software/SDL_rotate.h @@ -3,4 +3,5 @@ #endif extern SDL_Surface *_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle); -extern void _rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle); \ No newline at end of file +extern void _rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle); + diff --git a/src/eepp/helper/SDL2/src/stdlib/SDL_getenv.c b/src/eepp/helper/SDL2/src/stdlib/SDL_getenv.c old mode 100755 new mode 100644 index d90bd2564..6e6477bde --- a/src/eepp/helper/SDL2/src/stdlib/SDL_getenv.c +++ b/src/eepp/helper/SDL2/src/stdlib/SDL_getenv.c @@ -24,7 +24,7 @@ #ifndef HAVE_GETENV -#if defined(__WIN32__) && !defined(_WIN32_WCE) +#if defined(__WIN32__) #include "../core/windows/SDL_windows.h" diff --git a/src/eepp/helper/SDL2/src/stdlib/SDL_iconv.c b/src/eepp/helper/SDL2/src/stdlib/SDL_iconv.c old mode 100755 new mode 100644 index e67be619b..89a80a2c7 --- a/src/eepp/helper/SDL2/src/stdlib/SDL_iconv.c +++ b/src/eepp/helper/SDL2/src/stdlib/SDL_iconv.c @@ -87,15 +87,21 @@ enum ENCODING_UTF32, /* Needs byte order marker */ ENCODING_UTF32BE, ENCODING_UTF32LE, - ENCODING_UCS2, /* Native byte order assumed */ - ENCODING_UCS4, /* Native byte order assumed */ + ENCODING_UCS2BE, + ENCODING_UCS2LE, + ENCODING_UCS4BE, + ENCODING_UCS4LE, }; #if SDL_BYTEORDER == SDL_BIG_ENDIAN #define ENCODING_UTF16NATIVE ENCODING_UTF16BE #define ENCODING_UTF32NATIVE ENCODING_UTF32BE +#define ENCODING_UCS2NATIVE ENCODING_UCS2BE +#define ENCODING_UCS4NATIVE ENCODING_UCS4BE #else #define ENCODING_UTF16NATIVE ENCODING_UTF16LE #define ENCODING_UTF32NATIVE ENCODING_UTF32LE +#define ENCODING_UCS2NATIVE ENCODING_UCS2LE +#define ENCODING_UCS4NATIVE ENCODING_UCS4LE #endif struct _SDL_iconv_t @@ -128,10 +134,16 @@ static struct { "UTF-32BE", ENCODING_UTF32BE }, { "UTF32LE", ENCODING_UTF32LE }, { "UTF-32LE", ENCODING_UTF32LE }, - { "UCS2", ENCODING_UCS2 }, - { "UCS-2", ENCODING_UCS2 }, - { "UCS4", ENCODING_UCS4 }, - { "UCS-4", ENCODING_UCS4 }, + { "UCS2", ENCODING_UCS2BE }, + { "UCS-2", ENCODING_UCS2BE }, + { "UCS-2LE", ENCODING_UCS2LE }, + { "UCS-2BE", ENCODING_UCS2BE }, + { "UCS-2-INTERNAL", ENCODING_UCS2NATIVE }, + { "UCS4", ENCODING_UCS4BE }, + { "UCS-4", ENCODING_UCS4BE }, + { "UCS-4LE", ENCODING_UCS4LE }, + { "UCS-4BE", ENCODING_UCS4BE }, + { "UCS-4-INTERNAL", ENCODING_UCS4NATIVE }, /* *INDENT-ON* */ }; @@ -518,6 +530,29 @@ SDL_iconv(SDL_iconv_t cd, (Uint32) (W2 & 0x3FF)) + 0x10000; } break; + case ENCODING_UCS2LE: + { + Uint8 *p = (Uint8 *) src; + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + ch = ((Uint32) p[1] << 8) | (Uint32) p[0]; + src += 2; + srclen -= 2; + } + break; + case ENCODING_UCS2BE: + { + Uint8 *p = (Uint8 *) src; + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + ch = ((Uint32) p[0] << 8) | (Uint32) p[1]; + src += 2; + srclen -= 2; + } + break; + case ENCODING_UCS4BE: case ENCODING_UTF32BE: { Uint8 *p = (Uint8 *) src; @@ -531,6 +566,7 @@ SDL_iconv(SDL_iconv_t cd, srclen -= 4; } break; + case ENCODING_UCS4LE: case ENCODING_UTF32LE: { Uint8 *p = (Uint8 *) src; @@ -544,28 +580,6 @@ SDL_iconv(SDL_iconv_t cd, srclen -= 4; } break; - case ENCODING_UCS2: - { - Uint16 *p = (Uint16 *) src; - if (srclen < 2) { - return SDL_ICONV_EINVAL; - } - ch = *p; - src += 2; - srclen -= 2; - } - break; - case ENCODING_UCS4: - { - Uint32 *p = (Uint32 *) src; - if (srclen < 4) { - return SDL_ICONV_EINVAL; - } - ch = *p; - src += 4; - srclen -= 4; - } - break; } /* Encode a character */ @@ -728,12 +742,46 @@ SDL_iconv(SDL_iconv_t cd, } } break; - case ENCODING_UTF32BE: + case ENCODING_UCS2BE: { Uint8 *p = (Uint8 *) dst; - if (ch > 0x10FFFF) { + if (ch > 0xFFFF) { ch = UNKNOWN_UNICODE; } + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[0] = (Uint8) (ch >> 8); + p[1] = (Uint8) ch; + dst += 2; + dstlen -= 2; + } + break; + case ENCODING_UCS2LE: + { + Uint8 *p = (Uint8 *) dst; + if (ch > 0xFFFF) { + ch = UNKNOWN_UNICODE; + } + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[1] = (Uint8) (ch >> 8); + p[0] = (Uint8) ch; + dst += 2; + dstlen -= 2; + } + break; + case ENCODING_UTF32BE: + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + case ENCODING_UCS4BE: + if (ch > 0x7FFFFFFF) { + ch = UNKNOWN_UNICODE; + } + { + Uint8 *p = (Uint8 *) dst; if (dstlen < 4) { return SDL_ICONV_E2BIG; } @@ -746,11 +794,15 @@ SDL_iconv(SDL_iconv_t cd, } break; case ENCODING_UTF32LE: + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + case ENCODING_UCS4LE: + if (ch > 0x7FFFFFFF) { + ch = UNKNOWN_UNICODE; + } { Uint8 *p = (Uint8 *) dst; - if (ch > 0x10FFFF) { - ch = UNKNOWN_UNICODE; - } if (dstlen < 4) { return SDL_ICONV_E2BIG; } @@ -762,34 +814,6 @@ SDL_iconv(SDL_iconv_t cd, dstlen -= 4; } break; - case ENCODING_UCS2: - { - Uint16 *p = (Uint16 *) dst; - if (ch > 0xFFFF) { - ch = UNKNOWN_UNICODE; - } - if (dstlen < 2) { - return SDL_ICONV_E2BIG; - } - *p = (Uint16) ch; - dst += 2; - dstlen -= 2; - } - break; - case ENCODING_UCS4: - { - Uint32 *p = (Uint32 *) dst; - if (ch > 0x7FFFFFFF) { - ch = UNKNOWN_UNICODE; - } - if (dstlen < 4) { - return SDL_ICONV_E2BIG; - } - *p = ch; - dst += 4; - dstlen -= 4; - } - break; } /* Update state */ diff --git a/src/eepp/helper/SDL2/src/stdlib/SDL_malloc.c b/src/eepp/helper/SDL2/src/stdlib/SDL_malloc.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/stdlib/SDL_stdlib.c b/src/eepp/helper/SDL2/src/stdlib/SDL_stdlib.c old mode 100755 new mode 100644 index c4059f637..56eb5da4f --- a/src/eepp/helper/SDL2/src/stdlib/SDL_stdlib.c +++ b/src/eepp/helper/SDL2/src/stdlib/SDL_stdlib.c @@ -34,8 +34,8 @@ __declspec(selectany) int _fltused = 1; #endif -/* The optimizer on Visual Studio 2010 generates memcpy() calls */ -#if _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG) +/* The optimizer on Visual Studio 2010/2012 generates memcpy() calls */ +#if _MSC_VER >= 1600 && defined(_WIN64) && !defined(_DEBUG) #include #pragma function(memcpy) diff --git a/src/eepp/helper/SDL2/src/stdlib/SDL_string.c b/src/eepp/helper/SDL2/src/stdlib/SDL_string.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_assert.c b/src/eepp/helper/SDL2/src/test/SDL_test_assert.c new file mode 100644 index 000000000..13eda7be8 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_assert.c @@ -0,0 +1,113 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + + Used by the test framework and test cases. + +*/ + +#include "SDL_config.h" + +#include "SDL_test.h" + +/* Assert check message format */ +const char *SDLTest_AssertCheckFmt = "Assert '%s': %s"; + +/* Assert summary message format */ +const char *SDLTest_AssertSummaryFmt = "Assert Summary: Total=%d Passed=%d Failed=%d"; + +/*! \brief counts the failed asserts */ +static Uint32 SDLTest_AssertsFailed = 0; + +/*! \brief counts the passed asserts */ +static Uint32 SDLTest_AssertsPassed = 0; + +/* + * Assert that logs and break execution flow on failures (i.e. for harness errors). + */ +void SDLTest_Assert(int assertCondition, char *assertDescription) +{ + SDL_assert((SDLTest_AssertCheck(assertCondition, assertDescription))); +} + +/* + * Assert that logs but does not break execution flow on failures (i.e. for test cases). + */ +int SDLTest_AssertCheck(int assertCondition, char *assertDescription) +{ + char *fmt = (char *)SDLTest_AssertCheckFmt; + if (assertCondition == ASSERT_FAIL) + { + SDLTest_AssertsFailed++; + SDLTest_LogError(fmt, assertDescription, "Failed"); + } + else + { + SDLTest_AssertsPassed++; + SDLTest_Log(fmt, assertDescription, "Passed"); + } + + return assertCondition; +} + +/* + * Resets the assert summary counters to zero. + */ +void SDLTest_ResetAssertSummary() +{ + SDLTest_AssertsPassed = 0; + SDLTest_AssertsFailed = 0; +} + +/* + * Logs summary of all assertions (total, pass, fail) since last reset + * as INFO (failed==0) or ERROR (failed > 0). + */ +void SDLTest_LogAssertSummary() +{ + char *fmt = (char *)SDLTest_AssertSummaryFmt; + Uint32 totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; + if (SDLTest_AssertsFailed == 0) + { + SDLTest_Log(fmt, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); + } + else + { + SDLTest_LogError(fmt, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); + } +} + +/* + * Converts the current assert state into a test result + */ +int SDLTest_AssertSummaryToTestResult() +{ + if (SDLTest_AssertsFailed > 0) { + return TEST_RESULT_FAILED; + } else { + if (SDLTest_AssertsPassed > 0) { + return TEST_RESULT_PASSED; + } else { + return TEST_RESULT_NO_ASSERT; + } + } +} diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_common.c b/src/eepp/helper/SDL2/src/test/SDL_test_common.c new file mode 100644 index 000000000..2fe85b56c --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_common.c @@ -0,0 +1,1261 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* Ported from original test\common.c file. */ + +#include "SDL_config.h" +#include "SDL_test.h" + +#include + +#define VIDEO_USAGE \ +"[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]" + +#define AUDIO_USAGE \ +"[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]" + +SDLTest_CommonState * +SDLTest_CommonCreateState(char **argv, Uint32 flags) +{ + SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state)); + if (!state) { + SDL_OutOfMemory(); + return NULL; + } + + /* Initialize some defaults */ + state->argv = argv; + state->flags = flags; +#ifdef __NDS__ + state->window_title = ""; +#else + state->window_title = argv[0]; +#endif + state->window_flags = 0; + state->window_x = SDL_WINDOWPOS_UNDEFINED; + state->window_y = SDL_WINDOWPOS_UNDEFINED; + state->window_w = DEFAULT_WINDOW_WIDTH; + state->window_h = DEFAULT_WINDOW_HEIGHT; + state->num_windows = 1; + state->audiospec.freq = 22050; + state->audiospec.format = AUDIO_S16; + state->audiospec.channels = 2; + state->audiospec.samples = 2048; + + /* Set some very sane GL defaults */ + state->gl_red_size = 3; + state->gl_green_size = 3; + state->gl_blue_size = 2; + state->gl_alpha_size = 0; + state->gl_buffer_size = 0; + state->gl_depth_size = 16; + state->gl_stencil_size = 0; + state->gl_double_buffer = 1; + state->gl_accum_red_size = 0; + state->gl_accum_green_size = 0; + state->gl_accum_blue_size = 0; + state->gl_accum_alpha_size = 0; + state->gl_stereo = 0; + state->gl_multisamplebuffers = 0; + state->gl_multisamplesamples = 0; + state->gl_retained_backing = 1; + state->gl_accelerated = -1; + + return state; +} + +int +SDLTest_CommonArg(SDLTest_CommonState * state, int index) +{ + char **argv = state->argv; + +#ifdef __NDS__ + return 0; +#endif + + if (SDL_strcasecmp(argv[index], "--video") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->videodriver = argv[index]; + return 2; + } + if (SDL_strcasecmp(argv[index], "--renderer") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->renderdriver = argv[index]; + return 2; + } + if (SDL_strcasecmp(argv[index], "--info") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + if (SDL_strcasecmp(argv[index], "all") == 0) { + state->verbose |= + (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER | + VERBOSE_EVENT); + return 2; + } + if (SDL_strcasecmp(argv[index], "video") == 0) { + state->verbose |= VERBOSE_VIDEO; + return 2; + } + if (SDL_strcasecmp(argv[index], "modes") == 0) { + state->verbose |= VERBOSE_MODES; + return 2; + } + if (SDL_strcasecmp(argv[index], "render") == 0) { + state->verbose |= VERBOSE_RENDER; + return 2; + } + if (SDL_strcasecmp(argv[index], "event") == 0) { + state->verbose |= VERBOSE_EVENT; + return 2; + } + return -1; + } + if (SDL_strcasecmp(argv[index], "--log") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + if (SDL_strcasecmp(argv[index], "all") == 0) { + SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + if (SDL_strcasecmp(argv[index], "error") == 0) { + SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + if (SDL_strcasecmp(argv[index], "system") == 0) { + SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + if (SDL_strcasecmp(argv[index], "audio") == 0) { + SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + if (SDL_strcasecmp(argv[index], "video") == 0) { + SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + if (SDL_strcasecmp(argv[index], "render") == 0) { + SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + if (SDL_strcasecmp(argv[index], "input") == 0) { + SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE); + return 2; + } + return -1; + } + if (SDL_strcasecmp(argv[index], "--display") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->display = SDL_atoi(argv[index]); + if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) { + state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display); + state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display); + } + if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) { + state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display); + state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display); + } + return 2; + } + if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) { + state->window_flags |= SDL_WINDOW_FULLSCREEN; + state->num_windows = 1; + return 1; + } + if (SDL_strcasecmp(argv[index], "--windows") == 0) { + ++index; + if (!argv[index] || !SDL_isdigit(*argv[index])) { + return -1; + } + if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) { + state->num_windows = SDL_atoi(argv[index]); + } + return 2; + } + if (SDL_strcasecmp(argv[index], "--title") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->window_title = argv[index]; + return 2; + } + if (SDL_strcasecmp(argv[index], "--icon") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->window_icon = argv[index]; + return 2; + } + if (SDL_strcasecmp(argv[index], "--center") == 0) { + state->window_x = SDL_WINDOWPOS_CENTERED; + state->window_y = SDL_WINDOWPOS_CENTERED; + return 1; + } + if (SDL_strcasecmp(argv[index], "--position") == 0) { + char *x, *y; + ++index; + if (!argv[index]) { + return -1; + } + x = argv[index]; + y = argv[index]; + while (*y && *y != ',') { + ++y; + } + if (!*y) { + return -1; + } + *y++ = '\0'; + state->window_x = SDL_atoi(x); + state->window_y = SDL_atoi(y); + return 2; + } + if (SDL_strcasecmp(argv[index], "--geometry") == 0) { + char *w, *h; + ++index; + if (!argv[index]) { + return -1; + } + w = argv[index]; + h = argv[index]; + while (*h && *h != 'x') { + ++h; + } + if (!*h) { + return -1; + } + *h++ = '\0'; + state->window_w = SDL_atoi(w); + state->window_h = SDL_atoi(h); + return 2; + } + if (SDL_strcasecmp(argv[index], "--depth") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->depth = SDL_atoi(argv[index]); + return 2; + } + if (SDL_strcasecmp(argv[index], "--refresh") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->refresh_rate = SDL_atoi(argv[index]); + return 2; + } + if (SDL_strcasecmp(argv[index], "--vsync") == 0) { + state->render_flags |= SDL_RENDERER_PRESENTVSYNC; + return 1; + } + if (SDL_strcasecmp(argv[index], "--noframe") == 0) { + state->window_flags |= SDL_WINDOW_BORDERLESS; + return 1; + } + if (SDL_strcasecmp(argv[index], "--resize") == 0) { + state->window_flags |= SDL_WINDOW_RESIZABLE; + return 1; + } + if (SDL_strcasecmp(argv[index], "--minimize") == 0) { + state->window_flags |= SDL_WINDOW_MINIMIZED; + return 1; + } + if (SDL_strcasecmp(argv[index], "--maximize") == 0) { + state->window_flags |= SDL_WINDOW_MAXIMIZED; + return 1; + } + if (SDL_strcasecmp(argv[index], "--grab") == 0) { + state->window_flags |= SDL_WINDOW_INPUT_GRABBED; + return 1; + } + if (SDL_strcasecmp(argv[index], "--rate") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->audiospec.freq = SDL_atoi(argv[index]); + return 2; + } + if (SDL_strcasecmp(argv[index], "--format") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + if (SDL_strcasecmp(argv[index], "U8") == 0) { + state->audiospec.format = AUDIO_U8; + return 2; + } + if (SDL_strcasecmp(argv[index], "S8") == 0) { + state->audiospec.format = AUDIO_S8; + return 2; + } + if (SDL_strcasecmp(argv[index], "U16") == 0) { + state->audiospec.format = AUDIO_U16; + return 2; + } + if (SDL_strcasecmp(argv[index], "U16LE") == 0) { + state->audiospec.format = AUDIO_U16LSB; + return 2; + } + if (SDL_strcasecmp(argv[index], "U16BE") == 0) { + state->audiospec.format = AUDIO_U16MSB; + return 2; + } + if (SDL_strcasecmp(argv[index], "S16") == 0) { + state->audiospec.format = AUDIO_S16; + return 2; + } + if (SDL_strcasecmp(argv[index], "S16LE") == 0) { + state->audiospec.format = AUDIO_S16LSB; + return 2; + } + if (SDL_strcasecmp(argv[index], "S16BE") == 0) { + state->audiospec.format = AUDIO_S16MSB; + return 2; + } + return -1; + } + if (SDL_strcasecmp(argv[index], "--channels") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->audiospec.channels = (Uint8) SDL_atoi(argv[index]); + return 2; + } + if (SDL_strcasecmp(argv[index], "--samples") == 0) { + ++index; + if (!argv[index]) { + return -1; + } + state->audiospec.samples = (Uint16) SDL_atoi(argv[index]); + return 2; + } + if ((SDL_strcasecmp(argv[index], "-h") == 0) + || (SDL_strcasecmp(argv[index], "--help") == 0)) { + /* Print the usage message */ + return -1; + } + if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) { + /* Debug flag sent by Xcode */ + return 2; + } + return 0; +} + +const char * +SDLTest_CommonUsage(SDLTest_CommonState * state) +{ + switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + case SDL_INIT_VIDEO: + return VIDEO_USAGE; + case SDL_INIT_AUDIO: + return AUDIO_USAGE; + case (SDL_INIT_VIDEO | SDL_INIT_AUDIO): + return VIDEO_USAGE " " AUDIO_USAGE; + default: + return ""; + } +} + +static void +SDLTest_PrintRendererFlag(Uint32 flag) +{ + switch (flag) { + case SDL_RENDERER_PRESENTVSYNC: + fprintf(stderr, "PresentVSync"); + break; + case SDL_RENDERER_ACCELERATED: + fprintf(stderr, "Accelerated"); + break; + default: + fprintf(stderr, "0x%8.8x", flag); + break; + } +} + +static void +SDLTest_PrintPixelFormat(Uint32 format) +{ + switch (format) { + case SDL_PIXELFORMAT_UNKNOWN: + fprintf(stderr, "Unknwon"); + break; + case SDL_PIXELFORMAT_INDEX1LSB: + fprintf(stderr, "Index1LSB"); + break; + case SDL_PIXELFORMAT_INDEX1MSB: + fprintf(stderr, "Index1MSB"); + break; + case SDL_PIXELFORMAT_INDEX4LSB: + fprintf(stderr, "Index4LSB"); + break; + case SDL_PIXELFORMAT_INDEX4MSB: + fprintf(stderr, "Index4MSB"); + break; + case SDL_PIXELFORMAT_INDEX8: + fprintf(stderr, "Index8"); + break; + case SDL_PIXELFORMAT_RGB332: + fprintf(stderr, "RGB332"); + break; + case SDL_PIXELFORMAT_RGB444: + fprintf(stderr, "RGB444"); + break; + case SDL_PIXELFORMAT_RGB555: + fprintf(stderr, "RGB555"); + break; + case SDL_PIXELFORMAT_BGR555: + fprintf(stderr, "BGR555"); + break; + case SDL_PIXELFORMAT_ARGB4444: + fprintf(stderr, "ARGB4444"); + break; + case SDL_PIXELFORMAT_ABGR4444: + fprintf(stderr, "ABGR4444"); + break; + case SDL_PIXELFORMAT_ARGB1555: + fprintf(stderr, "ARGB1555"); + break; + case SDL_PIXELFORMAT_ABGR1555: + fprintf(stderr, "ABGR1555"); + break; + case SDL_PIXELFORMAT_RGB565: + fprintf(stderr, "RGB565"); + break; + case SDL_PIXELFORMAT_BGR565: + fprintf(stderr, "BGR565"); + break; + case SDL_PIXELFORMAT_RGB24: + fprintf(stderr, "RGB24"); + break; + case SDL_PIXELFORMAT_BGR24: + fprintf(stderr, "BGR24"); + break; + case SDL_PIXELFORMAT_RGB888: + fprintf(stderr, "RGB888"); + break; + case SDL_PIXELFORMAT_BGR888: + fprintf(stderr, "BGR888"); + break; + case SDL_PIXELFORMAT_ARGB8888: + fprintf(stderr, "ARGB8888"); + break; + case SDL_PIXELFORMAT_RGBA8888: + fprintf(stderr, "RGBA8888"); + break; + case SDL_PIXELFORMAT_ABGR8888: + fprintf(stderr, "ABGR8888"); + break; + case SDL_PIXELFORMAT_BGRA8888: + fprintf(stderr, "BGRA8888"); + break; + case SDL_PIXELFORMAT_ARGB2101010: + fprintf(stderr, "ARGB2101010"); + break; + case SDL_PIXELFORMAT_YV12: + fprintf(stderr, "YV12"); + break; + case SDL_PIXELFORMAT_IYUV: + fprintf(stderr, "IYUV"); + break; + case SDL_PIXELFORMAT_YUY2: + fprintf(stderr, "YUY2"); + break; + case SDL_PIXELFORMAT_UYVY: + fprintf(stderr, "UYVY"); + break; + case SDL_PIXELFORMAT_YVYU: + fprintf(stderr, "YVYU"); + break; + default: + fprintf(stderr, "0x%8.8x", format); + break; + } +} + +static void +SDLTest_PrintRenderer(SDL_RendererInfo * info) +{ + int i, count; + + fprintf(stderr, " Renderer %s:\n", info->name); + + fprintf(stderr, " Flags: 0x%8.8X", info->flags); + fprintf(stderr, " ("); + count = 0; + for (i = 0; i < sizeof(info->flags) * 8; ++i) { + Uint32 flag = (1 << i); + if (info->flags & flag) { + if (count > 0) { + fprintf(stderr, " | "); + } + SDLTest_PrintRendererFlag(flag); + ++count; + } + } + fprintf(stderr, ")\n"); + + fprintf(stderr, " Texture formats (%d): ", info->num_texture_formats); + for (i = 0; i < (int) info->num_texture_formats; ++i) { + if (i > 0) { + fprintf(stderr, ", "); + } + SDLTest_PrintPixelFormat(info->texture_formats[i]); + } + fprintf(stderr, "\n"); + + if (info->max_texture_width || info->max_texture_height) { + fprintf(stderr, " Max Texture Size: %dx%d\n", + info->max_texture_width, info->max_texture_height); + } +} + +static SDL_Surface * +SDLTest_LoadIcon(const char *file) +{ + SDL_Surface *icon; + + /* Load the icon surface */ + icon = SDL_LoadBMP(file); + if (icon == NULL) { + fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); + return (NULL); + } + + if (icon->format->palette) { + /* Set the colorkey */ + SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels)); + } + + return (icon); +} + +SDL_bool +SDLTest_CommonInit(SDLTest_CommonState * state) +{ + int i, j, m, n, w, h; + SDL_DisplayMode fullscreen_mode; + + if (state->flags & SDL_INIT_VIDEO) { + if (state->verbose & VERBOSE_VIDEO) { + n = SDL_GetNumVideoDrivers(); + if (n == 0) { + fprintf(stderr, "No built-in video drivers\n"); + } else { + fprintf(stderr, "Built-in video drivers:"); + for (i = 0; i < n; ++i) { + if (i > 0) { + fprintf(stderr, ","); + } + fprintf(stderr, " %s", SDL_GetVideoDriver(i)); + } + fprintf(stderr, "\n"); + } + } + if (SDL_VideoInit(state->videodriver) < 0) { + fprintf(stderr, "Couldn't initialize video driver: %s\n", + SDL_GetError()); + return SDL_FALSE; + } + if (state->verbose & VERBOSE_VIDEO) { + fprintf(stderr, "Video driver: %s\n", + SDL_GetCurrentVideoDriver()); + } + + /* Upload GL settings */ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size); + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size); + SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples); + if (state->gl_accelerated >= 0) { + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, + state->gl_accelerated); + } + SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing); + if (state->gl_major_version) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version); + } + + if (state->verbose & VERBOSE_MODES) { + SDL_Rect bounds; + SDL_DisplayMode mode; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + n = SDL_GetNumVideoDisplays(); + fprintf(stderr, "Number of displays: %d\n", n); + for (i = 0; i < n; ++i) { + fprintf(stderr, "Display %d:\n", i); + + SDL_zero(bounds); + SDL_GetDisplayBounds(i, &bounds); + fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y); + + SDL_GetDesktopDisplayMode(i, &mode); + SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, + &Bmask, &Amask); + fprintf(stderr, + " Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n", + mode.w, mode.h, mode.refresh_rate, bpp, + SDL_GetPixelFormatName(mode.format)); + if (Rmask || Gmask || Bmask) { + fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); + fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); + fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); + if (Amask) + fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); + } + + /* Print available fullscreen video modes */ + m = SDL_GetNumDisplayModes(i); + if (m == 0) { + fprintf(stderr, "No available fullscreen video modes\n"); + } else { + fprintf(stderr, " Fullscreen video modes:\n"); + for (j = 0; j < m; ++j) { + SDL_GetDisplayMode(i, j, &mode); + SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, + &Gmask, &Bmask, &Amask); + fprintf(stderr, + " Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n", + j, mode.w, mode.h, mode.refresh_rate, bpp, + SDL_GetPixelFormatName(mode.format)); + if (Rmask || Gmask || Bmask) { + fprintf(stderr, " Red Mask = 0x%.8x\n", + Rmask); + fprintf(stderr, " Green Mask = 0x%.8x\n", + Gmask); + fprintf(stderr, " Blue Mask = 0x%.8x\n", + Bmask); + if (Amask) + fprintf(stderr, + " Alpha Mask = 0x%.8x\n", + Amask); + } + } + } + } + } + + if (state->verbose & VERBOSE_RENDER) { + SDL_RendererInfo info; + + n = SDL_GetNumRenderDrivers(); + if (n == 0) { + fprintf(stderr, "No built-in render drivers\n"); + } else { + fprintf(stderr, "Built-in render drivers:\n"); + for (i = 0; i < n; ++i) { + SDL_GetRenderDriverInfo(i, &info); + SDLTest_PrintRenderer(&info); + } + } + } + + SDL_zero(fullscreen_mode); + switch (state->depth) { + case 8: + fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8; + break; + case 15: + fullscreen_mode.format = SDL_PIXELFORMAT_RGB555; + break; + case 16: + fullscreen_mode.format = SDL_PIXELFORMAT_RGB565; + break; + case 24: + fullscreen_mode.format = SDL_PIXELFORMAT_RGB24; + break; + default: + fullscreen_mode.format = SDL_PIXELFORMAT_RGB888; + break; + } + fullscreen_mode.refresh_rate = state->refresh_rate; + + state->windows = + (SDL_Window **) SDL_malloc(state->num_windows * + sizeof(*state->windows)); + state->renderers = + (SDL_Renderer **) SDL_malloc(state->num_windows * + sizeof(*state->renderers)); + if (!state->windows || !state->renderers) { + fprintf(stderr, "Out of memory!\n"); + return SDL_FALSE; + } + for (i = 0; i < state->num_windows; ++i) { + char title[1024]; + + if (state->num_windows > 1) { + SDL_snprintf(title, SDL_arraysize(title), "%s %d", + state->window_title, i + 1); + } else { + SDL_strlcpy(title, state->window_title, SDL_arraysize(title)); + } + state->windows[i] = + SDL_CreateWindow(title, state->window_x, state->window_y, + state->window_w, state->window_h, + state->window_flags); + if (!state->windows[i]) { + fprintf(stderr, "Couldn't create window: %s\n", + SDL_GetError()); + return SDL_FALSE; + } + SDL_GetWindowSize(state->windows[i], &w, &h); + if (!(state->window_flags & SDL_WINDOW_RESIZABLE) && + (w != state->window_w || h != state->window_h)) { + printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h); + state->window_w = w; + state->window_h = h; + } + if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) { + fprintf(stderr, "Can't set up fullscreen display mode: %s\n", + SDL_GetError()); + return SDL_FALSE; + } + + if (state->window_icon) { + SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon); + if (icon) { + SDL_SetWindowIcon(state->windows[i], icon); + SDL_FreeSurface(icon); + } + } + + SDL_ShowWindow(state->windows[i]); + + state->renderers[i] = NULL; + + if (!state->skip_renderer + && (state->renderdriver + || !(state->window_flags & SDL_WINDOW_OPENGL))) { + m = -1; + if (state->renderdriver) { + SDL_RendererInfo info; + n = SDL_GetNumRenderDrivers(); + for (j = 0; j < n; ++j) { + SDL_GetRenderDriverInfo(j, &info); + if (SDL_strcasecmp(info.name, state->renderdriver) == + 0) { + m = j; + break; + } + } + if (m == n) { + fprintf(stderr, + "Couldn't find render driver named %s", + state->renderdriver); + return SDL_FALSE; + } + } + state->renderers[i] = SDL_CreateRenderer(state->windows[i], + m, state->render_flags); + if (!state->renderers[i]) { + fprintf(stderr, "Couldn't create renderer: %s\n", + SDL_GetError()); + return SDL_FALSE; + } + if (state->verbose & VERBOSE_RENDER) { + SDL_RendererInfo info; + + fprintf(stderr, "Current renderer:\n"); + SDL_GetRendererInfo(state->renderers[i], &info); + SDLTest_PrintRenderer(&info); + } + } + } + } + + if (state->flags & SDL_INIT_AUDIO) { + if (state->verbose & VERBOSE_AUDIO) { + n = SDL_GetNumAudioDrivers(); + if (n == 0) { + fprintf(stderr, "No built-in audio drivers\n"); + } else { + fprintf(stderr, "Built-in audio drivers:"); + for (i = 0; i < n; ++i) { + if (i > 0) { + fprintf(stderr, ","); + } + fprintf(stderr, " %s", SDL_GetAudioDriver(i)); + } + fprintf(stderr, "\n"); + } + } + if (SDL_AudioInit(state->audiodriver) < 0) { + fprintf(stderr, "Couldn't initialize audio driver: %s\n", + SDL_GetError()); + return SDL_FALSE; + } + if (state->verbose & VERBOSE_VIDEO) { + fprintf(stderr, "Audio driver: %s\n", + SDL_GetCurrentAudioDriver()); + } + + if (SDL_OpenAudio(&state->audiospec, NULL) < 0) { + fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); + return SDL_FALSE; + } + } + + return SDL_TRUE; +} + +static void +SDLTest_PrintEvent(SDL_Event * event) +{ + if (event->type == SDL_MOUSEMOTION) { + /* Mouse motion is really spammy */ + //return; + } + + fprintf(stderr, "SDL EVENT: "); + switch (event->type) { + case SDL_WINDOWEVENT: + switch (event->window.event) { + case SDL_WINDOWEVENT_SHOWN: + fprintf(stderr, "Window %d shown", event->window.windowID); + break; + case SDL_WINDOWEVENT_HIDDEN: + fprintf(stderr, "Window %d hidden", event->window.windowID); + break; + case SDL_WINDOWEVENT_EXPOSED: + fprintf(stderr, "Window %d exposed", event->window.windowID); + break; + case SDL_WINDOWEVENT_MOVED: + fprintf(stderr, "Window %d moved to %d,%d", + event->window.windowID, event->window.data1, + event->window.data2); + break; + case SDL_WINDOWEVENT_RESIZED: + fprintf(stderr, "Window %d resized to %dx%d", + event->window.windowID, event->window.data1, + event->window.data2); + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + fprintf(stderr, "Window %d changed size to %dx%d", + event->window.windowID, event->window.data1, + event->window.data2); + break; + case SDL_WINDOWEVENT_MINIMIZED: + fprintf(stderr, "Window %d minimized", event->window.windowID); + break; + case SDL_WINDOWEVENT_MAXIMIZED: + fprintf(stderr, "Window %d maximized", event->window.windowID); + break; + case SDL_WINDOWEVENT_RESTORED: + fprintf(stderr, "Window %d restored", event->window.windowID); + break; + case SDL_WINDOWEVENT_ENTER: + fprintf(stderr, "Mouse entered window %d", + event->window.windowID); + break; + case SDL_WINDOWEVENT_LEAVE: + fprintf(stderr, "Mouse left window %d", event->window.windowID); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + fprintf(stderr, "Window %d gained keyboard focus", + event->window.windowID); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + fprintf(stderr, "Window %d lost keyboard focus", + event->window.windowID); + break; + case SDL_WINDOWEVENT_CLOSE: + fprintf(stderr, "Window %d closed", event->window.windowID); + break; + default: + fprintf(stderr, "Window %d got unknown event %d", + event->window.windowID, event->window.event); + break; + } + break; + case SDL_KEYDOWN: + fprintf(stderr, + "Keyboard: key pressed in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s", + event->key.windowID, + event->key.keysym.scancode, + SDL_GetScancodeName(event->key.keysym.scancode), + event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym)); + break; + case SDL_KEYUP: + fprintf(stderr, + "Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s", + event->key.windowID, + event->key.keysym.scancode, + SDL_GetScancodeName(event->key.keysym.scancode), + event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym)); + break; + case SDL_TEXTINPUT: + fprintf(stderr, "Keyboard: text input \"%s\" in window %d", + event->text.text, event->text.windowID); + break; + case SDL_MOUSEMOTION: + fprintf(stderr, "Mouse: moved to %d,%d (%d,%d) in window %d", + event->motion.x, event->motion.y, + event->motion.xrel, event->motion.yrel, + event->motion.windowID); + break; + case SDL_MOUSEBUTTONDOWN: + fprintf(stderr, "Mouse: button %d pressed at %d,%d in window %d", + event->button.button, event->button.x, event->button.y, + event->button.windowID); + break; + case SDL_MOUSEBUTTONUP: + fprintf(stderr, "Mouse: button %d released at %d,%d in window %d", + event->button.button, event->button.x, event->button.y, + event->button.windowID); + break; + case SDL_MOUSEWHEEL: + fprintf(stderr, + "Mouse: wheel scrolled %d in x and %d in y in window %d", + event->wheel.x, event->wheel.y, event->wheel.windowID); + break; + case SDL_JOYBALLMOTION: + fprintf(stderr, "Joystick %d: ball %d moved by %d,%d", + event->jball.which, event->jball.ball, event->jball.xrel, + event->jball.yrel); + break; + case SDL_JOYHATMOTION: + fprintf(stderr, "Joystick %d: hat %d moved to ", event->jhat.which, + event->jhat.hat); + switch (event->jhat.value) { + case SDL_HAT_CENTERED: + fprintf(stderr, "CENTER"); + break; + case SDL_HAT_UP: + fprintf(stderr, "UP"); + break; + case SDL_HAT_RIGHTUP: + fprintf(stderr, "RIGHTUP"); + break; + case SDL_HAT_RIGHT: + fprintf(stderr, "RIGHT"); + break; + case SDL_HAT_RIGHTDOWN: + fprintf(stderr, "RIGHTDOWN"); + break; + case SDL_HAT_DOWN: + fprintf(stderr, "DOWN"); + break; + case SDL_HAT_LEFTDOWN: + fprintf(stderr, "LEFTDOWN"); + break; + case SDL_HAT_LEFT: + fprintf(stderr, "LEFT"); + break; + case SDL_HAT_LEFTUP: + fprintf(stderr, "LEFTUP"); + break; + default: + fprintf(stderr, "UNKNOWN"); + break; + } + break; + case SDL_JOYBUTTONDOWN: + fprintf(stderr, "Joystick %d: button %d pressed", + event->jbutton.which, event->jbutton.button); + break; + case SDL_JOYBUTTONUP: + fprintf(stderr, "Joystick %d: button %d released", + event->jbutton.which, event->jbutton.button); + break; + case SDL_CLIPBOARDUPDATE: + fprintf(stderr, "Clipboard updated"); + break; + case SDL_QUIT: + fprintf(stderr, "Quit requested"); + break; + case SDL_USEREVENT: + fprintf(stderr, "User event %d", event->user.code); + break; + default: + fprintf(stderr, "Unknown event %d", event->type); + break; + } + fprintf(stderr, "\n"); +} + +static void +SDLTest_ScreenShot(SDL_Renderer *renderer) +{ + SDL_Rect viewport; + SDL_Surface *surface; + + if (!renderer) { + return; + } + + SDL_RenderGetViewport(renderer, &viewport); + surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x00FF0000, 0x0000FF00, 0x000000FF, +#else + 0x000000FF, 0x0000FF00, 0x00FF0000, +#endif + 0x00000000); + if (!surface) { + fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError()); + return; + } + + if (SDL_RenderReadPixels(renderer, NULL, surface->format->format, + surface->pixels, surface->pitch) < 0) { + fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError()); + return; + } + + if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) { + fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError()); + return; + } +} + +void +SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) +{ + int i; + + if (state->verbose & VERBOSE_EVENT) { + SDLTest_PrintEvent(event); + } + + switch (event->type) { + case SDL_WINDOWEVENT: + switch (event->window.event) { + case SDL_WINDOWEVENT_SIZE_CHANGED: + { + SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); + if (window) { + for (i = 0; i < state->num_windows; ++i) { + if (window == state->windows[i] && + (state->window_flags & SDL_WINDOW_RESIZABLE)) { + SDL_Rect viewport; + + viewport.x = 0; + viewport.y = 0; + SDL_GetWindowSize(window, &viewport.w, &viewport.h); + SDL_RenderSetViewport(state->renderers[i], &viewport); + } + } + } + } + break; + case SDL_WINDOWEVENT_CLOSE: + { + SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); + if (window) { + SDL_DestroyWindow(window); + } + } + break; + } + break; + case SDL_KEYDOWN: + switch (event->key.keysym.sym) { + /* Add hotkeys here */ + case SDLK_PRINTSCREEN: { + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + for (i = 0; i < state->num_windows; ++i) { + if (window == state->windows[i]) { + SDLTest_ScreenShot(state->renderers[i]); + } + } + } + } + break; + case SDLK_EQUALS: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrt-+ double the size of the window */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + int w, h; + SDL_GetWindowSize(window, &w, &h); + SDL_SetWindowSize(window, w*2, h*2); + } + } + break; + case SDLK_MINUS: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrt-- double the size of the window */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + int w, h; + SDL_GetWindowSize(window, &w, &h); + SDL_SetWindowSize(window, w/2, h/2); + } + } + break; + case SDLK_c: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-C copy awesome text! */ + SDL_SetClipboardText("SDL rocks!\nYou know it!"); + printf("Copied text to clipboard\n"); + } + break; + case SDLK_v: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-V paste awesome text! */ + char *text = SDL_GetClipboardText(); + if (*text) { + printf("Clipboard: %s\n", text); + } else { + printf("Clipboard is empty\n"); + } + SDL_free(text); + } + break; + case SDLK_g: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-G toggle grab */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window)); + } + } + break; + case SDLK_m: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-M maximize */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + Uint32 flags = SDL_GetWindowFlags(window); + if (flags & SDL_WINDOW_MAXIMIZED) { + SDL_RestoreWindow(window); + } else { + SDL_MaximizeWindow(window); + } + } + } + break; + case SDLK_r: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-R toggle mouse relative mode */ + SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode()); + } + break; + case SDLK_z: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-Z minimize */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + SDL_MinimizeWindow(window); + } + } + break; + case SDLK_RETURN: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-Enter toggle fullscreen */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + Uint32 flags = SDL_GetWindowFlags(window); + if (flags & SDL_WINDOW_FULLSCREEN) { + SDL_SetWindowFullscreen(window, SDL_FALSE); + } else { + SDL_SetWindowFullscreen(window, SDL_TRUE); + } + } + } + break; + case SDLK_b: + if (event->key.keysym.mod & KMOD_CTRL) { + /* Ctrl-B toggle window border */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + const Uint32 flags = SDL_GetWindowFlags(window); + const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0); + SDL_SetWindowBordered(window, b); + } + } + break; + case SDLK_1: + if (event->key.keysym.mod & KMOD_CTRL) { + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window); + } + break; + case SDLK_ESCAPE: + *done = 1; + break; + default: + break; + } + break; + case SDL_QUIT: + *done = 1; + break; + } +} + +void +SDLTest_CommonQuit(SDLTest_CommonState * state) +{ + int i; + + if (state->windows) { + SDL_free(state->windows); + } + if (state->renderers) { + for (i = 0; i < state->num_windows; ++i) { + if (state->renderers[i]) { + SDL_DestroyRenderer(state->renderers[i]); + } + } + SDL_free(state->renderers); + } + if (state->flags & SDL_INIT_VIDEO) { + SDL_VideoQuit(); + } + if (state->flags & SDL_INIT_AUDIO) { + SDL_AudioQuit(); + } + SDL_free(state); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_crc32.c b/src/eepp/helper/SDL2/src/test/SDL_test_crc32.c new file mode 100644 index 000000000..17c4f0f59 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_crc32.c @@ -0,0 +1,165 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + + Used by the test execution component. + Original source code contributed by A. Schiffler for GSOC project. + +*/ + +#include "SDL_config.h" + +#include "SDL_test.h" + + +int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext) +{ + int i,j; + CrcUint32 c; + + /* Sanity check context pointer */ + if (crcContext==NULL) { + return -1; + } + + /* + * Build auxiliary table for parallel byte-at-a-time CRC-32 + */ +#ifdef ORIGINAL_METHOD + for (i = 0; i < 256; ++i) { + for (c = i << 24, j = 8; j > 0; --j) { + c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); + } + crcContext->crc32_table[i] = c; + } +#else + for (i=0; i<256; i++) { + c = i; + for (j=8; j>0; j--) { + if (c & 1) { + c = (c >> 1) ^ CRC32_POLY; + } else { + c >>= 1; + } + } + crcContext->crc32_table[i] = c; + } +#endif + + return 0; +} + +/* Complete CRC32 calculation on a memory block */ + +int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) +{ + if (SDLTest_Crc32CalcStart(crcContext,crc32)) { + return -1; + } + + if (SDLTest_Crc32CalcBuffer(crcContext, inBuf, inLen, crc32)) { + return -1; + } + + if (SDLTest_Crc32CalcEnd(crcContext, crc32)) { + return -1; + } + + return 0; +} + +/* Start crc calculation */ + +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32) +{ + /* Sanity check pointers */ + if (crcContext==NULL) { + *crc32=0; + return -1; + } + + /* + * Preload shift register, per CRC-32 spec + */ + *crc32 = 0xffffffff; + + return 0; +} + +/* Finish crc calculation */ + +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32) +{ + /* Sanity check pointers */ + if (crcContext==NULL) { + *crc32=0; + return -1; + } + + /* + * Return complement, per CRC-32 spec + */ + *crc32 = (~(*crc32)); + + return 0; +} + +/* Include memory block in crc */ + +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) +{ + CrcUint8 *p; + register CrcUint32 crc; + + if (crcContext==NULL) { + *crc32=0; + return -1; + } + + if (inBuf==NULL) { + return -1; + } + + /* + * Calculate CRC from data + */ + crc = *crc32; + for (p = inBuf; inLen > 0; ++p, --inLen) { +#ifdef ORIGINAL_METHOD + crc = (crc << 8) ^ crcContext->crc32_table[(crc >> 24) ^ *p]; +#else + crc = ((crc >> 8) & 0x00FFFFFF) ^ crcContext->crc32_table[ (crc ^ *p) & 0xFF ]; +#endif + } + *crc32 = crc; + + return 0; +} + +int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext) +{ + if (crcContext==NULL) { + return -1; + } + + return 0; +} diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_font.c b/src/eepp/helper/SDL2/src/test/SDL_test_font.c new file mode 100644 index 000000000..48f4dffe6 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_font.c @@ -0,0 +1,3238 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +#include "SDL_test.h" + +/* ---- 8x8 font definition ---- */ + +/* Originally part of SDL2_gfx */ + +/* ZLIB (c) A. Schiffler 2012 */ + +#define SDL_TESTFONTDATAMAX (8*256) + +static unsigned char SDLTest_FontData[SDL_TESTFONTDATAMAX] = { + + /* + * 0 0x00 '^@' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 1 0x01 '^A' + */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + + /* + * 2 0x02 '^B' + */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + + /* + * 3 0x03 '^C' + */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* + * 4 0x04 '^D' + */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* + * 5 0x05 '^E' + */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* + * 6 0x06 '^F' + */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* + * 7 0x07 '^G' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 8 0x08 '^H' + */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* + * 9 0x09 '^I' + */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 10 0x0a '^J' + */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + + /* + * 11 0x0b '^K' + */ + 0x0f, /* 00001111 */ + 0x07, /* 00000111 */ + 0x0f, /* 00001111 */ + 0x7d, /* 01111101 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + + /* + * 12 0x0c '^L' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + + /* + * 13 0x0d '^M' + */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + + /* + * 14 0x0e '^N' + */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + + /* + * 15 0x0f '^O' + */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + + /* + * 16 0x10 '^P' + */ + 0x80, /* 10000000 */ + 0xe0, /* 11100000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xe0, /* 11100000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* + * 17 0x11 '^Q' + */ + 0x02, /* 00000010 */ + 0x0e, /* 00001110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x0e, /* 00001110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* + * 18 0x12 '^R' + */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + + /* + * 19 0x13 '^S' + */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* + * 20 0x14 '^T' + */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + + /* + * 21 0x15 '^U' + */ + 0x3e, /* 00111110 */ + 0x61, /* 01100001 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x86, /* 10000110 */ + 0x7c, /* 01111100 */ + + /* + * 22 0x16 '^V' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 23 0x17 '^W' + */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + + /* + * 24 0x18 '^X' + */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 25 0x19 '^Y' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 26 0x1a '^Z' + */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 27 0x1b '^[' + */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 28 0x1c '^\' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 29 0x1d '^]' + */ + 0x00, /* 00000000 */ + 0x24, /* 00100100 */ + 0x66, /* 01100110 */ + 0xff, /* 11111111 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 30 0x1e '^^' + */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 31 0x1f '^_' + */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 32 0x20 ' ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 33 0x21 '!' + */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 34 0x22 '"' + */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 35 0x23 '#' + */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* + * 36 0x24 '$' + */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x60, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 37 0x25 '%' + */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 38 0x26 '&' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 39 0x27 ''' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 40 0x28 '(' + */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* + * 41 0x29 ')' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 42 0x2a '*' + */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 43 0x2b '+' + */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 44 0x2c ',' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* + * 45 0x2d '-' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 46 0x2e '.' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 47 0x2f '/' + */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* + * 48 0x30 '0' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* + * 49 0x31 '1' + */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 50 0x32 '2' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 51 0x33 '3' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 52 0x34 '4' + */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* + * 53 0x35 '5' + */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 54 0x36 '6' + */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 55 0x37 '7' + */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 56 0x38 '8' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 57 0x39 '9' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 58 0x3a ':' + */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 59 0x3b ';' + */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* + * 60 0x3c '<' + */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + + /* + * 61 0x3d '=' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 62 0x3e '>' + */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* + * 63 0x3f '?' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 64 0x40 '@' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 65 0x41 'A' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 66 0x42 'B' + */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 67 0x43 'C' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 68 0x44 'D' + */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* + * 69 0x45 'E' + */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 70 0x46 'F' + */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 71 0x47 'G' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + + /* + * 72 0x48 'H' + */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 73 0x49 'I' + */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 74 0x4a 'J' + */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 75 0x4b 'K' + */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 76 0x4c 'L' + */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 77 0x4d 'M' + */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 78 0x4e 'N' + */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 79 0x4f 'O' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 80 0x50 'P' + */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 81 0x51 'Q' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xce, /* 11001110 */ + 0x7c, /* 01111100 */ + 0x0e, /* 00001110 */ + + /* + * 82 0x52 'R' + */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 83 0x53 'S' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 84 0x54 'T' + */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 85 0x55 'U' + */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 86 0x56 'V' + */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* + * 87 0x57 'W' + */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* + * 88 0x58 'X' + */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 89 0x59 'Y' + */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 90 0x5a 'Z' + */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x8c, /* 10001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 91 0x5b '[' + */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 92 0x5c '\' + */ + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* + * 93 0x5d ']' + */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 94 0x5e '^' + */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 95 0x5f '_' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + + /* + * 96 0x60 '`' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 97 0x61 'a' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 98 0x62 'b' + */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + + /* + * 99 0x63 'c' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 100 0x64 'd' + */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 101 0x65 'e' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 102 0x66 'f' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf8, /* 11111000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 103 0x67 'g' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + + /* + * 104 0x68 'h' + */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 105 0x69 'i' + */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 106 0x6a 'j' + */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + + /* + * 107 0x6b 'k' + */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 108 0x6c 'l' + */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 109 0x6d 'm' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0x00, /* 00000000 */ + + /* + * 110 0x6e 'n' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* + * 111 0x6f 'o' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 112 0x70 'p' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + + /* + * 113 0x71 'q' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + + /* + * 114 0x72 'r' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 115 0x73 's' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 116 0x74 't' + */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + + /* + * 117 0x75 'u' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 118 0x76 'v' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* + * 119 0x77 'w' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* + * 120 0x78 'x' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 121 0x79 'y' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* + * 122 0x7a 'z' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x4c, /* 01001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 123 0x7b '{' + */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + + /* + * 124 0x7c '|' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 125 0x7d '}' + */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* + * 126 0x7e '~' + */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 127 0x7f '' + */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 128 0x80 '€' + */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + + /* + * 129 0x81 '' + */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 130 0x82 '‚' + */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 131 0x83 'ƒ' + */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 132 0x84 '„' + */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 133 0x85 '…' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 134 0x86 '†' + */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 135 0x87 '‡' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + + /* + * 136 0x88 'ˆ' + */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 137 0x89 '‰' + */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 138 0x8a 'Š' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 139 0x8b '‹' + */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 140 0x8c 'Œ' + */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 141 0x8d '' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 142 0x8e 'Ž' + */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 143 0x8f '' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 144 0x90 '' + */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 145 0x91 '‘' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 146 0x92 '’' + */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* + * 147 0x93 '“' + */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 148 0x94 '”' + */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 149 0x95 '•' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 150 0x96 '–' + */ + 0x78, /* 01111000 */ + 0x84, /* 10000100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 151 0x97 '—' + */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 152 0x98 '˜' + */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* + * 153 0x99 '™' + */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* + * 154 0x9a 'š' + */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 155 0x9b '›' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 156 0x9c 'œ' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 157 0x9d '' + */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 158 0x9e 'ž' + */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfa, /* 11111010 */ + 0xc6, /* 11000110 */ + 0xcf, /* 11001111 */ + 0xc6, /* 11000110 */ + 0xc7, /* 11000111 */ + + /* + * 159 0x9f 'Ÿ' + */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* + * 160 0xa0 ' ' + */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 161 0xa1 '¡' + */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 162 0xa2 '¢' + */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 163 0xa3 '£' + */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 164 0xa4 '¤' + */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* + * 165 0xa5 '¥' + */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* + * 166 0xa6 '¦' + */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 167 0xa7 '§' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 168 0xa8 '¨' + */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x63, /* 01100011 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + + /* + * 169 0xa9 '©' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 170 0xaa 'ª' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 171 0xab '«' + */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7e, /* 01111110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x0f, /* 00001111 */ + + /* + * 172 0xac '¬' + */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7a, /* 01111010 */ + 0x36, /* 00110110 */ + 0x6a, /* 01101010 */ + 0xdf, /* 11011111 */ + 0x06, /* 00000110 */ + + /* + * 173 0xad '­' + */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 174 0xae '®' + */ + 0x00, /* 00000000 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 175 0xaf '¯' + */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 176 0xb0 '°' + */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + + /* + * 177 0xb1 '±' + */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* + * 178 0xb2 '²' + */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + + /* + * 179 0xb3 '³' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 180 0xb4 '´' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 181 0xb5 'µ' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 182 0xb6 '¶' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 183 0xb7 '·' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 184 0xb8 '¸' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 185 0xb9 '¹' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 186 0xba 'º' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 187 0xbb '»' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 188 0xbc '¼' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 189 0xbd '½' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 190 0xbe '¾' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 191 0xbf '¿' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 192 0xc0 'À' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 193 0xc1 'Á' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 194 0xc2 'Â' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 195 0xc3 'Ã' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 196 0xc4 'Ä' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 197 0xc5 'Å' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 198 0xc6 'Æ' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 199 0xc7 'Ç' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 200 0xc8 'È' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 201 0xc9 'É' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 202 0xca 'Ê' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 203 0xcb 'Ë' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 204 0xcc 'Ì' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 205 0xcd 'Í' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 206 0xce 'Î' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 207 0xcf 'Ï' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 208 0xd0 'Ð' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 209 0xd1 'Ñ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 210 0xd2 'Ò' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 211 0xd3 'Ó' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 212 0xd4 'Ô' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 213 0xd5 'Õ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 214 0xd6 'Ö' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 215 0xd7 '×' + */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* + * 216 0xd8 'Ø' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 217 0xd9 'Ù' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 218 0xda 'Ú' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 219 0xdb 'Û' + */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* + * 220 0xdc 'Ü' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* + * 221 0xdd 'Ý' + */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* + * 222 0xde 'Þ' + */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* + * 223 0xdf 'ß' + */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 224 0xe0 'à' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xc8, /* 11001000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 225 0xe1 'á' + */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 226 0xe2 'â' + */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* + * 227 0xe3 'ã' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* + * 228 0xe4 'ä' + */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 229 0xe5 'å' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* + * 230 0xe6 'æ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0xc0, /* 11000000 */ + + /* + * 231 0xe7 'ç' + */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 232 0xe8 'è' + */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + + /* + * 233 0xe9 'é' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* + * 234 0xea 'ê' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + + /* + * 235 0xeb 'ë' + */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 236 0xec 'ì' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 237 0xed 'í' + */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + + /* + * 238 0xee 'î' + */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* + * 239 0xef 'ï' + */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 240 0xf0 'ð' + */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 241 0xf1 'ñ' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 242 0xf2 'ò' + */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 243 0xf3 'ó' + */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 244 0xf4 'ô' + */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 245 0xf5 'õ' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + + /* + * 246 0xf6 'ö' + */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 247 0xf7 '÷' + */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 248 0xf8 'ø' + */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 249 0xf9 'ù' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 250 0xfa 'ú' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 251 0xfb 'û' + */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + + /* + * 252 0xfc 'ü' + */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 253 0xfd 'ý' + */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 254 0xfe 'þ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 255 0xff ' ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; + + +/* ---- Character */ + +/*! +\brief Global cache for 8x8 pixel font textures created at runtime. +*/ +static SDL_Texture *SDLTest_CharTextureCache[256]; + +int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c) +{ + const Uint32 charWidth = 8; + const Uint32 charHeight = 8; + const Uint32 charSize = 8; + SDL_Rect srect; + SDL_Rect drect; + int result; + Uint32 ix, iy; + const unsigned char *charpos; + Uint8 *curpos; + Uint8 patt, mask; + Uint8 *linepos; + Uint32 pitch; + SDL_Surface *character; + Uint32 ci; + Uint8 r, g, b, a; + + /* + * Setup source rectangle + */ + srect.x = 0; + srect.y = 0; + srect.w = charWidth; + srect.h = charHeight; + + /* + * Setup destination rectangle + */ + drect.x = x; + drect.y = y; + drect.w = charWidth; + drect.h = charHeight; + + /* Character index in cache */ + ci = (unsigned char)c; + + /* + * Create new charWidth x charHeight bitmap surface if not already present. + */ + if (SDLTest_CharTextureCache[ci] == NULL) { + /* + * Redraw character into surface + */ + character = SDL_CreateRGBSurface(SDL_SWSURFACE, + charWidth, charHeight, 32, + 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); + if (character == NULL) { + return (-1); + } + + charpos = SDLTest_FontData + ci * charSize; + linepos = (Uint8 *)character->pixels; + pitch = character->pitch; + + /* + * Drawing loop + */ + patt = 0; + for (iy = 0; iy < charWidth; iy++) { + mask = 0x00; + curpos = linepos; + for (ix = 0; ix < charWidth; ix++) { + if (!(mask >>= 1)) { + patt = *charpos++; + mask = 0x80; + } + if (patt & mask) { + *(Uint32 *)curpos = 0xffffffff; + } else { + *(Uint32 *)curpos = 0; + } + curpos += 4; + } + linepos += pitch; + } + + /* Convert temp surface into texture */ + SDLTest_CharTextureCache[ci] = SDL_CreateTextureFromSurface(renderer, character); + SDL_FreeSurface(character); + + /* + * Check pointer + */ + if (SDLTest_CharTextureCache[ci] == NULL) { + return (-1); + } + } + + /* + * Set color + */ + result = 0; + result |= SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a); + result |= SDL_SetTextureColorMod(SDLTest_CharTextureCache[ci], r, g, b); + result |= SDL_SetTextureAlphaMod(SDLTest_CharTextureCache[ci], a); + + /* + * Draw texture onto destination + */ + result |= SDL_RenderCopy(renderer, SDLTest_CharTextureCache[ci], &srect, &drect); + + return (result); +} + +int SDLTest_DrawString(SDL_Renderer * renderer, int x, int y, const char *s) +{ + const Uint32 charWidth = 8; + int result = 0; + int curx = x; + int cury = y; + const char *curchar = s; + + while (*curchar && !result) { + result |= SDLTest_DrawCharacter(renderer, curx, cury, *curchar); + curx += charWidth; + curchar++; + } + + return (result); +} + diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_fuzzer.c b/src/eepp/helper/SDL2/src/test/SDL_test_fuzzer.c new file mode 100644 index 000000000..a25a8c260 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_fuzzer.c @@ -0,0 +1,637 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + + Data generators for fuzzing test data in a reproducible way. + +*/ + +#include "SDL_config.h" + +#include +#include +#include +#include +#include + +#include "SDL_test.h" + +/** + *Counter for fuzzer invocations + */ +static int fuzzerInvocationCounter; + +/** + * Context for shared random number generator + */ +static SDLTest_RandomContext rndContext; + +/* + * Note: doxygen documentation markup for functions is in the header file. + */ + +void +SDLTest_FuzzerInit(Uint64 execKey) +{ + Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF; + Uint32 b = execKey & 0x00000000FFFFFFFF; + SDLTest_RandomInit(&rndContext, a, b); +} + +int +SDLTest_GetInvocationCount() +{ + return fuzzerInvocationCounter; +} + +Uint8 +SDLTest_RandomUint8() +{ + fuzzerInvocationCounter++; + + return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF; +} + +Sint8 +SDLTest_RandomSint8() +{ + fuzzerInvocationCounter++; + + return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF; +} + +Uint16 +SDLTest_RandomUint16() +{ + fuzzerInvocationCounter++; + + return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF; +} + +Sint16 +SDLTest_RandomSint16() +{ + fuzzerInvocationCounter++; + + return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF; +} + +Sint32 +SDLTest_RandomSint32() +{ + fuzzerInvocationCounter++; + + return (Sint32) SDLTest_RandomInt(&rndContext); +} + +Uint32 +SDLTest_RandomUint32() +{ + fuzzerInvocationCounter++; + + return (Uint32) SDLTest_RandomInt(&rndContext); +} + +Uint64 +SDLTest_RandomUint64() +{ + Uint64 value; + Uint32 *vp = (void*)&value; + + fuzzerInvocationCounter++; + + vp[0] = SDLTest_RandomSint32(); + vp[1] = SDLTest_RandomSint32(); + + return value; +} + +Sint64 +SDLTest_RandomSint64() +{ + Uint64 value; + Uint32 *vp = (void*)&value; + + fuzzerInvocationCounter++; + + vp[0] = SDLTest_RandomSint32(); + vp[1] = SDLTest_RandomSint32(); + + return value; +} + + + +Sint32 +SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax) +{ + Sint64 min = pMin; + Sint64 max = pMax; + Sint64 temp; + Sint64 number; + + if(pMin > pMax) { + temp = min; + min = max; + max = temp; + } else if(pMin == pMax) { + return (Sint32)min; + } + + number = SDLTest_RandomUint32(); // invocation count increment in there + + return (Sint32)((number % ((max + 1) - min)) + min); +} + +/*! + * Generates boundary values between the given boundaries. + * Boundary values are inclusive. See the examples below. + * If boundary2 < boundary1, the values are swapped. + * If boundary1 == boundary2, value of boundary1 will be returned + * + * Generating boundary values for Uint8: + * BoundaryValues(sizeof(Uint8), 10, 20, True) -> [10,11,19,20] + * BoundaryValues(sizeof(Uint8), 10, 20, False) -> [9,21] + * BoundaryValues(sizeof(Uint8), 0, 15, True) -> [0, 1, 14, 15] + * BoundaryValues(sizeof(Uint8), 0, 15, False) -> [16] + * BoundaryValues(sizeof(Uint8), 0, 255, False) -> NULL + * + * Generator works the same for other types of unsigned integers. + * + * Note: outBuffer will be allocated and needs to be freed later. + * If outbuffer != NULL, it'll be freed. + * + * \param maxValue The biggest value that is acceptable for this data type. + * For instance, for Uint8 -> 255, Uint16 -> 65536 etc. + * \param pBoundary1 defines lower boundary + * \param pBoundary2 defines upper boundary + * \param validDomain Generate only for valid domain (for the data type) + * + * \param outBuffer The generated boundary values are put here + * + * \returns Returns the number of elements in outBuffer or -1 in case of error + */ +Uint32 +SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, + Uint64 pBoundary1, Uint64 pBoundary2, SDL_bool validDomain, + Uint64 *outBuffer) +{ + Uint64 boundary1 = pBoundary1, boundary2 = pBoundary2; + Uint64 temp; + Uint64 tempBuf[4]; + int index; + + if(outBuffer != NULL) { + SDL_free(outBuffer); + } + + if(boundary1 > boundary2) { + temp = boundary1; + boundary1 = boundary2; + boundary2 = temp; + } + + index = 0; + if(boundary1 == boundary2) { + tempBuf[index++] = boundary1; + } + else if(validDomain) { + tempBuf[index++] = boundary1; + + if(boundary1 < UINT64_MAX) + tempBuf[index++] = boundary1 + 1; + + tempBuf[index++] = boundary2 - 1; + tempBuf[index++] = boundary2; + } + else { + if(boundary1 > 0) { + tempBuf[index++] = boundary1 - 1; + } + + if(boundary2 < maxValue && boundary2 < UINT64_MAX) { + tempBuf[index++] = boundary2 + 1; + } + } + + if(index == 0) { + // There are no valid boundaries + return 0; + } + + // Create the return buffer + outBuffer = (Uint64 *)SDL_malloc(index * sizeof(Uint64)); + if(outBuffer == NULL) { + return 0; + } + + SDL_memcpy(outBuffer, tempBuf, index * sizeof(Uint64)); + + return index; +} + +Uint8 +SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain) +{ + Uint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Uint8 retVal; + + // max value for Uint8 + const Uint64 maxValue = UINT8_MAX; + + size = SDLTest_GenerateUnsignedBoundaryValues(maxValue, + (Uint64) boundary1, (Uint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return 0; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Uint8)buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +Uint16 +SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain) +{ + Uint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Uint16 retVal; + + // max value for Uint16 + const Uint64 maxValue = UINT16_MAX; + + size = SDLTest_GenerateUnsignedBoundaryValues(maxValue, + (Uint64) boundary1, (Uint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return 0; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Uint16) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +Uint32 +SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain) +{ + Uint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Uint32 retVal; + + // max value for Uint32 + const Uint64 maxValue = UINT32_MAX; + + size = SDLTest_GenerateUnsignedBoundaryValues(maxValue, + (Uint64) boundary1, (Uint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return 0; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Uint32) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +Uint64 +SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain) +{ + Uint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Uint64 retVal; + + // max value for Uint64 + const Uint64 maxValue = UINT64_MAX; + + size = SDLTest_GenerateUnsignedBoundaryValues(maxValue, + (Uint64) boundary1, (Uint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return 0; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Uint64) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +/*! + * Generates boundary values between the given boundaries. + * Boundary values are inclusive. See the examples below. + * If boundary2 < boundary1, the values are swapped. + * If boundary1 == boundary2, value of boundary1 will be returned + * + * Generating boundary values for Sint8: + * SignedBoundaryValues(sizeof(Sint8), -10, 20, True) -> [-11,-10,19,20] + * SignedBoundaryValues(sizeof(Sint8), -10, 20, False) -> [-11,21] + * SignedBoundaryValues(sizeof(Sint8), -30, -15, True) -> [-30, -29, -16, -15] + * SignedBoundaryValues(sizeof(Sint8), -128, 15, False) -> [16] + * SignedBoundaryValues(sizeof(Sint8), -128, 127, False) -> NULL + * + * Generator works the same for other types of signed integers. + * + * Note: outBuffer will be allocated and needs to be freed later. + * If outbuffer != NULL, it'll be freed. + * + * + * \param minValue The smallest value that is acceptable for this data type. + * For instance, for Uint8 -> -128, Uint16 -> -32,768 etc. + * \param maxValue The biggest value that is acceptable for this data type. + * For instance, for Uint8 -> 127, Uint16 -> 32767 etc. + * \param pBoundary1 defines lower boundary + * \param pBoundary2 defines upper boundary + * \param validDomain Generate only for valid domain (for the data type) + * + * \param outBuffer The generated boundary values are put here + * + * \returns Returns the number of elements in outBuffer or -1 in case of error + */ +Uint32 +SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, + Sint64 pBoundary1, Sint64 pBoundary2, SDL_bool validDomain, + Sint64 *outBuffer) +{ + int index; + Sint64 tempBuf[4]; + Sint64 boundary1 = pBoundary1, boundary2 = pBoundary2; + + if(outBuffer != NULL) { + SDL_free(outBuffer); + } + + if(boundary1 > boundary2) { + Sint64 temp = boundary1; + boundary1 = boundary2; + boundary2 = temp; + } + + index = 0; + if(boundary1 == boundary2) { + tempBuf[index++] = boundary1; + } + else if(validDomain) { + tempBuf[index++] = boundary1; + + if(boundary1 < LLONG_MAX) + tempBuf[index++] = boundary1 + 1; + + if(boundary2 > LLONG_MIN) + tempBuf[index++] = boundary2 - 1; + + tempBuf[index++] = boundary2; + } + else { + if(boundary1 > minValue && boundary1 > LLONG_MIN) { + tempBuf[index++] = boundary1 - 1; + } + + if(boundary2 < maxValue && boundary2 < UINT64_MAX) { + tempBuf[index++] = boundary2 + 1; + } + } + + if(index == 0) { + // There are no valid boundaries + return 0; + } + + // Create the return buffer + outBuffer = (Sint64 *)SDL_malloc(index * sizeof(Sint64)); + if(outBuffer == NULL) { + return 0; + } + + SDL_memcpy((void *)outBuffer, (void *)tempBuf, index * sizeof(Sint64)); + + return (Uint32)index; +} + +Sint8 +SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain) +{ + // min & max values for Sint8 + const Sint64 maxValue = CHAR_MAX; + const Sint64 minValue = CHAR_MIN; + + Sint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Sint8 retVal; + + size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, + (Sint64) boundary1, (Sint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return CHAR_MIN; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Sint8) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +Sint16 +SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain) +{ + // min & max values for Sint16 + const Sint64 maxValue = SHRT_MAX; + const Sint64 minValue = SHRT_MIN; + Sint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Sint16 retVal; + + size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, + (Sint64) boundary1, (Sint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return SHRT_MIN; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Sint16) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +Sint32 +SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain) +{ + // min & max values for Sint32 + const Sint64 maxValue = INT_MAX; + const Sint64 minValue = INT_MIN; + + Sint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Sint32 retVal; + + size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, + (Sint64) boundary1, (Sint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return INT_MIN; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Sint32) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +Sint64 +SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain) +{ + Sint64 *buffer = NULL; + Uint32 size; + Uint32 index; + Sint64 retVal; + + // min & max values for Sint64 + const Sint64 maxValue = LLONG_MAX; + const Sint64 minValue = LLONG_MIN; + + size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, + (Sint64) boundary1, (Sint64) boundary2, + validDomain, buffer); + if (buffer == NULL || size == 0) { + return LLONG_MIN; + } + + index = SDLTest_RandomSint32() % size; + retVal = (Sint64) buffer[index]; + + SDL_free(buffer); + + fuzzerInvocationCounter++; + + return retVal; +} + +float +SDLTest_RandomUnitFloat() +{ + return (float) SDLTest_RandomUint32() / UINT_MAX; +} + +float +SDLTest_RandomFloat() +{ + return (float) (FLT_MIN + SDLTest_RandomUnitDouble() * (FLT_MAX - FLT_MIN)); +} + +double +SDLTest_RandomUnitDouble() +{ + return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0); +} + +double +SDLTest_RandomDouble() +{ + double r = 0.0; + double s = 1.0; + do { + s /= UINT_MAX + 1.0; + r += (double)SDLTest_RandomInt(&rndContext) * s; + } while (s > DBL_EPSILON); + + fuzzerInvocationCounter++; + + return r; +} + + +char * +SDLTest_RandomAsciiString() +{ + // note: fuzzerInvocationCounter is increment in the RandomAsciiStringWithMaximumLenght + return SDLTest_RandomAsciiStringWithMaximumLength(255); +} + +char * +SDLTest_RandomAsciiStringWithMaximumLength(int maxSize) +{ + int size; + char *string; + int counter; + + fuzzerInvocationCounter++; + + if(maxSize < 1) { + return NULL; + } + + size = (SDLTest_RandomUint32() % (maxSize + 1)) + 1; + string = (char *)SDL_malloc(size * sizeof(char)); + if (string==NULL) { + return NULL; + } + + for(counter = 0; counter < size; ++counter) { + string[counter] = (char)SDLTest_RandomIntegerInRange(1, 127); + } + + string[counter] = '\0'; + + return string; +} diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_harness.c b/src/eepp/helper/SDL2/src/test/SDL_test_harness.c new file mode 100644 index 000000000..15b721f86 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_harness.c @@ -0,0 +1,454 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#include "SDL_test.h" + +#include +#include +#include +#include + +/* Assert check message format */ +const char *SDLTest_TestCheckFmt = "Test '%s': %s"; + +/* Invalid test name/description message format */ +const char *SDLTest_InvalidNameFmt = "(Invalid)"; + +/*! \brief Timeout for single test case execution */ +static Uint32 SDLTest_TestCaseTimeout = 3600; + +/** + * Generates a random run seed string for the harness. The generated seed + * will contain alphanumeric characters (0-9A-Z). + * + * Note: The returned string needs to be deallocated by the caller. + * + * \param length The length of the seed string to generate + * + * \returns The generated seed string + */ +char * +SDLTest_GenerateRunSeed(const int length) +{ + char *seed = NULL; + SDLTest_RandomContext randomContext; + int counter; + + // Sanity check input + if (length <= 0) { + SDLTest_LogError("The length of the harness seed must be >0."); + return NULL; + } + + // Allocate output buffer + seed = (char *)SDL_malloc((length + 1) * sizeof(char)); + if (seed == NULL) { + SDLTest_LogError("SDL_malloc for run seed output buffer failed."); + return NULL; + } + + // Generate a random string of alphanumeric characters + SDLTest_RandomInitTime(&randomContext); + for (counter = 0; counter < length - 1; ++counter) { + unsigned int number = SDLTest_Random(&randomContext); + char ch = (char) (number % (91 - 48)) + 48; + if (ch >= 58 && ch <= 64) { + ch = 65; + } + seed[counter] = ch; + } + seed[counter] = '\0'; + + return seed; +} + +/** + * Generates an execution key for the fuzzer. + * + * \param runSeed The run seed to use + * \param suiteName The name of the test suite + * \param testName The name of the test + * \param iteration The iteration count + * + * \returns The generated execution key to initialize the fuzzer with. + * + */ +Uint64 +SDLTest_GenerateExecKey(char *runSeed, char *suiteName, char *testName, int iteration) +{ + SDLTest_Md5Context md5Context; + Uint64 *keys; + char iterationString[16]; + Uint32 runSeedLength; + Uint32 suiteNameLength; + Uint32 testNameLength; + Uint32 iterationStringLength; + Uint32 entireStringLength; + char *buffer; + + if (runSeed == NULL || strlen(runSeed)==0) { + SDLTest_LogError("Invalid runSeed string."); + return -1; + } + + if (suiteName == NULL || strlen(suiteName)==0) { + SDLTest_LogError("Invalid suiteName string."); + return -1; + } + + if (testName == NULL || strlen(testName)==0) { + SDLTest_LogError("Invalid testName string."); + return -1; + } + + if (iteration <= 0) { + SDLTest_LogError("Invalid iteration count."); + return -1; + } + + // Convert iteration number into a string + memset(iterationString, 0, sizeof(iterationString)); + SDL_snprintf(iterationString, sizeof(iterationString) - 1, "%d", iteration); + + // Combine the parameters into single string + runSeedLength = strlen(runSeed); + suiteNameLength = strlen(suiteName); + testNameLength = strlen(testName); + iterationStringLength = strlen(iterationString); + entireStringLength = runSeedLength + suiteNameLength + testNameLength + iterationStringLength + 1; + buffer = (char *)SDL_malloc(entireStringLength); + if (buffer == NULL) { + SDLTest_LogError("SDL_malloc failed to allocate buffer for execKey generation."); + return 0; + } + SDL_snprintf(buffer, entireStringLength, "%s%s%s%d", runSeed, suiteName, testName, iteration); + + // Hash string and use half of the digest as 64bit exec key + SDLTest_Md5Init(&md5Context); + SDLTest_Md5Update(&md5Context, (unsigned char *)buffer, entireStringLength); + SDLTest_Md5Final(&md5Context); + SDL_free(buffer); + keys = (Uint64 *)md5Context.digest; + + return keys[0]; +} + +/** + * \brief Set timeout handler for test. + * + * Note: SDL_Init(SDL_INIT_TIMER) will be called if it wasn't done so before. + * + * \param timeout Timeout interval in seconds. + * \param callback Function that will be called after timeout has elapsed. + * + * \return Timer id or -1 on failure. + */ +SDL_TimerID +SDLTest_SetTestTimeout(int timeout, void (*callback)()) +{ + Uint32 timeoutInMilliseconds; + SDL_TimerID timerID; + + if (callback == NULL) { + SDLTest_LogError("Timeout callback can't be NULL"); + return -1; + } + + if (timeout < 0) { + SDLTest_LogError("Timeout value must be bigger than zero."); + return -1; + } + + /* Init SDL timer if not initialized before */ + if (SDL_WasInit(SDL_INIT_TIMER) == 0) { + if (SDL_InitSubSystem(SDL_INIT_TIMER)) { + SDLTest_LogError("Failed to init timer subsystem: %s", SDL_GetError()); + return -1; + } + } + + /* Set timer */ + timeoutInMilliseconds = timeout * 1000; + timerID = SDL_AddTimer(timeoutInMilliseconds, (SDL_TimerCallback)callback, 0x0); + if (timerID == 0) { + SDLTest_LogError("Creation of SDL timer failed: %s", SDL_GetError()); + return -1; + } + + return timerID; +} + +void +SDLTest_BailOut() +{ + SDLTest_LogError("TestCaseTimeout timer expired. Aborting test run."); + exit(TEST_ABORTED); // bail out from the test +} + +/** + * \brief Execute a test using the given execution key. + * + * \param testSuite Suite containing the test case. + * \param testCase Case to execute. + * \param execKey Execution key for the fuzzer. + * + * \returns Test case result. + */ +int +SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, SDLTest_TestCaseReference *testCase, Uint64 execKey) +{ + SDL_TimerID timer = 0; + int testResult = 0; + + if (testSuite==NULL || testCase==NULL || testSuite->name==NULL || testCase->name==NULL) + { + SDLTest_LogError("Setup failure: testSuite or testCase references NULL"); + return TEST_RESULT_SETUP_FAILURE; + } + + if (!testCase->enabled) + { + SDLTest_Log((char *)SDLTest_TestCheckFmt, testCase->name, "Skipped"); + return TEST_RESULT_SKIPPED; + } + + // Initialize fuzzer + SDLTest_FuzzerInit(execKey); + + // Reset assert tracker + SDLTest_ResetAssertSummary(); + + // Set timeout timer + timer = SDLTest_SetTestTimeout(SDLTest_TestCaseTimeout, SDLTest_BailOut); + + // Maybe run suite initalizer function + if (testSuite->testSetUp) { + testSuite->testSetUp(0x0); + if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) { + SDLTest_LogError((char *)SDLTest_TestCheckFmt, testSuite->name, "Failed"); + return TEST_RESULT_SETUP_FAILURE; + } + } + + // Run test case function + testCase->testCase(0x0); + testResult = SDLTest_AssertSummaryToTestResult(); + + // Maybe run suite cleanup function (ignore failed asserts) + if (testSuite->testTearDown) { + testSuite->testTearDown(0x0); + } + + // Cancel timeout timer + if (timer) { + SDL_RemoveTimer(timer); + } + + // Report on asserts and fuzzer usage + SDLTest_Log("Fuzzer invocations: %d", SDLTest_GetFuzzerInvocationCount()); + SDLTest_LogAssertSummary(); + + // Analyze assert count to determine final test case result + switch (testResult) { + case TEST_RESULT_PASSED: + SDLTest_LogError((char *)SDLTest_TestCheckFmt, testCase->name, "Failed"); + case TEST_RESULT_FAILED: + SDLTest_Log((char *)SDLTest_TestCheckFmt, testCase->name, "Passed"); + case TEST_RESULT_NO_ASSERT: + SDLTest_LogError((char *)SDLTest_TestCheckFmt, testCase->name, "No Asserts"); + } + + return testResult; +} + +/* Prints summary of all suites/tests contained in the given reference */ +void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) +{ + int suiteCounter; + int testCounter; + SDLTest_TestSuiteReference *testSuite; + SDLTest_TestCaseReference *testCase; + + // Loop over all suites + suiteCounter = 0; + while(&testSuites[suiteCounter]) { + testSuite=&testSuites[suiteCounter]; + suiteCounter++; + SDLTest_Log("Test Suite %i - %s\n", suiteCounter, + (testSuite->name) ? testSuite->name : SDLTest_InvalidNameFmt); + + // Loop over all test cases + testCounter = 0; + while(testSuite->testCases[testCounter]) + { + testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; + testCounter++; + SDLTest_Log(" Test Case %i - %s: %s", testCounter, + (testCase->name) ? testCase->name : SDLTest_InvalidNameFmt, + (testCase->description) ? testCase->description : SDLTest_InvalidNameFmt); + } + } +} + + +/** + * \brief Execute a test using the given execution key. + * + * \param testSuites Suites containing the test case. + * \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one. + * \param userExecKey Custom execution key provided by user, or 0 to autogenerate one. + * \param testIterations Number of iterations to run each test case. + * + * \returns Test run result; 0 when all tests passed, 1 if any tests failed. + */ +int +SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites, char *userRunSeed, Uint64 userExecKey, int testIterations) +{ + int suiteCounter; + int testCounter; + int iterationCounter; + SDLTest_TestSuiteReference *testSuite; + SDLTest_TestCaseReference *testCase; + char *runSeed = NULL; + Uint64 execKey; + Uint32 runStartTicks; + time_t runStartTimestamp; + Uint32 suiteStartTicks; + time_t suiteStartTimestamp; + Uint32 testStartTicks; + time_t testStartTimestamp; + Uint32 runEndTicks; + time_t runEndTimestamp; + Uint32 suiteEndTicks; + time_t suiteEndTimestamp; + Uint32 testEndTicks; + time_t testEndTimestamp; + int testResult; + int totalTestFailedCount, totalTestPassedCount, totalTestSkippedCount; + int testFailedCount, testPassedCount, testSkippedCount; + + // Sanitize test iterations + if (testIterations < 1) { + testIterations = 1; + } + + // Generate run see if we don't have one already + if (userRunSeed == NULL || strlen(userRunSeed) == 0) { + runSeed = SDLTest_GenerateRunSeed(16); + if (runSeed == NULL) { + SDLTest_LogError("Generating a random run seed failed"); + return 2; + } + } + + // Reset per-run counters + totalTestFailedCount = totalTestPassedCount = totalTestSkippedCount = 0; + + // Take time - run start + runStartTicks = SDL_GetTicks(); + runStartTimestamp = time(0); + + // TODO log run started + + // Loop over all suites + suiteCounter = 0; + while(&testSuites[suiteCounter]) { + testSuite=&testSuites[suiteCounter]; + suiteCounter++; + + // Reset per-suite counters + testFailedCount = testPassedCount = testSkippedCount = 0; + + // Take time - suite start + suiteStartTicks = SDL_GetTicks(); + suiteStartTimestamp = time(0); + + // TODO log suite started + SDLTest_Log("Test Suite %i - %s\n", suiteCounter, + (testSuite->name) ? testSuite->name : SDLTest_InvalidNameFmt); + + // Loop over all test cases + testCounter = 0; + while(testSuite->testCases[testCounter]) + { + testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; + testCounter++; + + // Take time - test start + testStartTicks = SDL_GetTicks(); + testStartTimestamp = time(0); + + // TODO log test started + SDLTest_Log("Test Case %i - %s: %s", testCounter, + (testCase->name) ? testCase->name : SDLTest_InvalidNameFmt, + (testCase->description) ? testCase->description : SDLTest_InvalidNameFmt); + + // Loop over all iterations + iterationCounter = 0; + while(iterationCounter < testIterations) + { + iterationCounter++; + + if(userExecKey != 0) { + execKey = userExecKey; + } else { + execKey = SDLTest_GenerateExecKey(runSeed, testSuite->name, testCase->name, iterationCounter); + } + + SDLTest_Log("Test Iteration %i: execKey %d", iterationCounter, execKey); + testResult = SDLTest_RunTest(testSuite, testCase, execKey); + + if (testResult == TEST_RESULT_PASSED) { + testPassedCount++; + totalTestPassedCount++; + } else if (testResult == TEST_RESULT_SKIPPED) { + testSkippedCount++; + totalTestSkippedCount++; + } else { + testFailedCount++; + totalTestFailedCount++; + } + } + + // Take time - test end + testEndTicks = SDL_GetTicks(); + testEndTimestamp = time(0); + + // TODO log test ended + } + + // Take time - suite end + suiteEndTicks = SDL_GetTicks(); + suiteEndTimestamp = time(0); + + // TODO log suite ended + } + + // Take time - run end + runEndTicks = SDL_GetTicks(); + runEndTimestamp = time(0); + + // TODO log run ended + + return (totalTestFailedCount ? 1 : 0); +} diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_log.c b/src/eepp/helper/SDL2/src/test/SDL_test_log.c new file mode 100644 index 000000000..0c38c44f1 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_log.c @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + + Used by the test framework and test cases. + +*/ + +// quiet windows compiler warnings +#define _CRT_SECURE_NO_WARNINGS + +#include "SDL_config.h" + +#include /* va_list */ +#include +#include +#include + +#include "SDL_test.h" + +/* + * Note: Maximum size of SDLTest log message is less than SDLs limit + * to ensure we can fit additional information such as the timestamp. + */ +#define SDLTEST_MAX_LOGMESSAGE_LENGTH 3584 + +/*! + * Converts unix timestamp to its ascii representation in localtime + * + * Note: Uses a static buffer internally, so the return value + * isn't valid after the next call of this function. If you + * want to retain the return value, make a copy of it. + * + * \param timestamp A Timestamp, i.e. time(0) + * + * \return Ascii representation of the timestamp in localtime + */ +char *SDLTest_TimestampToString(const time_t timestamp) +{ + time_t copy; + static char buffer[256]; + struct tm *local; + + memset(buffer, 0, sizeof(buffer));\ + copy = timestamp; + local = localtime(©); + strftime(buffer, sizeof(buffer), "%a %Y-%m-%d %H:%M:%S %Z", local); + + return buffer; +} + +/* + * Prints given message with a timestamp in the TEST category and INFO priority. + */ +void SDLTest_Log(char *fmt, ...) +{ + va_list list; + char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH]; + + // Print log message into a buffer + memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); + va_start(list, fmt); + SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list); + va_end(list); + + // Log with timestamp and newline + SDL_LogMessage(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_INFO, "%s: %s\n", SDLTest_TimestampToString(time(0)), logMessage); +} + +/* + * Prints given message with a timestamp in the TEST category and the ERROR priority. + */ +void SDLTest_LogError(char *fmt, ...) +{ + va_list list; + char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH]; + + // Print log message into a buffer + memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); + va_start(list, fmt); + SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list); + va_end(list); + + // Log with timestamp and newline + SDL_LogMessage(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_ERROR, "%s: %s\n", SDLTest_TimestampToString(time(0)), logMessage); +} diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_md5.c b/src/eepp/helper/SDL2/src/test/SDL_test_md5.c new file mode 100644 index 000000000..c26fa6144 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_md5.c @@ -0,0 +1,336 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + *********************************************************************** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include "SDL_config.h" + +#include "SDL_test.h" + +/* Forward declaration of static helper function */ +static void SDLTest_Md5Transform(MD5UINT4 * buf, MD5UINT4 * in); + +static unsigned char MD5PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ + +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* + The routine MD5Init initializes the message-digest context + mdContext. All fields are set to zero. +*/ + +void SDLTest_Md5Init(SDLTest_Md5Context * mdContext) +{ + if (mdContext==NULL) return; + + mdContext->i[0] = mdContext->i[1] = (MD5UINT4) 0; + + /* + * Load magic initialization constants. + */ + mdContext->buf[0] = (MD5UINT4) 0x67452301; + mdContext->buf[1] = (MD5UINT4) 0xefcdab89; + mdContext->buf[2] = (MD5UINT4) 0x98badcfe; + mdContext->buf[3] = (MD5UINT4) 0x10325476; +} + +/* + The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. +*/ + +void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf, + unsigned int inLen) +{ + MD5UINT4 in[16]; + int mdi; + unsigned int i, ii; + + if (mdContext == NULL) return; + if (inBuf == NULL || inLen < 1) return; + + /* + * compute number of bytes mod 64 + */ + mdi = (int) ((mdContext->i[0] >> 3) & 0x3F); + + /* + * update number of bits + */ + if ((mdContext->i[0] + ((MD5UINT4) inLen << 3)) < mdContext->i[0]) + mdContext->i[1]++; + mdContext->i[0] += ((MD5UINT4) inLen << 3); + mdContext->i[1] += ((MD5UINT4) inLen >> 29); + + while (inLen--) { + /* + * add new character to buffer, increment mdi + */ + mdContext->in[mdi++] = *inBuf++; + + /* + * transform if necessary + */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((MD5UINT4) mdContext->in[ii + 3]) << 24) | + (((MD5UINT4) mdContext->in[ii + 2]) << 16) | + (((MD5UINT4) mdContext->in[ii + 1]) << 8) | + ((MD5UINT4) mdContext->in[ii]); + SDLTest_Md5Transform(mdContext->buf, in); + mdi = 0; + } + } +} + +/* + The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. +*/ + +void SDLTest_Md5Final(SDLTest_Md5Context * mdContext) +{ + MD5UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + if (mdContext == NULL) return; + + /* + * save number of bits + */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* + * compute number of bytes mod 64 + */ + mdi = (int) ((mdContext->i[0] >> 3) & 0x3F); + + /* + * pad out to 56 mod 64 + */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + SDLTest_Md5Update(mdContext, MD5PADDING, padLen); + + /* + * append length in bits and transform + */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((MD5UINT4) mdContext->in[ii + 3]) << 24) | + (((MD5UINT4) mdContext->in[ii + 2]) << 16) | + (((MD5UINT4) mdContext->in[ii + 1]) << 8) | + ((MD5UINT4) mdContext->in[ii]); + SDLTest_Md5Transform(mdContext->buf, in); + + /* + * store buffer in digest + */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char) (mdContext->buf[i] & 0xFF); + mdContext->digest[ii + 1] = + (unsigned char) ((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii + 2] = + (unsigned char) ((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii + 3] = + (unsigned char) ((mdContext->buf[i] >> 24) & 0xFF); + } +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void SDLTest_Md5Transform(MD5UINT4 * buf, MD5UINT4 * in) +{ + MD5UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* + * Round 1 + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF(a, b, c, d, in[0], S11, 3614090360u); /* 1 */ + FF(d, a, b, c, in[1], S12, 3905402710u); /* 2 */ + FF(c, d, a, b, in[2], S13, 606105819u); /* 3 */ + FF(b, c, d, a, in[3], S14, 3250441966u); /* 4 */ + FF(a, b, c, d, in[4], S11, 4118548399u); /* 5 */ + FF(d, a, b, c, in[5], S12, 1200080426u); /* 6 */ + FF(c, d, a, b, in[6], S13, 2821735955u); /* 7 */ + FF(b, c, d, a, in[7], S14, 4249261313u); /* 8 */ + FF(a, b, c, d, in[8], S11, 1770035416u); /* 9 */ + FF(d, a, b, c, in[9], S12, 2336552879u); /* 10 */ + FF(c, d, a, b, in[10], S13, 4294925233u); /* 11 */ + FF(b, c, d, a, in[11], S14, 2304563134u); /* 12 */ + FF(a, b, c, d, in[12], S11, 1804603682u); /* 13 */ + FF(d, a, b, c, in[13], S12, 4254626195u); /* 14 */ + FF(c, d, a, b, in[14], S13, 2792965006u); /* 15 */ + FF(b, c, d, a, in[15], S14, 1236535329u); /* 16 */ + + /* + * Round 2 + */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG(a, b, c, d, in[1], S21, 4129170786u); /* 17 */ + GG(d, a, b, c, in[6], S22, 3225465664u); /* 18 */ + GG(c, d, a, b, in[11], S23, 643717713u); /* 19 */ + GG(b, c, d, a, in[0], S24, 3921069994u); /* 20 */ + GG(a, b, c, d, in[5], S21, 3593408605u); /* 21 */ + GG(d, a, b, c, in[10], S22, 38016083u); /* 22 */ + GG(c, d, a, b, in[15], S23, 3634488961u); /* 23 */ + GG(b, c, d, a, in[4], S24, 3889429448u); /* 24 */ + GG(a, b, c, d, in[9], S21, 568446438u); /* 25 */ + GG(d, a, b, c, in[14], S22, 3275163606u); /* 26 */ + GG(c, d, a, b, in[3], S23, 4107603335u); /* 27 */ + GG(b, c, d, a, in[8], S24, 1163531501u); /* 28 */ + GG(a, b, c, d, in[13], S21, 2850285829u); /* 29 */ + GG(d, a, b, c, in[2], S22, 4243563512u); /* 30 */ + GG(c, d, a, b, in[7], S23, 1735328473u); /* 31 */ + GG(b, c, d, a, in[12], S24, 2368359562u); /* 32 */ + + /* + * Round 3 + */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH(a, b, c, d, in[5], S31, 4294588738u); /* 33 */ + HH(d, a, b, c, in[8], S32, 2272392833u); /* 34 */ + HH(c, d, a, b, in[11], S33, 1839030562u); /* 35 */ + HH(b, c, d, a, in[14], S34, 4259657740u); /* 36 */ + HH(a, b, c, d, in[1], S31, 2763975236u); /* 37 */ + HH(d, a, b, c, in[4], S32, 1272893353u); /* 38 */ + HH(c, d, a, b, in[7], S33, 4139469664u); /* 39 */ + HH(b, c, d, a, in[10], S34, 3200236656u); /* 40 */ + HH(a, b, c, d, in[13], S31, 681279174u); /* 41 */ + HH(d, a, b, c, in[0], S32, 3936430074u); /* 42 */ + HH(c, d, a, b, in[3], S33, 3572445317u); /* 43 */ + HH(b, c, d, a, in[6], S34, 76029189u); /* 44 */ + HH(a, b, c, d, in[9], S31, 3654602809u); /* 45 */ + HH(d, a, b, c, in[12], S32, 3873151461u); /* 46 */ + HH(c, d, a, b, in[15], S33, 530742520u); /* 47 */ + HH(b, c, d, a, in[2], S34, 3299628645u); /* 48 */ + + /* + * Round 4 + */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II(a, b, c, d, in[0], S41, 4096336452u); /* 49 */ + II(d, a, b, c, in[7], S42, 1126891415u); /* 50 */ + II(c, d, a, b, in[14], S43, 2878612391u); /* 51 */ + II(b, c, d, a, in[5], S44, 4237533241u); /* 52 */ + II(a, b, c, d, in[12], S41, 1700485571u); /* 53 */ + II(d, a, b, c, in[3], S42, 2399980690u); /* 54 */ + II(c, d, a, b, in[10], S43, 4293915773u); /* 55 */ + II(b, c, d, a, in[1], S44, 2240044497u); /* 56 */ + II(a, b, c, d, in[8], S41, 1873313359u); /* 57 */ + II(d, a, b, c, in[15], S42, 4264355552u); /* 58 */ + II(c, d, a, b, in[6], S43, 2734768916u); /* 59 */ + II(b, c, d, a, in[13], S44, 1309151649u); /* 60 */ + II(a, b, c, d, in[4], S41, 4149444226u); /* 61 */ + II(d, a, b, c, in[11], S42, 3174756917u); /* 62 */ + II(c, d, a, b, in[2], S43, 718787259u); /* 63 */ + II(b, c, d, a, in[9], S44, 3951481745u); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} diff --git a/src/eepp/helper/SDL2/src/test/SDL_test_random.c b/src/eepp/helper/SDL2/src/test/SDL_test_random.c new file mode 100644 index 000000000..01fa413f2 --- /dev/null +++ b/src/eepp/helper/SDL2/src/test/SDL_test_random.c @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + + A portable "32-bit Multiply with carry" random number generator. + + Used by the fuzzer component. + Original source code contributed by A. Schiffler for GSOC project. + +*/ + +#include "SDL_config.h" + +#include +#include +#include + +#include "SDL_test.h" + +/* Initialize random number generator with two integer variables */ + +void SDLTest_RandomInit(SDLTest_RandomContext * rndContext, unsigned int xi, unsigned int ci) +{ + if (rndContext==NULL) return; + + /* + * Choose a value for 'a' from this list + * 1791398085 1929682203 1683268614 1965537969 1675393560 + * 1967773755 1517746329 1447497129 1655692410 1606218150 + * 2051013963 1075433238 1557985959 1781943330 1893513180 + * 1631296680 2131995753 2083801278 1873196400 1554115554 + */ + rndContext->a = 1655692410; + rndContext->x = 30903; + rndContext->c = 0; + if (xi != 0) { + rndContext->x = xi; + } + rndContext->c = ci; + rndContext->ah = rndContext->a >> 16; + rndContext->al = rndContext->a & 65535; +} + +/* Initialize random number generator from system time */ + +void SDLTest_RandomInitTime(SDLTest_RandomContext * rndContext) +{ + int a, b; + + if (rndContext==NULL) return; + + srand((unsigned int)time(NULL)); + a=rand(); + srand(clock()); + b=rand(); + SDLTest_RandomInit(rndContext, a, b); +} + +/* Returns random numbers */ + +unsigned int SDLTest_Random(SDLTest_RandomContext * rndContext) +{ + unsigned int xh, xl; + + if (rndContext==NULL) return -1; + + xh = rndContext->x >> 16, xl = rndContext->x & 65535; + rndContext->x = rndContext->x * rndContext->a + rndContext->c; + rndContext->c = + xh * rndContext->ah + ((xh * rndContext->al) >> 16) + + ((xl * rndContext->ah) >> 16); + if (xl * rndContext->al >= (~rndContext->c + 1)) + rndContext->c++; + return (rndContext->x); +} diff --git a/src/eepp/helper/SDL2/src/thread/SDL_systhread.h b/src/eepp/helper/SDL2/src/thread/SDL_systhread.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/SDL_thread.c b/src/eepp/helper/SDL2/src/thread/SDL_thread.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/SDL_thread_c.h b/src/eepp/helper/SDL2/src/thread/SDL_thread_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/beos/SDL_syssem.c b/src/eepp/helper/SDL2/src/thread/beos/SDL_syssem.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/beos/SDL_systhread.c b/src/eepp/helper/SDL2/src/thread/beos/SDL_systhread.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/beos/SDL_systhread_c.h b/src/eepp/helper/SDL2/src/thread/beos/SDL_systhread_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/generic/SDL_syscond.c b/src/eepp/helper/SDL2/src/thread/generic/SDL_syscond.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/generic/SDL_sysmutex.c b/src/eepp/helper/SDL2/src/thread/generic/SDL_sysmutex.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/generic/SDL_sysmutex_c.h b/src/eepp/helper/SDL2/src/thread/generic/SDL_sysmutex_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/generic/SDL_syssem.c b/src/eepp/helper/SDL2/src/thread/generic/SDL_syssem.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/generic/SDL_systhread.c b/src/eepp/helper/SDL2/src/thread/generic/SDL_systhread.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/generic/SDL_systhread_c.h b/src/eepp/helper/SDL2/src/thread/generic/SDL_systhread_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_syscond.c b/src/eepp/helper/SDL2/src/thread/nds/SDL_syscond.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_syscond_c.h b/src/eepp/helper/SDL2/src/thread/nds/SDL_syscond_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_sysmutex.c b/src/eepp/helper/SDL2/src/thread/nds/SDL_sysmutex.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_sysmutex_c.h b/src/eepp/helper/SDL2/src/thread/nds/SDL_sysmutex_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_syssem.c b/src/eepp/helper/SDL2/src/thread/nds/SDL_syssem.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_syssem_c.h b/src/eepp/helper/SDL2/src/thread/nds/SDL_syssem_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_systhread.c b/src/eepp/helper/SDL2/src/thread/nds/SDL_systhread.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/nds/SDL_systhread_c.h b/src/eepp/helper/SDL2/src/thread/nds/SDL_systhread_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/pthread/SDL_syscond.c b/src/eepp/helper/SDL2/src/thread/pthread/SDL_syscond.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/pthread/SDL_sysmutex.c b/src/eepp/helper/SDL2/src/thread/pthread/SDL_sysmutex.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/pthread/SDL_sysmutex_c.h b/src/eepp/helper/SDL2/src/thread/pthread/SDL_sysmutex_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/pthread/SDL_syssem.c b/src/eepp/helper/SDL2/src/thread/pthread/SDL_syssem.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/pthread/SDL_systhread.c b/src/eepp/helper/SDL2/src/thread/pthread/SDL_systhread.c old mode 100755 new mode 100644 index 292f7dcab..fa07fbfa6 --- a/src/eepp/helper/SDL2/src/thread/pthread/SDL_systhread.c +++ b/src/eepp/helper/SDL2/src/thread/pthread/SDL_systhread.c @@ -28,18 +28,30 @@ #endif #include + #ifdef __LINUX__ #include #include #include #include -extern int pthread_setname_np (pthread_t __target_thread, __const char *__name) __THROW __nonnull ((2)); +#endif // __LINUX__ + +#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__) +#include +#ifndef RTLD_DEFAULT +#define RTLD_DEFAULT NULL +#endif #endif #include "SDL_platform.h" #include "SDL_thread.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" +#ifdef __ANDROID__ +#include "../../core/android/SDL_android.h" +#endif + +#include "SDL_assert.h" /* List of signals to mask in the subthreads */ static const int sig_list[] = { @@ -51,15 +63,38 @@ static const int sig_list[] = { static void * RunThread(void *data) { +#ifdef __ANDROID__ + Android_JNI_SetupThread(); +#endif SDL_RunThread(data); return NULL; } +#if defined(__MACOSX__) || defined(__IPHONEOS__) +static SDL_bool checked_setname = SDL_FALSE; +static int (*ppthread_setname_np)(const char*) = NULL; +#elif defined(__LINUX__) +static SDL_bool checked_setname = SDL_FALSE; +static int (*ppthread_setname_np)(pthread_t, const char*) = NULL; +#endif int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { pthread_attr_t type; + /* do this here before any threads exist, so there's no race condition. */ + #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) + if (!checked_setname) { + void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np"); + #if defined(__MACOSX__) || defined(__IPHONEOS__) + ppthread_setname_np = (int(*)(const char*)) fn; + #elif defined(__LINUX__) + ppthread_setname_np = (int(*)(pthread_t, const char*)) fn; + #endif + checked_setname = SDL_TRUE; + } + #endif + /* Set the thread attributes */ if (pthread_attr_init(&type) != 0) { SDL_SetError("Couldn't initialize pthread attributes"); @@ -83,14 +118,20 @@ SDL_SYS_SetupThread(const char *name) sigset_t mask; if (name != NULL) { -#if ( (__MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)) || \ - (__IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)) ) - if (pthread_setname_np != NULL) { pthread_setname_np(name); } -#elif HAVE_PTHREAD_SETNAME_NP - pthread_setname_np(pthread_self(), name); -#elif HAVE_PTHREAD_SET_NAME_NP - pthread_set_name_np(pthread_self(), name); -#endif + #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) + SDL_assert(checked_setname); + if (ppthread_setname_np != NULL) { + #if defined(__MACOSX__) || defined(__IPHONEOS__) + ppthread_setname_np(name); + #elif defined(__LINUX__) + ppthread_setname_np(pthread_self(), name); + #endif + } + #elif HAVE_PTHREAD_SETNAME_NP + pthread_setname_np(pthread_self(), name); + #elif HAVE_PTHREAD_SET_NAME_NP + pthread_set_name_np(pthread_self(), name); + #endif } /* Mask asynchronous signals for this thread */ diff --git a/src/eepp/helper/SDL2/src/thread/pthread/SDL_systhread_c.h b/src/eepp/helper/SDL2/src/thread/pthread/SDL_systhread_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/windows/SDL_sysmutex.c b/src/eepp/helper/SDL2/src/thread/windows/SDL_sysmutex.c old mode 100755 new mode 100644 index 779314277..882c9c69b --- a/src/eepp/helper/SDL2/src/thread/windows/SDL_sysmutex.c +++ b/src/eepp/helper/SDL2/src/thread/windows/SDL_sysmutex.c @@ -44,12 +44,8 @@ SDL_CreateMutex(void) mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); if (mutex) { /* Initialize */ -#ifdef _WIN32_WCE - InitializeCriticalSection(&mutex->cs); -#else /* On SMP systems, a non-zero spin count generally helps performance */ InitializeCriticalSectionAndSpinCount(&mutex->cs, 2000); -#endif } else { SDL_OutOfMemory(); } diff --git a/src/eepp/helper/SDL2/src/thread/windows/SDL_syssem.c b/src/eepp/helper/SDL2/src/thread/windows/SDL_syssem.c old mode 100755 new mode 100644 index 98b5ba7de..8a958eba5 --- a/src/eepp/helper/SDL2/src/thread/windows/SDL_syssem.c +++ b/src/eepp/helper/SDL2/src/thread/windows/SDL_syssem.c @@ -27,18 +27,10 @@ #include "../../core/windows/SDL_windows.h" #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 count; }; @@ -53,11 +45,7 @@ SDL_CreateSemaphore(Uint32 initial_value) 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"); @@ -76,11 +64,7 @@ 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); @@ -103,11 +87,7 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) } 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; @@ -159,11 +139,7 @@ SDL_SemPost(SDL_sem * sem) * 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; diff --git a/src/eepp/helper/SDL2/src/thread/windows/SDL_systhread.c b/src/eepp/helper/SDL2/src/thread/windows/SDL_systhread.c old mode 100755 new mode 100644 index efe2ccb31..e399689dd --- a/src/eepp/helper/SDL2/src/thread/windows/SDL_systhread.c +++ b/src/eepp/helper/SDL2/src/thread/windows/SDL_systhread.c @@ -30,10 +30,8 @@ #include "SDL_systhread_c.h" #ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD -#ifndef _WIN32_WCE /* We'll use the C library from this DLL */ #include -#endif /* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */ #if (defined(__MINGW32__) && (__GNUC__ < 4)) @@ -112,13 +110,8 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args, 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 */ pThreadStartParms pThreadParms = (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms)); diff --git a/src/eepp/helper/SDL2/src/thread/windows/SDL_systhread_c.h b/src/eepp/helper/SDL2/src/thread/windows/SDL_systhread_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/thread/windows/win_ce_semaphore.c b/src/eepp/helper/SDL2/src/thread/windows/win_ce_semaphore.c deleted file mode 100644 index f243682b7..000000000 --- a/src/eepp/helper/SDL2/src/thread/windows/win_ce_semaphore.c +++ /dev/null @@ -1,233 +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. -*/ -#include "SDL_config.h" - -#if SDL_THREAD_WINDOWS - -#include "../../core/windows/SDL_windows.h" - -#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; -} - -#endif /* SDL_THREAD_WINDOWS */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/thread/windows/win_ce_semaphore.h b/src/eepp/helper/SDL2/src/thread/windows/win_ce_semaphore.h deleted file mode 100644 index b9f7402eb..000000000 --- a/src/eepp/helper/SDL2/src/thread/windows/win_ce_semaphore.h +++ /dev/null @@ -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 --git a/src/eepp/helper/SDL2/src/timer/SDL_timer.c b/src/eepp/helper/SDL2/src/timer/SDL_timer.c old mode 100755 new mode 100644 index 69500450e..739bd4626 --- a/src/eepp/helper/SDL2/src/timer/SDL_timer.c +++ b/src/eepp/helper/SDL2/src/timer/SDL_timer.c @@ -223,7 +223,7 @@ SDL_TimerInit(void) data->active = SDL_TRUE; /* !!! FIXME: this is nasty. */ -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) +#if defined(__WIN32__) && !defined(HAVE_LIBC) #undef SDL_CreateThread data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL); #else diff --git a/src/eepp/helper/SDL2/src/timer/SDL_timer_c.h b/src/eepp/helper/SDL2/src/timer/SDL_timer_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/timer/beos/SDL_systimer.c b/src/eepp/helper/SDL2/src/timer/beos/SDL_systimer.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/timer/dummy/SDL_systimer.c b/src/eepp/helper/SDL2/src/timer/dummy/SDL_systimer.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/timer/nds/SDL_systimer.c b/src/eepp/helper/SDL2/src/timer/nds/SDL_systimer.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/timer/unix/SDL_systimer.c b/src/eepp/helper/SDL2/src/timer/unix/SDL_systimer.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/timer/wince/SDL_systimer.c b/src/eepp/helper/SDL2/src/timer/wince/SDL_systimer.c deleted file mode 100755 index b9bac4ed2..000000000 --- a/src/eepp/helper/SDL2/src/timer/wince/SDL_systimer.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "SDL_config.h" - -#ifdef SDL_TIMER_WINCE - -#include "../../core/windows/SDL_windows.h" - -#include "SDL_timer.h" - -static Uint64 start_date; -static Uint64 start_ticks; - -static Uint64 -wce_ticks(void) -{ - return ((Uint64) GetTickCount()); -} - -static Uint64 -wce_date(void) -{ - union - { - FILETIME ftime; - Uint64 itime; - } ftime; - SYSTEMTIME stime; - - GetSystemTime(&stime); - SystemTimeToFileTime(&stime, &ftime.ftime); - ftime.itime /= 10000; // Convert 100ns intervals to 1ms intervals - // Remove ms portion, which can't be relied on - ftime.itime -= (ftime.itime % 1000); - return (ftime.itime); -} - -static Sint32 -wce_rel_ticks(void) -{ - return ((Sint32) (wce_ticks() - start_ticks)); -} - -static Sint32 -wce_rel_date(void) -{ - return ((Sint32) (wce_date() - start_date)); -} - -/* Recard start-time of application for reference */ -void -SDL_StartTicks(void) -{ - start_date = wce_date(); - start_ticks = wce_ticks(); -} - -/* Return time in ms relative to when SDL was started */ -Uint32 -SDL_GetTicks() -{ - Sint32 offset = wce_rel_date() - wce_rel_ticks(); - if ((offset < -1000) || (offset > 1000)) { -// fprintf(stderr,"Time desync(%+d), resyncing\n",offset/1000); - start_ticks -= offset; - } - - return ((Uint32) wce_rel_ticks()); -} - -Uint64 -SDL_GetPerformanceCounter(void) -{ - return SDL_GetTicks(); -} - -Uint64 -SDL_GetPerformanceFrequency(void) -{ - return 1000; -} - -/* Give up approx. givem milliseconds to the OS. */ -void -SDL_Delay(Uint32 ms) -{ - Sleep(ms); -} - -#endif /* SDL_TIMER_WINCE */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/timer/windows/SDL_systimer.c b/src/eepp/helper/SDL2/src/timer/windows/SDL_systimer.c old mode 100755 new mode 100644 index d721832f7..a08c9ff31 --- a/src/eepp/helper/SDL2/src/timer/windows/SDL_systimer.c +++ b/src/eepp/helper/SDL2/src/timer/windows/SDL_systimer.c @@ -27,10 +27,6 @@ #include "SDL_timer.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 */ diff --git a/src/eepp/helper/SDL2/src/video/SDL_RLEaccel.c b/src/eepp/helper/SDL2/src/video/SDL_RLEaccel.c old mode 100755 new mode 100644 index 40fe95719..8554a5652 --- a/src/eepp/helper/SDL2/src/video/SDL_RLEaccel.c +++ b/src/eepp/helper/SDL2/src/video/SDL_RLEaccel.c @@ -1270,9 +1270,8 @@ RLEColorkeySurface(SDL_Surface * surface) Uint8 *rlebuf, *dst; int maxn; int y; - Uint8 *srcbuf, *curbuf, *lastline; + Uint8 *srcbuf, *lastline; int maxsize = 0; - int skip, run; int bpp = surface->format->BytesPerPixel; getpix_func getpix; Uint32 ckey, rgbmask; @@ -1306,9 +1305,7 @@ RLEColorkeySurface(SDL_Surface * surface) /* Set up the conversion */ srcbuf = (Uint8 *) surface->pixels; - curbuf = srcbuf; maxn = bpp == 4 ? 65535 : 255; - skip = run = 0; dst = rlebuf; rgbmask = ~surface->format->Amask; ckey = surface->map->info.colorkey & rgbmask; diff --git a/src/eepp/helper/SDL2/src/video/SDL_RLEaccel_c.h b/src/eepp/helper/SDL2/src/video/SDL_RLEaccel_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit.c b/src/eepp/helper/SDL2/src/video/SDL_blit.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit.h b/src/eepp/helper/SDL2/src/video/SDL_blit.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_0.c b/src/eepp/helper/SDL2/src/video/SDL_blit_0.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_1.c b/src/eepp/helper/SDL2/src/video/SDL_blit_1.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_A.c b/src/eepp/helper/SDL2/src/video/SDL_blit_A.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_N.c b/src/eepp/helper/SDL2/src/video/SDL_blit_N.c old mode 100755 new mode 100644 index a87df23ae..2d7255ada --- a/src/eepp/helper/SDL2/src/video/SDL_blit_N.c +++ b/src/eepp/helper/SDL2/src/video/SDL_blit_N.c @@ -2360,16 +2360,16 @@ static const struct blit_table normal_blit_2[] = { #endif {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_RGB565_ARGB8888, SET_ALPHA}, + 0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_RGB565_ABGR8888, SET_ALPHA}, + 0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00, - 0, Blit_RGB565_RGBA8888, SET_ALPHA}, + 0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000, - 0, Blit_RGB565_BGRA8888, SET_ALPHA}, + 0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, /* Default for 16-bit RGB source, used if no other blitter matches */ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_auto.c b/src/eepp/helper/SDL2/src/video/SDL_blit_auto.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_auto.h b/src/eepp/helper/SDL2/src/video/SDL_blit_auto.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_copy.c b/src/eepp/helper/SDL2/src/video/SDL_blit_copy.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_copy.h b/src/eepp/helper/SDL2/src/video/SDL_blit_copy.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_slow.c b/src/eepp/helper/SDL2/src/video/SDL_blit_slow.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_blit_slow.h b/src/eepp/helper/SDL2/src/video/SDL_blit_slow.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_bmp.c b/src/eepp/helper/SDL2/src/video/SDL_bmp.c old mode 100755 new mode 100644 index c31d022f0..9103fa95f --- a/src/eepp/helper/SDL2/src/video/SDL_bmp.c +++ b/src/eepp/helper/SDL2/src/video/SDL_bmp.c @@ -51,7 +51,7 @@ SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) { SDL_bool was_error; - long fp_offset = 0; + Sint64 fp_offset = 0; int bmpPitch; int i, pad; SDL_Surface *surface; @@ -67,23 +67,23 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) /* The Win32 BMP file header (14 bytes) */ char magic[2]; - Uint32 bfSize; - Uint16 bfReserved1; - Uint16 bfReserved2; - Uint32 bfOffBits; + /*Uint32 bfSize = 0;*/ + /*Uint16 bfReserved1 = 0;*/ + /*Uint16 bfReserved2 = 0;*/ + Uint32 bfOffBits = 0; /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ - Uint32 biSize; - Sint32 biWidth; - Sint32 biHeight; - Uint16 biPlanes; - Uint16 biBitCount; - Uint32 biCompression; - Uint32 biSizeImage; - Sint32 biXPelsPerMeter; - Sint32 biYPelsPerMeter; - Uint32 biClrUsed; - Uint32 biClrImportant; + Uint32 biSize = 0; + Sint32 biWidth = 0; + Sint32 biHeight = 0; + /*Uint16 biPlanes = 0;*/ + Uint16 biBitCount = 0; + Uint32 biCompression = 0; + /*Uint32 biSizeImage = 0;*/ + /*Sint32 biXPelsPerMeter = 0;*/ + /*Sint32 biYPelsPerMeter = 0;*/ + Uint32 biClrUsed = 0; + /*Uint32 biClrImportant = 0;*/ /* Make sure we are passed a valid data source */ surface = NULL; @@ -106,9 +106,9 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) was_error = SDL_TRUE; goto done; } - bfSize = SDL_ReadLE32(src); - bfReserved1 = SDL_ReadLE16(src); - bfReserved2 = SDL_ReadLE16(src); + /*bfSize =*/ SDL_ReadLE32(src); + /*bfReserved1 =*/ SDL_ReadLE16(src); + /*bfReserved2 =*/ SDL_ReadLE16(src); bfOffBits = SDL_ReadLE32(src); /* Read the Win32 BITMAPINFOHEADER */ @@ -116,25 +116,20 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) if (biSize == 12) { biWidth = (Uint32) SDL_ReadLE16(src); biHeight = (Uint32) SDL_ReadLE16(src); - biPlanes = SDL_ReadLE16(src); + /*biPlanes =*/ SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = BI_RGB; - biSizeImage = 0; - biXPelsPerMeter = 0; - biYPelsPerMeter = 0; - biClrUsed = 0; - biClrImportant = 0; } else { biWidth = SDL_ReadLE32(src); biHeight = SDL_ReadLE32(src); - biPlanes = SDL_ReadLE16(src); + /*biPlanes =*/ SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = SDL_ReadLE32(src); - biSizeImage = SDL_ReadLE32(src); - biXPelsPerMeter = SDL_ReadLE32(src); - biYPelsPerMeter = SDL_ReadLE32(src); + /*biSizeImage =*/ SDL_ReadLE32(src); + /*biXPelsPerMeter =*/ SDL_ReadLE32(src); + /*biYPelsPerMeter =*/ SDL_ReadLE32(src); biClrUsed = SDL_ReadLE32(src); - biClrImportant = SDL_ReadLE32(src); + /*biClrImportant =*/ SDL_ReadLE32(src); } if (biHeight < 0) { topDown = SDL_TRUE; @@ -376,7 +371,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) int SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) { - long fp_offset; + Sint64 fp_offset; int i, pad; SDL_Surface *surface; Uint8 *bits; @@ -520,7 +515,7 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } /* Write the bitmap offset */ - bfOffBits = SDL_RWtell(dst) - fp_offset; + bfOffBits = (Uint32)(SDL_RWtell(dst) - fp_offset); if (SDL_RWseek(dst, fp_offset + 10, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); } @@ -547,7 +542,7 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } /* Write the BMP file size */ - bfSize = SDL_RWtell(dst) - fp_offset; + bfSize = (Uint32)(SDL_RWtell(dst) - fp_offset); if (SDL_RWseek(dst, fp_offset + 2, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); } diff --git a/src/eepp/helper/SDL2/src/video/SDL_clipboard.c b/src/eepp/helper/SDL2/src/video/SDL_clipboard.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_fillrect.c b/src/eepp/helper/SDL2/src/video/SDL_fillrect.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_pixels.c b/src/eepp/helper/SDL2/src/video/SDL_pixels.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_pixels_c.h b/src/eepp/helper/SDL2/src/video/SDL_pixels_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_rect.c b/src/eepp/helper/SDL2/src/video/SDL_rect.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_rect_c.h b/src/eepp/helper/SDL2/src/video/SDL_rect_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_shape.c b/src/eepp/helper/SDL2/src/video/SDL_shape.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_shape_internals.h b/src/eepp/helper/SDL2/src/video/SDL_shape_internals.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/SDL_stretch.c b/src/eepp/helper/SDL2/src/video/SDL_stretch.c old mode 100755 new mode 100644 index 6f8084519..8c829f9b4 --- a/src/eepp/helper/SDL2/src/video/SDL_stretch.c +++ b/src/eepp/helper/SDL2/src/video/SDL_stretch.c @@ -33,7 +33,7 @@ into the general blitting mechanism. */ -#if ((defined(_MFC_VER) && defined(_M_IX86)/* && !defined(_WIN32_WCE) still needed? */) || \ +#if ((defined(_MFC_VER) && defined(_M_IX86)) || \ defined(__WATCOMC__) || \ (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES /* There's a bug with gcc 4.4.1 and -O2 where srcp doesn't get the correct @@ -209,7 +209,6 @@ SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, int src_locked; int dst_locked; int pos, inc; - int dst_width; int dst_maxrow; int src_row, dst_row; Uint8 *srcp = NULL; @@ -286,7 +285,6 @@ SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, inc = (srcrect->h << 16) / dstrect->h; src_row = srcrect->y; dst_row = dstrect->y; - dst_width = dstrect->w * bpp; #ifdef USE_ASM_STRETCH /* Write the opcodes for this stretch */ diff --git a/src/eepp/helper/SDL2/src/video/SDL_surface.c b/src/eepp/helper/SDL2/src/video/SDL_surface.c old mode 100755 new mode 100644 index eb63904ea..e989a1aab --- a/src/eepp/helper/SDL2/src/video/SDL_surface.c +++ b/src/eepp/helper/SDL2/src/video/SDL_surface.c @@ -684,33 +684,54 @@ int SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) { + static const Uint32 complex_copy_flags = ( + SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | + SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | + SDL_COPY_COLORKEY + ); + /* Save off the original dst width, height */ int dstW = dstrect->w; int dstH = dstrect->h; + SDL_Rect full_rect; SDL_Rect final_dst = *dstrect; SDL_Rect final_src = *srcrect; /* Clip the dst surface to the dstrect */ - SDL_SetClipRect( dst, &final_dst ); + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = dst->w; + full_rect.h = dst->h; + if (!SDL_IntersectRect(&final_dst, &full_rect, &final_dst)) { + return 0; + } /* Did the dst width change? */ - if ( dstW != dst->clip_rect.w ) { + if ( dstW != final_dst.w ) { /* scale the src width appropriately */ final_src.w = final_src.w * dst->clip_rect.w / dstW; } /* Did the dst height change? */ - if ( dstH != dst->clip_rect.h ) { + if ( dstH != final_dst.h ) { /* scale the src width appropriately */ final_src.h = final_src.h * dst->clip_rect.h / dstH; } /* Clip the src surface to the srcrect */ - SDL_SetClipRect( src, &final_src ); + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = src->w; + full_rect.h = src->h; + if (!SDL_IntersectRect(&final_src, &full_rect, &final_src)) { + return 0; + } src->map->info.flags |= SDL_COPY_NEAREST; - if ( src->format->format == dst->format->format && !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { + if ( !(src->map->info.flags & complex_copy_flags) && + src->format->format == dst->format->format && + !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { return SDL_SoftStretch( src, &final_src, dst, &final_dst ); } else { return SDL_LowerBlit( src, &final_src, dst, &final_dst ); @@ -912,6 +933,7 @@ int SDL_ConvertPixels(int width, int height, SDL_PixelFormat src_fmt, dst_fmt; SDL_BlitMap src_blitmap, dst_blitmap; SDL_Rect rect; + void *nonconst_src = (void *) src; /* Fast path for same format copy */ if (src_format == dst_format) { @@ -925,6 +947,7 @@ int SDL_ConvertPixels(int width, int height, case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: bpp = 2; + break; default: SDL_SetError("Unknown FOURCC pixel format"); return -1; @@ -942,7 +965,7 @@ int SDL_ConvertPixels(int width, int height, return 0; } - if (!SDL_CreateSurfaceOnStack(width, height, src_format, (void*)src, + if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src, src_pitch, &src_surface, &src_fmt, &src_blitmap)) { return -1; diff --git a/src/eepp/helper/SDL2/src/video/SDL_sysvideo.h b/src/eepp/helper/SDL2/src/video/SDL_sysvideo.h old mode 100755 new mode 100644 index 679be4bf8..830426603 --- a/src/eepp/helper/SDL2/src/video/SDL_sysvideo.h +++ b/src/eepp/helper/SDL2/src/video/SDL_sysvideo.h @@ -23,6 +23,7 @@ #ifndef _SDL_sysvideo_h #define _SDL_sysvideo_h +#include "SDL_messagebox.h" #include "SDL_shape.h" /* The SDL video driver */ @@ -73,6 +74,7 @@ struct SDL_Window char *title; int x, y; int w, h; + int min_w, min_h; Uint32 flags; /* Stored position and size for windowed mode */ @@ -180,16 +182,18 @@ struct SDL_VideoDevice void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon); void (*SetWindowPosition) (_THIS, SDL_Window * window); void (*SetWindowSize) (_THIS, SDL_Window * window); + void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); void (*ShowWindow) (_THIS, SDL_Window * window); void (*HideWindow) (_THIS, SDL_Window * window); void (*RaiseWindow) (_THIS, SDL_Window * window); void (*MaximizeWindow) (_THIS, SDL_Window * window); void (*MinimizeWindow) (_THIS, SDL_Window * window); void (*RestoreWindow) (_THIS, SDL_Window * window); + void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); - void (*SetWindowGrab) (_THIS, SDL_Window * window); + void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*DestroyWindow) (_THIS, SDL_Window * window); int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, SDL_Rect * rects, int numrects); @@ -233,11 +237,20 @@ struct SDL_VideoDevice void (*StopTextInput) (_THIS); void (*SetTextInputRect) (_THIS, SDL_Rect *rect); + /* Screen keyboard */ + SDL_bool (*SDL_HasScreenKeyboardSupport) (_THIS); + void (*SDL_ShowScreenKeyboard) (_THIS, SDL_Window *window); + void (*SDL_HideScreenKeyboard) (_THIS, SDL_Window *window); + SDL_bool (*SDL_IsScreenKeyboardShown) (_THIS, SDL_Window *window); + /* Clipboard */ int (*SetClipboardText) (_THIS, const char *text); char * (*GetClipboardText) (_THIS); SDL_bool (*HasClipboardText) (_THIS); + /* MessageBox */ + int (*ShowMessageBox) (_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid); + /* * * */ /* Data common to all drivers */ SDL_bool suspend_screensaver; @@ -272,6 +285,8 @@ struct SDL_VideoDevice int minor_version; int flags; int profile_mask; + int use_egl; + int share_with_current_context; int retained_backing; int driver_loaded; char driver_path[256]; @@ -288,7 +303,7 @@ struct SDL_VideoDevice void *driverdata; struct SDL_GLDriverData *gl_data; -#if SDL_VIDEO_OPENGL_ES +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 struct SDL_PrivateGLESData *gles_data; #endif @@ -351,6 +366,7 @@ extern void SDL_OnWindowMinimized(SDL_Window * window); extern void SDL_OnWindowRestored(SDL_Window * window); extern void SDL_OnWindowFocusGained(SDL_Window * window); extern void SDL_OnWindowFocusLost(SDL_Window * window); +extern void SDL_UpdateWindowGrab(SDL_Window * window); extern SDL_Window * SDL_GetFocusWindow(void); #endif /* _SDL_sysvideo_h */ diff --git a/src/eepp/helper/SDL2/src/video/SDL_video.c b/src/eepp/helper/SDL2/src/video/SDL_video.c old mode 100755 new mode 100644 index 61941d3d2..e3109481e --- a/src/eepp/helper/SDL2/src/video/SDL_video.c +++ b/src/eepp/helper/SDL2/src/video/SDL_video.c @@ -107,11 +107,6 @@ static SDL_VideoDevice *_this = NULL; return retval; \ } -#define INVALIDATE_GLCONTEXT() \ - _this->current_glwin = NULL; \ - _this->current_glctx = NULL; - - /* Support for framebuffer emulation using an accelerated renderer */ #define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" @@ -493,15 +488,19 @@ SDL_VideoInit(const char *driver_name) #if SDL_VIDEO_OPENGL _this->gl_config.major_version = 2; _this->gl_config.minor_version = 1; + _this->gl_config.use_egl = 0; #elif SDL_VIDEO_OPENGL_ES _this->gl_config.major_version = 1; _this->gl_config.minor_version = 1; + _this->gl_config.use_egl = 1; #elif SDL_VIDEO_OPENGL_ES2 _this->gl_config.major_version = 2; _this->gl_config.minor_version = 0; + _this->gl_config.use_egl = 1; #endif _this->gl_config.flags = 0; _this->gl_config.profile_mask = 0; + _this->gl_config.share_with_current_context = 0; /* Initialize the video subsystem */ if (_this->VideoInit(_this) < 0) { @@ -523,6 +522,17 @@ SDL_VideoInit(const char *driver_name) _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; } + /* If we don't use a screen keyboard, turn on text input by default, + otherwise programs that expect to get text events without enabling + UNICODE input won't get any events. + + Actually, come to think of it, you needed to call SDL_EnableUNICODE(1) + in SDL 1.2 before you got text input events. Hmm... + */ + if (!SDL_HasScreenKeyboardSupport()) { + SDL_StartTextInput(); + } + /* We're ready to go! */ return 0; } @@ -624,8 +634,8 @@ SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect) SDL_GetDisplayBounds(displayIndex-1, rect); rect->x += rect->w; } - rect->w = display->desktop_mode.w; - rect->h = display->desktop_mode.h; + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; } return 0; } @@ -934,13 +944,18 @@ SDL_GetWindowDisplay(SDL_Window * window) } /* Find the display containing the window */ - center.x = window->x + window->w / 2; - center.y = window->y + window->h / 2; for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; + if (display->fullscreen_window == window) { + return i; + } + } + center.x = window->x + window->w / 2; + center.y = window->y + window->h / 2; + for (i = 0; i < _this->num_displays; ++i) { SDL_GetDisplayBounds(i, &rect); - if (display->fullscreen_window == window || SDL_EnclosePoints(¢er, 1, &rect, NULL)) { + if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { return i; } @@ -1164,7 +1179,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) SDL_SetError("No OpenGL support in video driver"); return NULL; } - SDL_GL_LoadLibrary(NULL); + if (SDL_GL_LoadLibrary(NULL) < 0) { + return NULL; + } } window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); window->magic = &_this->window_magic; @@ -1491,6 +1508,24 @@ SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) } } +void +SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered) +{ + CHECK_WINDOW_MAGIC(window, ); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + const int want = (bordered != SDL_FALSE); /* normalize the flag. */ + const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0); + if ((want != have) && (_this->SetWindowBordered)) { + if (want) { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } else { + window->flags |= SDL_WINDOW_BORDERLESS; + } + _this->SetWindowBordered(_this, window, (SDL_bool) want); + } + } +} + void SDL_SetWindowSize(SDL_Window * window, int w, int h) { @@ -1528,19 +1563,47 @@ SDL_GetWindowSize(SDL_Window * window, int *w, int *h) CHECK_WINDOW_MAGIC(window, ); if (_this && window && window->magic == &_this->window_magic) { - if (w) { - *w = window->w; - } - if (h) { - *h = window->h; - } - } else { - if (w) { - *w = 0; - } - if (h) { - *h = 0; + *w = window->w; + *h = window->h; + } +} + +void +SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + window->min_w = min_w; + window->min_h = min_h; + if (_this->SetWindowMinimumSize) { + _this->SetWindowMinimumSize(_this, window); } + /* Ensure that window is not smaller than minimal size */ + SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h)); + } +} + +void +SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) +{ + int dummy; + + if (!min_w) { + min_w = &dummy; + } + if (!min_h) { + min_h = &dummy; + } + + *min_w = 0; + *min_h = 0; + + CHECK_WINDOW_MAGIC(window, ); + + if (_this && window && window->magic == &_this->window_magic) { + *min_w = window->min_w; + *min_h = window->min_h; } } @@ -1826,11 +1889,18 @@ SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, return 0; } -static void +void SDL_UpdateWindowGrab(SDL_Window * window) { - if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) { - _this->SetWindowGrab(_this, window); + if (_this->SetWindowGrab) { + SDL_bool grabbed; + if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && + (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + grabbed = SDL_TRUE; + } else { + grabbed = SDL_FALSE; + } + _this->SetWindowGrab(_this, window, grabbed); } } @@ -1861,14 +1931,12 @@ SDL_GetWindowGrab(SDL_Window * window) void SDL_OnWindowShown(SDL_Window * window) { - INVALIDATE_GLCONTEXT(); SDL_OnWindowRestored(window); } void SDL_OnWindowHidden(SDL_Window * window) { - INVALIDATE_GLCONTEXT(); SDL_UpdateFullscreenMode(window, SDL_FALSE); } @@ -1902,10 +1970,7 @@ SDL_OnWindowFocusGained(SDL_Window * window) _this->SetWindowGammaRamp(_this, window, window->gamma); } - if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) && - _this->SetWindowGrab) { - _this->SetWindowGrab(_this, window); - } + SDL_UpdateWindowGrab(window); } void @@ -1915,10 +1980,7 @@ SDL_OnWindowFocusLost(SDL_Window * window) _this->SetWindowGammaRamp(_this, window, window->saved_gamma); } - if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) && - _this->SetWindowGrab) { - _this->SetWindowGrab(_this, window); - } + SDL_UpdateWindowGrab(window); /* If we're fullscreen on a single-head system and lose focus, minimize */ if ((window->flags & SDL_WINDOW_FULLSCREEN) && _this->num_displays == 1) { @@ -1963,7 +2025,7 @@ SDL_DestroyWindow(SDL_Window * window) /* make no context current if this is the current context window. */ if (window->flags & SDL_WINDOW_OPENGL) { if (_this->current_glwin == window) { - SDL_GL_MakeCurrent(NULL, NULL); + SDL_GL_MakeCurrent(window, NULL); } } @@ -2302,12 +2364,34 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) case SDL_GL_CONTEXT_MINOR_VERSION: _this->gl_config.minor_version = value; break; + case SDL_GL_CONTEXT_EGL: + _this->gl_config.use_egl = value; + break; case SDL_GL_CONTEXT_FLAGS: + if( value & ~(SDL_GL_CONTEXT_DEBUG_FLAG | + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG | + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG | + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG) ) { + SDL_SetError("Unknown OpenGL context flag %d", value); + retval = -1; + break; + } _this->gl_config.flags = value; break; case SDL_GL_CONTEXT_PROFILE_MASK: + if( value != 0 && + value != SDL_GL_CONTEXT_PROFILE_CORE && + value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY && + value != SDL_GL_CONTEXT_PROFILE_ES ) { + SDL_SetError("Unknown OpenGL context profile %d", value); + retval = -1; + break; + } _this->gl_config.profile_mask = value; break; + case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: + _this->gl_config.share_with_current_context = value; + break; default: SDL_SetError("Unknown OpenGL attribute"); retval = -1; @@ -2454,6 +2538,11 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) *value = _this->gl_config.minor_version; return 0; } + case SDL_GL_CONTEXT_EGL: + { + *value = _this->gl_config.use_egl; + return 0; + } case SDL_GL_CONTEXT_FLAGS: { *value = _this->gl_config.flags; @@ -2464,6 +2553,11 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) *value = _this->gl_config.profile_mask; return 0; } + case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: + { + *value = _this->gl_config.share_with_current_context; + return 0; + } default: SDL_SetError("Unknown OpenGL attribute"); return -1; @@ -2567,16 +2661,13 @@ int SDL_GL_GetSwapInterval(void) { if (!_this) { - SDL_UninitializedVideo(); - return -1; + return 0; } else if (_this->current_glctx == NULL) { - SDL_SetError("No OpenGL context has been made current"); - return -1; + return 0; } else if (_this->GL_GetSwapInterval) { return _this->GL_GetSwapInterval(_this); } else { - SDL_SetError("Getting the swap interval is not supported"); - return -1; + return 0; } } @@ -2595,7 +2686,7 @@ SDL_GL_SwapWindow(SDL_Window * window) void SDL_GL_DeleteContext(SDL_GLContext context) { - if (!_this || !_this->gl_data || !context) { + if (!_this || !context) { return; } _this->GL_MakeCurrent(_this, NULL, NULL); @@ -2720,19 +2811,47 @@ SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) void SDL_StartTextInput(void) { + SDL_Window *window; + + /* First, enable text events */ + SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); + SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); + + /* Then show the on-screen keyboard, if any */ + window = SDL_GetFocusWindow(); + if (window && _this && _this->SDL_ShowScreenKeyboard) { + _this->SDL_ShowScreenKeyboard(_this, window); + } + + /* Finally start the text input system */ if (_this && _this->StartTextInput) { _this->StartTextInput(_this); } - SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); - SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); +} + +SDL_bool +SDL_IsTextInputActive(void) +{ + return (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE); } void SDL_StopTextInput(void) { + SDL_Window *window; + + /* Stop the text input system */ if (_this && _this->StopTextInput) { _this->StopTextInput(_this); } + + /* Hide the on-screen keyboard, if any */ + window = SDL_GetFocusWindow(); + if (window && _this && _this->SDL_HideScreenKeyboard) { + _this->SDL_HideScreenKeyboard(_this, window); + } + + /* Finally disable text events */ SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); } @@ -2745,4 +2864,97 @@ SDL_SetTextInputRect(SDL_Rect *rect) } } +SDL_bool +SDL_HasScreenKeyboardSupport(void) +{ + if (_this && _this->SDL_HasScreenKeyboardSupport) { + return _this->SDL_HasScreenKeyboardSupport(_this); + } + return SDL_FALSE; +} + +SDL_bool +SDL_IsScreenKeyboardShown(SDL_Window *window) +{ + if (window && _this && _this->SDL_IsScreenKeyboardShown) { + return _this->SDL_IsScreenKeyboardShown(_this, window); + } + return SDL_FALSE; +} + +#if SDL_VIDEO_DRIVER_WINDOWS +#include "windows/SDL_windowsmessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_COCOA +#include "cocoa/SDL_cocoamessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_UIKIT +#include "uikit/SDL_uikitmessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_X11 +#include "x11/SDL_x11messagebox.h" +#endif + +int +SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + int dummybutton; + + if (!buttonid) { + buttonid = &dummybutton; + } + if (_this && _this->ShowMessageBox) { + if (_this->ShowMessageBox(_this, messageboxdata, buttonid) == 0) { + return 0; + } + } + + /* It's completely fine to call this function before video is initialized */ +#if SDL_VIDEO_DRIVER_WINDOWS + if (WIN_ShowMessageBox(messageboxdata, buttonid) == 0) { + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_COCOA + if (Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) { + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_UIKIT + if (UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) { + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_X11 + if (X11_ShowMessageBox(messageboxdata, buttonid) == 0) { + return 0; + } +#endif + + SDL_SetError("No message system available"); + return -1; +} + +int +SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window) +{ + SDL_MessageBoxData data; + SDL_MessageBoxButtonData button; + + SDL_zero(data); + data.flags = flags; + data.title = title; + data.message = message; + data.numbuttons = 1; + data.buttons = &button; + data.window = window; + + SDL_zero(button); + button.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; + button.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + button.text = "OK"; + + return SDL_ShowMessageBox(&data, NULL); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidevents.c b/src/eepp/helper/SDL2/src/video/android/SDL_androidevents.c old mode 100755 new mode 100644 index b82f9c1b9..d51a91ce0 --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidevents.c +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidevents.c @@ -22,12 +22,65 @@ #if SDL_VIDEO_DRIVER_ANDROID +/* We're going to do this by default */ +#define SDL_ANDROID_BLOCK_ON_PAUSE 1 + #include "SDL_androidevents.h" +#include "SDL_events.h" void Android_PumpEvents(_THIS) { + static int isPaused = 0; +#if SDL_ANDROID_BLOCK_ON_PAUSE + static int isPausing = 0; +#endif /* No polling necessary */ + + /* + * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume + * When the pause semaphore is signaled, if SDL_ANDROID_BLOCK_ON_PAUSE is defined the event loop will block until the resume signal is emitted. + * When the resume semaphore is signaled, SDL_GL_CreateContext is called which in turn calls Java code + * SDLActivity::createGLContext -> SDLActivity:: initEGL -> SDLActivity::createEGLSurface -> SDLActivity::createEGLContext + */ + +#if SDL_ANDROID_BLOCK_ON_PAUSE + if (isPaused && !isPausing) { + if(SDL_SemWait(Android_ResumeSem) == 0) { +#else + if (isPaused) { + if(SDL_SemTryWait(Android_ResumeSem) == 0) { +#endif + isPaused = 0; + /* TODO: Should we double check if we are on the same thread as the one that made the original GL context? + * This call will go through the following chain of calls in Java: + * SDLActivity::createGLContext -> SDLActivity:: initEGL -> SDLActivity::createEGLSurface -> SDLActivity::createEGLContext + * SDLActivity::createEGLContext will attempt to restore the GL context first, and if that fails it will create a new one + * If a new GL context is created, the user needs to restore the textures manually (TODO: notify the user that this happened with a message) + */ + SDL_GL_CreateContext(Android_Window); + } + } + else { +#if SDL_ANDROID_BLOCK_ON_PAUSE + if( isPausing || SDL_SemTryWait(Android_PauseSem) == 0 ) { + /* We've been signaled to pause, but before we block ourselves, we need to make sure that + SDL_WINDOWEVENT_FOCUS_LOST and SDL_WINDOWEVENT_MINIMIZED have reached the app */ + if (SDL_HasEvent(SDL_WINDOWEVENT)) { + isPausing = 1; + } + else { + isPausing = 0; + isPaused = 1; + } + } +#else + if(SDL_SemTryWait(Android_PauseSem) == 0) { + /* If we fall in here, the system is/was paused */ + isPaused = 1; + } +#endif + } } #endif /* SDL_VIDEO_DRIVER_ANDROID */ diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidevents.h b/src/eepp/helper/SDL2/src/video/android/SDL_androidevents.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidgl.c b/src/eepp/helper/SDL2/src/video/android/SDL_androidgl.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.c b/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.c old mode 100755 new mode 100644 index e4de1b965..b1fe43a0e --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.c +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.c @@ -103,10 +103,10 @@ static SDL_Scancode Android_Keycodes[] = { SDL_SCANCODE_TAB, /* AKEYCODE_TAB */ SDL_SCANCODE_SPACE, /* AKEYCODE_SPACE */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SYM */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EXPLORER */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ENVELOPE */ + SDL_SCANCODE_WWW, /* AKEYCODE_EXPLORER */ + SDL_SCANCODE_MAIL, /* AKEYCODE_ENVELOPE */ SDL_SCANCODE_RETURN, /* AKEYCODE_ENTER */ - SDL_SCANCODE_DELETE, /* AKEYCODE_DEL */ + SDL_SCANCODE_BACKSPACE, /* AKEYCODE_DEL */ SDL_SCANCODE_GRAVE, /* AKEYCODE_GRAVE */ SDL_SCANCODE_MINUS, /* AKEYCODE_MINUS */ SDL_SCANCODE_EQUALS, /* AKEYCODE_EQUALS */ @@ -115,7 +115,7 @@ static SDL_Scancode Android_Keycodes[] = { SDL_SCANCODE_BACKSLASH, /* AKEYCODE_BACKSLASH */ SDL_SCANCODE_SEMICOLON, /* AKEYCODE_SEMICOLON */ SDL_SCANCODE_APOSTROPHE, /* AKEYCODE_APOSTROPHE */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SLASH */ + SDL_SCANCODE_SLASH, /* AKEYCODE_SLASH */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AT */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HEADSETHOOK */ @@ -150,6 +150,115 @@ static SDL_Scancode Android_Keycodes[] = { SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_START */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_SELECT */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_MODE */ + SDL_SCANCODE_ESCAPE, /* AKEYCODE_ESCAPE */ + SDL_SCANCODE_DELETE, /* AKEYCODE_FORWARD_DEL */ + SDL_SCANCODE_LCTRL, /* AKEYCODE_CTRL_LEFT */ + SDL_SCANCODE_RCTRL, /* AKEYCODE_CTRL_RIGHT */ + SDL_SCANCODE_CAPSLOCK, /* AKEYCODE_CAPS_LOCK */ + SDL_SCANCODE_SCROLLLOCK, /* AKEYCODE_SCROLL_LOCK */ + SDL_SCANCODE_LGUI, /* AKEYCODE_META_LEFT */ + SDL_SCANCODE_RGUI, /* AKEYCODE_META_RIGHT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FUNCTION */ + SDL_SCANCODE_PRINTSCREEN, /* AKEYCODE_SYSRQ */ + SDL_SCANCODE_PAUSE, /* AKEYCODE_BREAK */ + SDL_SCANCODE_HOME, /* AKEYCODE_MOVE_HOME */ + SDL_SCANCODE_END, /* AKEYCODE_MOVE_END */ + SDL_SCANCODE_INSERT, /* AKEYCODE_INSERT */ + SDL_SCANCODE_AC_FORWARD, /* AKEYCODE_FORWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PLAY */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PAUSE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_CLOSE */ + SDL_SCANCODE_EJECT, /* AKEYCODE_MEDIA_EJECT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_RECORD */ + SDL_SCANCODE_F1, /* AKEYCODE_F1 */ + SDL_SCANCODE_F2, /* AKEYCODE_F2 */ + SDL_SCANCODE_F3, /* AKEYCODE_F3 */ + SDL_SCANCODE_F4, /* AKEYCODE_F4 */ + SDL_SCANCODE_F5, /* AKEYCODE_F5 */ + SDL_SCANCODE_F6, /* AKEYCODE_F6 */ + SDL_SCANCODE_F7, /* AKEYCODE_F7 */ + SDL_SCANCODE_F8, /* AKEYCODE_F8 */ + SDL_SCANCODE_F9, /* AKEYCODE_F9 */ + SDL_SCANCODE_F10, /* AKEYCODE_F10 */ + SDL_SCANCODE_F11, /* AKEYCODE_F11 */ + SDL_SCANCODE_F12, /* AKEYCODE_F12 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM_LOCK */ + SDL_SCANCODE_KP_0, /* AKEYCODE_NUMPAD_0 */ + SDL_SCANCODE_KP_1, /* AKEYCODE_NUMPAD_1 */ + SDL_SCANCODE_KP_2, /* AKEYCODE_NUMPAD_2 */ + SDL_SCANCODE_KP_3, /* AKEYCODE_NUMPAD_3 */ + SDL_SCANCODE_KP_4, /* AKEYCODE_NUMPAD_4 */ + SDL_SCANCODE_KP_5, /* AKEYCODE_NUMPAD_5 */ + SDL_SCANCODE_KP_6, /* AKEYCODE_NUMPAD_6 */ + SDL_SCANCODE_KP_7, /* AKEYCODE_NUMPAD_7 */ + SDL_SCANCODE_KP_8, /* AKEYCODE_NUMPAD_8 */ + SDL_SCANCODE_KP_9, /* AKEYCODE_NUMPAD_9 */ + SDL_SCANCODE_KP_DIVIDE, /* AKEYCODE_NUMPAD_DIVIDE */ + SDL_SCANCODE_KP_MULTIPLY, /* AKEYCODE_NUMPAD_MULTIPLY */ + SDL_SCANCODE_KP_MINUS, /* AKEYCODE_NUMPAD_SUBTRACT */ + SDL_SCANCODE_KP_PLUS, /* AKEYCODE_NUMPAD_ADD */ + SDL_SCANCODE_KP_PERIOD, /* AKEYCODE_NUMPAD_DOT */ + SDL_SCANCODE_KP_COMMA, /* AKEYCODE_NUMPAD_COMMA */ + SDL_SCANCODE_KP_ENTER, /* AKEYCODE_NUMPAD_ENTER */ + SDL_SCANCODE_KP_EQUALS, /* AKEYCODE_NUMPAD_EQUALS */ + SDL_SCANCODE_KP_LEFTPAREN, /* AKEYCODE_NUMPAD_LEFT_PAREN */ + SDL_SCANCODE_KP_RIGHTPAREN, /* AKEYCODE_NUMPAD_RIGHT_PAREN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOLUME_MUTE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_INFO */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_UP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_DOWN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_IN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_OUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WINDOW */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_GUIDE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DVR */ + SDL_SCANCODE_AC_BOOKMARKS, /* AKEYCODE_BOOKMARK */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAPTIONS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SETTINGS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_INPUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_INPUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_RED */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_GREEN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_YELLOW */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_BLUE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_APP_SWITCH */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_3 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_4 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_5 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_6 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_7 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_8 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_9 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_10 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_11 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_12 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_13 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_14 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_15 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_16 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LANGUAGE_SWITCH */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MANNER_MODE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_3D_MODE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CONTACTS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALENDAR */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUSIC */ + SDL_SCANCODE_CALCULATOR, /* AKEYCODE_CALCULATOR */ + SDL_SCANCODE_LANG5, /* AKEYCODE_ZENKAKU_HANKAKU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EISU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUHENKAN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HENKAN */ + SDL_SCANCODE_LANG3, /* AKEYCODE_KATAKANA_HIRAGANA */ + SDL_SCANCODE_INTERNATIONAL3, /* AKEYCODE_YEN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_RO */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_KANA */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ASSIST */ }; static SDL_Scancode @@ -178,6 +287,38 @@ Android_OnKeyUp(int keycode) return SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode(keycode)); } +SDL_bool +Android_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +SDL_bool +Android_IsScreenKeyboardShown(_THIS, SDL_Window * window) +{ + return SDL_IsTextInputActive(); +} + +void +Android_StartTextInput(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + Android_JNI_ShowTextInput(&videodata->textRect); +} + +void +Android_StopTextInput(_THIS) +{ + Android_JNI_HideTextInput(); +} + +void +Android_SetTextInputRect(_THIS, SDL_Rect *rect) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + videodata->textRect = *rect; +} + #endif /* SDL_VIDEO_DRIVER_ANDROID */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.h b/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.h old mode 100755 new mode 100644 index df17cf1d1..9cc7b0261 --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.h +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidkeyboard.h @@ -26,4 +26,11 @@ extern void Android_InitKeyboard(); extern int Android_OnKeyDown(int keycode); extern int Android_OnKeyUp(int keycode); +extern SDL_bool Android_HasScreenKeyboardSupport(_THIS); +extern SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window * window); + +extern void Android_StartTextInput(_THIS); +extern void Android_StopTextInput(_THIS); +extern void Android_SetTextInputRect(_THIS, SDL_Rect *rect); + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidtouch.c b/src/eepp/helper/SDL2/src/video/android/SDL_androidtouch.c old mode 100755 new mode 100644 index 90ecef9d7..645a9071c --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidtouch.c +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidtouch.c @@ -40,25 +40,38 @@ #define ACTION_POINTER_1_DOWN 5 #define ACTION_POINTER_1_UP 6 +static SDL_FingerID leftFingerDown = 0; + +static void Android_GetWindowCoordinates(float x, float y, + int *window_x, int *window_y) +{ + int window_w, window_h; + + SDL_GetWindowSize(Android_Window, &window_w, &window_h); + *window_x = (int)(x * window_w); + *window_y = (int)(y * window_h); +} + void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p) { SDL_TouchID touchDeviceId = 0; SDL_FingerID fingerId = 0; - + int window_x, window_y; + if (!Android_Window) { return; } - + touchDeviceId = (SDL_TouchID)touch_device_id_in; if (!SDL_GetTouch(touchDeviceId)) { SDL_Touch touch; memset( &touch, 0, sizeof(touch) ); touch.id = touchDeviceId; touch.x_min = 0.0f; - touch.x_max = (float)Android_ScreenWidth; + touch.x_max = 1.0f; touch.native_xres = touch.x_max - touch.x_min; touch.y_min = 0.0f; - touch.y_max = (float)Android_ScreenHeight; + touch.y_max = 1.0f; touch.native_yres = touch.y_max - touch.y_min; touch.pressure_min = 0.0f; touch.pressure_max = 1.0f; @@ -68,18 +81,39 @@ void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int actio } } - fingerId = (SDL_FingerID)pointer_finger_id_in; switch (action) { case ACTION_DOWN: case ACTION_POINTER_1_DOWN: + if (!leftFingerDown) { + Android_GetWindowCoordinates(x, y, &window_x, &window_y); + + /* send moved event */ + SDL_SendMouseMotion(NULL, 0, window_x, window_y); + + /* send mouse down event */ + SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT); + + leftFingerDown = fingerId; + } SDL_SendFingerDown(touchDeviceId, fingerId, SDL_TRUE, x, y, p); break; case ACTION_MOVE: + if (!leftFingerDown) { + Android_GetWindowCoordinates(x, y, &window_x, &window_y); + + /* send moved event */ + SDL_SendMouseMotion(NULL, 0, window_x, window_y); + } SDL_SendTouchMotion(touchDeviceId, fingerId, SDL_FALSE, x, y, p); break; case ACTION_UP: case ACTION_POINTER_1_UP: + if (fingerId == leftFingerDown) { + /* send mouse up */ + SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT); + leftFingerDown = 0; + } SDL_SendFingerDown(touchDeviceId, fingerId, SDL_FALSE, x, y, p); break; default: diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidtouch.h b/src/eepp/helper/SDL2/src/video/android/SDL_androidtouch.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.c b/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.c old mode 100755 new mode 100644 index c97e0d7f0..7cb62eff3 --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.c +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.c @@ -33,6 +33,7 @@ #include "../../events/SDL_windowevents_c.h" #include "SDL_androidvideo.h" +#include "SDL_androidclipboard.h" #include "SDL_androidevents.h" #include "SDL_androidkeyboard.h" #include "SDL_androidwindow.h" @@ -64,6 +65,7 @@ extern void Android_GL_DeleteContext(_THIS, SDL_GLContext context); int Android_ScreenWidth = 0; int Android_ScreenHeight = 0; Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN; +SDL_sem *Android_PauseSem = NULL, *Android_ResumeSem = NULL; /* Currently only one window */ SDL_Window *Android_Window = NULL; @@ -85,17 +87,24 @@ Android_CreateDevice(int devindex) { printf("Creating video device\n"); SDL_VideoDevice *device; + SDL_VideoData *data; /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); - if (device) { - SDL_free(device); - } - return (0); + return NULL; } + data = (SDL_VideoData*) SDL_calloc(1, sizeof(SDL_VideoData)); + if (!data) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + + device->driverdata = data; + /* Set the function pointers */ device->VideoInit = Android_VideoInit; device->VideoQuit = Android_VideoQuit; @@ -118,6 +127,20 @@ Android_CreateDevice(int devindex) device->GL_SwapWindow = Android_GL_SwapWindow; device->GL_DeleteContext = Android_GL_DeleteContext; + /* Text input */ + device->StartTextInput = Android_StartTextInput; + device->StopTextInput = Android_StopTextInput; + device->SetTextInputRect = Android_SetTextInputRect; + + /* Screen keyboard */ + device->SDL_HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport; + device->SDL_IsScreenKeyboardShown = Android_IsScreenKeyboardShown; + + /* Clipboard */ + device->SetClipboardText = Android_SetClipboardText; + device->GetClipboardText = Android_GetClipboardText; + device->HasClipboardText = Android_HasClipboardText; + return device; } @@ -141,7 +164,6 @@ Android_VideoInit(_THIS) return -1; } - SDL_zero(mode); SDL_AddDisplayMode(&_this->displays[0], &mode); Android_InitKeyboard(); diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.h b/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.h old mode 100755 new mode 100644 index 8ffe8ccc0..3add56ad0 --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.h +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidvideo.h @@ -23,6 +23,8 @@ #ifndef _SDL_androidvideo_h #define _SDL_androidvideo_h +#include "SDL_mutex.h" +#include "SDL_rect.h" #include "../SDL_sysvideo.h" /* Called by the JNI layer when the screen changes size or format */ @@ -30,11 +32,18 @@ extern void Android_SetScreenResolution(int width, int height, Uint32 format); /* Private display data */ +typedef struct SDL_VideoData +{ + SDL_Rect textRect; +} SDL_VideoData; + extern int Android_ScreenWidth; extern int Android_ScreenHeight; extern Uint32 Android_ScreenFormat; +extern SDL_sem *Android_PauseSem, *Android_ResumeSem; extern SDL_Window *Android_Window; + #endif /* _SDL_androidvideo_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidwindow.c b/src/eepp/helper/SDL2/src/video/android/SDL_androidwindow.c old mode 100755 new mode 100644 index 43213e759..ba3093dca --- a/src/eepp/helper/SDL2/src/video/android/SDL_androidwindow.c +++ b/src/eepp/helper/SDL2/src/video/android/SDL_androidwindow.c @@ -35,6 +35,8 @@ Android_CreateWindow(_THIS, SDL_Window * window) return -1; } Android_Window = window; + Android_PauseSem = SDL_CreateSemaphore(0); + Android_ResumeSem = SDL_CreateSemaphore(0); /* Adjust the window data to match the screen */ window->x = 0; @@ -48,6 +50,10 @@ Android_CreateWindow(_THIS, SDL_Window * window) window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */ window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ + /* One window, it always has focus */ + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + return 0; } @@ -62,6 +68,10 @@ Android_DestroyWindow(_THIS, SDL_Window * window) { if (window == Android_Window) { Android_Window = NULL; + if (Android_PauseSem) SDL_DestroySemaphore(Android_PauseSem); + if (Android_ResumeSem) SDL_DestroySemaphore(Android_ResumeSem); + Android_PauseSem = NULL; + Android_ResumeSem = NULL; } } diff --git a/src/eepp/helper/SDL2/src/video/android/SDL_androidwindow.h b/src/eepp/helper/SDL2/src/video/android/SDL_androidwindow.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_BWin.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_BWin.h old mode 100755 new mode 100644 index b53b76ae1..da06f6cd6 --- a/src/eepp/helper/SDL2/src/video/bwindow/SDL_BWin.h +++ b/src/eepp/helper/SDL2/src/video/bwindow/SDL_BWin.h @@ -55,6 +55,7 @@ enum WinCommands { BWIN_MINIMIZE_WINDOW, BWIN_RESTORE_WINDOW, BWIN_SET_TITLE, + BWIN_SET_BORDERED, BWIN_FULLSCREEN }; @@ -63,8 +64,8 @@ class SDL_BWin:public BDirectWindow { public: /* Constructor/Destructor */ - SDL_BWin(BRect bounds, uint32 flags):BDirectWindow(bounds, "Untitled", - B_TITLED_WINDOW, flags) + SDL_BWin(BRect bounds, window_look look, uint32 flags) + : BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags) { _last_buttons = 0; @@ -372,6 +373,9 @@ class SDL_BWin:public BDirectWindow case BWIN_RESIZE_WINDOW: _ResizeTo(message); break; + case BWIN_SET_BORDERED: + _SetBordered(message); + break; case BWIN_SHOW_WINDOW: Show(); break; @@ -553,7 +557,15 @@ private: } ResizeTo(w, h); } - + + void _SetBordered(BMessage *msg) { + bool bEnabled; + if(msg->FindBool("window-border", &bEnabled) != B_OK) { + return; + } + SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); + } + void _Restore() { if(IsMinimized()) { Minimize(false); diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bclipboard.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bclipboard.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bclipboard.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bclipboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bevents.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bevents.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bevents.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bevents.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bframebuffer.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bframebuffer.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bframebuffer.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bframebuffer.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bkeyboard.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bkeyboard.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bkeyboard.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bkeyboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bmodes.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bmodes.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bmodes.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bmodes.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bopengl.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bopengl.cc old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bopengl.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bopengl.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bvideo.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bvideo.cc old mode 100755 new mode 100644 index 2bfbb6616..eaee88efa --- a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bvideo.cc +++ b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bvideo.cc @@ -80,6 +80,7 @@ BE_CreateDevice(int devindex) device->MaximizeWindow = BE_MaximizeWindow; device->MinimizeWindow = BE_MinimizeWindow; device->RestoreWindow = BE_RestoreWindow; + device->SetWindowBordered = BE_SetWindowBordered; device->SetWindowFullscreen = BE_SetWindowFullscreen; device->SetWindowGammaRamp = BE_SetWindowGammaRamp; device->GetWindowGammaRamp = BE_GetWindowGammaRamp; diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bvideo.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bvideo.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.cc b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.cc old mode 100755 new mode 100644 index 9432de2ff..bc3ae0167 --- a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.cc +++ b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.cc @@ -41,6 +41,8 @@ static inline SDL_BApp *_GetBeApp() { static int _InitWindow(_THIS, SDL_Window *window) { uint32 flags = 0; + window_look look = B_BORDERED_WINDOW_LOOK; + BRect bounds( window->x, window->y, @@ -59,10 +61,10 @@ static int _InitWindow(_THIS, SDL_Window *window) { flags |= B_NOT_RESIZABLE | B_NOT_ZOOMABLE; } if(window->flags & SDL_WINDOW_BORDERLESS) { - /* TODO: Add support for this flag */ + look = B_NO_BORDER_WINDOW_LOOK; } - SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, flags); + SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, look, flags); if(bwin == NULL) return ENOMEM; @@ -137,6 +139,12 @@ void BE_SetWindowSize(_THIS, SDL_Window * window) { _ToBeWin(window)->PostMessage(&msg); } +void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { + BMessage msg(BWIN_SET_BORDERED); + msg.AddBool("window-border", bordered != SDL_FALSE); + _ToBeWin(window)->PostMessage(&msg); +} + void BE_ShowWindow(_THIS, SDL_Window * window) { BMessage msg(BWIN_SHOW_WINDOW); _ToBeWin(window)->PostMessage(&msg); @@ -187,7 +195,7 @@ int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { } -void BE_SetWindowGrab(_THIS, SDL_Window * window) { +void BE_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { /* TODO: Implement this! */ } diff --git a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.h b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.h old mode 100755 new mode 100644 index e979f9b42..a5c992eca --- a/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.h +++ b/src/eepp/helper/SDL2/src/video/bwindow/SDL_bwindow.h @@ -38,10 +38,11 @@ extern void BE_RaiseWindow(_THIS, SDL_Window * window); extern void BE_MaximizeWindow(_THIS, SDL_Window * window); extern void BE_MinimizeWindow(_THIS, SDL_Window * window); extern void BE_RestoreWindow(_THIS, SDL_Window * window); +extern void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void BE_SetWindowGrab(_THIS, SDL_Window * window); +extern void BE_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void BE_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaclipboard.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaclipboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaclipboard.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaclipboard.m old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaevents.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaevents.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaevents.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaevents.m old mode 100755 new mode 100644 index 11c6b4e08..0c42828f1 --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaevents.m +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaevents.m @@ -81,6 +81,7 @@ CreateApplicationMenus(void) NSString *appName; NSString *title; NSMenu *appleMenu; + NSMenu *serviceMenu; NSMenu *windowMenu; NSMenuItem *menuItem; @@ -97,14 +98,22 @@ CreateApplicationMenus(void) [appleMenu addItem:[NSMenuItem separatorItem]]; - [appleMenu addItemWithTitle:@"Preferences" action:nil keyEquivalent:@""]; + [appleMenu addItemWithTitle:@"Preferences…" action:nil keyEquivalent:@","]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + serviceMenu = [[NSMenu alloc] initWithTitle:@""]; + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:serviceMenu]; + + [NSApp setServicesMenu:serviceMenu]; [appleMenu addItem:[NSMenuItem separatorItem]]; title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@/*"h"*/""]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@/*"h"*/""]; + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; @@ -112,7 +121,7 @@ CreateApplicationMenus(void) [appleMenu addItem:[NSMenuItem separatorItem]]; title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@/*"q"*/""]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; /* Put menu into the menubar */ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; @@ -128,11 +137,11 @@ CreateApplicationMenus(void) /* Create the window menu */ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@/*"m"*/""]; - [windowMenu addItem:menuItem]; - [menuItem release]; + /* Add menu items */ + [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; + /* Put menu into the menubar */ menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; [menuItem setSubmenu:windowMenu]; @@ -147,6 +156,7 @@ CreateApplicationMenus(void) void Cocoa_RegisterApp(void) { + /* This can get called more than once! Be careful what you initialize! */ ProcessSerialNumber psn; NSAutoreleasePool *pool; @@ -206,23 +216,17 @@ Cocoa_PumpEvents(_THIS) case NSMouseMoved: case NSScrollWheel: Cocoa_HandleMouseEvent(_this, event); - /* Pass through to NSApp to make sure everything stays in sync */ - [NSApp sendEvent:event]; break; case NSKeyDown: case NSKeyUp: case NSFlagsChanged: Cocoa_HandleKeyEvent(_this, event); - /* Fall through to pass event to NSApp; er, nevermind... */ - - /* Add to support system-wide keyboard shortcuts like CMD+Space */ - if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) - [NSApp sendEvent: event]; break; default: - [NSApp sendEvent:event]; break; } + /* Pass through to NSApp to make sure everything stays in sync */ + [NSApp sendEvent:event]; } [pool release]; } diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoakeyboard.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoakeyboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoakeyboard.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoakeyboard.m old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamodes.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamodes.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamodes.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamodes.m old mode 100755 new mode 100644 index 581e4d4a0..3de8d4da7 --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamodes.m +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamodes.m @@ -102,9 +102,6 @@ CG_SetError(const char *prefix, CGDisplayErr result) case kCGErrorCannotComplete: error = "kCGErrorCannotComplete"; break; - case kCGErrorNameTooLong: - error = "kCGErrorNameTooLong"; - break; case kCGErrorNotImplemented: error = "kCGErrorNotImplemented"; break; @@ -114,9 +111,6 @@ CG_SetError(const char *prefix, CGDisplayErr result) case kCGErrorTypeCheck: error = "kCGErrorTypeCheck"; break; - case kCGErrorNoCurrentPoint: - error = "kCGErrorNoCurrentPoint"; - break; case kCGErrorInvalidOperation: error = "kCGErrorInvalidOperation"; break; diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamouse.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamouse.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamouse.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamouse.m old mode 100755 new mode 100644 index 67b805a95..c56b147be --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamouse.m +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoamouse.m @@ -22,6 +22,7 @@ #if SDL_VIDEO_DRIVER_COCOA +#include "SDL_assert.h" #include "SDL_events.h" #include "SDL_cocoavideo.h" @@ -75,6 +76,68 @@ Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) return cursor; } +static SDL_Cursor * +Cocoa_CreateSystemCursor(SDL_SystemCursor id) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSCursor *nscursor = NULL; + SDL_Cursor *cursor = NULL; + + switch(id) + { + case SDL_SYSTEM_CURSOR_ARROW: + nscursor = [NSCursor arrowCursor]; + break; + case SDL_SYSTEM_CURSOR_IBEAM: + nscursor = [NSCursor IBeamCursor]; + break; + case SDL_SYSTEM_CURSOR_WAIT: + nscursor = [NSCursor arrowCursor]; + break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: + nscursor = [NSCursor crosshairCursor]; + break; + case SDL_SYSTEM_CURSOR_WAITARROW: + nscursor = [NSCursor arrowCursor]; + break; + case SDL_SYSTEM_CURSOR_SIZENWSE: + case SDL_SYSTEM_CURSOR_SIZENESW: + nscursor = [NSCursor closedHandCursor]; + break; + case SDL_SYSTEM_CURSOR_SIZEWE: + nscursor = [NSCursor resizeLeftRightCursor]; + break; + case SDL_SYSTEM_CURSOR_SIZENS: + nscursor = [NSCursor resizeUpDownCursor]; + break; + case SDL_SYSTEM_CURSOR_SIZEALL: + nscursor = [NSCursor closedHandCursor]; + break; + case SDL_SYSTEM_CURSOR_NO: + nscursor = [NSCursor operationNotAllowedCursor]; + break; + case SDL_SYSTEM_CURSOR_HAND: + nscursor = [NSCursor pointingHandCursor]; + break; + default: + SDL_assert(!"Unknown system cursor"); + return NULL; + } + + if (nscursor) { + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + // We'll free it later, so retain it here + [nscursor retain]; + cursor->driverdata = nscursor; + } + } + + [pool release]; + + return cursor; +} + static void Cocoa_FreeCursor(SDL_Cursor * cursor) { @@ -139,6 +202,7 @@ Cocoa_InitMouse(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); mouse->CreateCursor = Cocoa_CreateCursor; + mouse->CreateSystemCursor = Cocoa_CreateSystemCursor; mouse->ShowCursor = Cocoa_ShowCursor; mouse->FreeCursor = Cocoa_FreeCursor; mouse->WarpMouse = Cocoa_WarpMouse; diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaopengl.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaopengl.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaopengl.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaopengl.m old mode 100755 new mode 100644 index 44dcc30d6..880b0c145 --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoaopengl.m @@ -32,9 +32,16 @@ #include "SDL_loadso.h" #include "SDL_opengl.h" - #define DEFAULT_OPENGL "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib" + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 +#define kCGLPFAOpenGLProfile 99 +#define kCGLOGLPVersion_Legacy 0x1000 +#define kCGLOGLPVersion_3_2_Core 0x3200 +#endif + + int Cocoa_GL_LoadLibrary(_THIS, const char *path) { @@ -70,6 +77,9 @@ Cocoa_GL_UnloadLibrary(_THIS) SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window) { + const int wantver = (_this->gl_config.major_version << 8) | + (_this->gl_config.minor_version); + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; NSAutoreleasePool *pool; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; @@ -78,8 +88,32 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) NSOpenGLContext *context; int i = 0; + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { + SDL_SetError ("OpenGL ES not supported on this platform"); + return NULL; + } + + /* Sadly, we'll have to update this as life progresses, since we need to + set an enum for context profiles, not a context version number */ + if (wantver > 0x0302) { + SDL_SetError ("OpenGL > 3.2 is not supported on this platform"); + return NULL; + } + pool = [[NSAutoreleasePool alloc] init]; + /* specify a profile if we're on Lion (10.7) or later. */ + if (data->osversion >= 0x1070) { + NSOpenGLPixelFormatAttribute profile = kCGLOGLPVersion_Legacy; + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) { + if (wantver == 0x0302) { + profile = kCGLOGLPVersion_3_2_Core; + } + } + attr[i++] = kCGLPFAOpenGLProfile; + attr[i++] = profile; + } + #ifndef FULLSCREEN_TOGGLEABLE if (window->flags & SDL_WINDOW_FULLSCREEN) { attr[i++] = NSOpenGLPFAFullScreen; @@ -250,7 +284,7 @@ Cocoa_GL_GetSwapInterval(_THIS) NSAutoreleasePool *pool; NSOpenGLContext *nscontext; GLint value; - int status; + int status = 0; pool = [[NSAutoreleasePool alloc] init]; @@ -258,9 +292,6 @@ Cocoa_GL_GetSwapInterval(_THIS) if (nscontext != nil) { [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval]; status = (int)value; - } else { - SDL_SetError("No current OpenGL context"); - status = -1; } [pool release]; diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoashape.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoashape.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoashape.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoashape.m old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoavideo.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoavideo.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoavideo.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoavideo.m old mode 100755 new mode 100644 index c79ed4544..aa832bdad --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoavideo.m +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoavideo.m @@ -22,6 +22,13 @@ #if SDL_VIDEO_DRIVER_COCOA +#if defined(__APPLE__) && defined(__POWERPC__) +#include +#undef bool +#undef vector +#undef pixel +#endif + #include "SDL.h" #include "SDL_endian.h" #include "SDL_cocoavideo.h" @@ -88,12 +95,14 @@ Cocoa_CreateDevice(int devindex) device->SetWindowIcon = Cocoa_SetWindowIcon; device->SetWindowPosition = Cocoa_SetWindowPosition; device->SetWindowSize = Cocoa_SetWindowSize; + device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize; device->ShowWindow = Cocoa_ShowWindow; device->HideWindow = Cocoa_HideWindow; device->RaiseWindow = Cocoa_RaiseWindow; device->MaximizeWindow = Cocoa_MaximizeWindow; device->MinimizeWindow = Cocoa_MinimizeWindow; device->RestoreWindow = Cocoa_RestoreWindow; + device->SetWindowBordered = Cocoa_SetWindowBordered; device->SetWindowFullscreen = Cocoa_SetWindowFullscreen; device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; @@ -210,6 +219,18 @@ Cocoa_CreateImage(SDL_Surface * surface) return img; } +/* + * Mac OS X log support. + * + * This doesn't really have aything to do with the interfaces of the SDL video + * subsystem, but we need to stuff this into an Objective-C source code file. + */ + +void SDL_NSLog(const char *text) +{ + NSLog(@"%s", text); +} + /* * Mac OS X assertion support. * diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.h b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.h old mode 100755 new mode 100644 index 4d6e756ce..9c8149ef5 --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.h +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.h @@ -56,8 +56,6 @@ typedef struct SDL_WindowData SDL_WindowData; -(void) mouseUp:(NSEvent *) theEvent; -(void) rightMouseUp:(NSEvent *) theEvent; -(void) otherMouseUp:(NSEvent *) theEvent; --(void) mouseEntered:(NSEvent *)theEvent; --(void) mouseExited:(NSEvent *)theEvent; -(void) mouseMoved:(NSEvent *) theEvent; -(void) mouseDragged:(NSEvent *) theEvent; -(void) rightMouseDragged:(NSEvent *) theEvent; @@ -96,16 +94,18 @@ extern void Cocoa_SetWindowTitle(_THIS, SDL_Window * window); extern void Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window); extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window); +extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void Cocoa_ShowWindow(_THIS, SDL_Window * window); extern void Cocoa_HideWindow(_THIS, SDL_Window * window); extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window); extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window); extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window); extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window); +extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window); +extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.m b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.m old mode 100755 new mode 100644 index ef19ce002..cf880325d --- a/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.m +++ b/src/eepp/helper/SDL2/src/video/cocoa/SDL_cocoawindow.m @@ -200,10 +200,8 @@ static __inline__ void ConvertNSRect(NSRect *r) y = (int)(window->h - point.y); if (x >= 0 && x < window->w && y >= 0 && y < window->h) { - if (SDL_GetMouseFocus() != window) { - [self mouseEntered:nil]; - } SDL_SendMouseMotion(window, 0, x, y); + SDL_SetCursor(NULL); } } @@ -224,6 +222,29 @@ static __inline__ void ConvertNSRect(NSRect *r) } } +// We'll respond to key events by doing nothing so we don't beep. +// We could handle key messages here, but we lose some in the NSApp dispatch, +// where they get converted to action messages, etc. +- (void)flagsChanged:(NSEvent *)theEvent +{ + //Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent); +} +- (void)keyDown:(NSEvent *)theEvent +{ + //Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent); +} +- (void)keyUp:(NSEvent *)theEvent +{ + //Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent); +} + +// We'll respond to selectors by doing nothing so we don't beep. +// The escape key gets converted to a "cancel" selector, etc. +- (void)doCommandBySelector:(SEL)aSelector +{ + //NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector)); +} + - (void)mouseDown:(NSEvent *)theEvent { int button; @@ -286,38 +307,6 @@ static __inline__ void ConvertNSRect(NSRect *r) [self mouseUp:theEvent]; } -- (void)mouseEntered:(NSEvent *)theEvent -{ - SDL_SetMouseFocus(_data->window); - - SDL_SetCursor(NULL); -} - -- (void)mouseExited:(NSEvent *)theEvent -{ - SDL_Window *window = _data->window; - - if (SDL_GetMouseFocus() == window) { - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - int x, y; - NSPoint point; - CGPoint cgpoint; - - point = [theEvent locationInWindow]; - point.y = window->h - point.y; - - SDL_SendMouseMotion(window, 0, (int)point.x, (int)point.y); - SDL_GetMouseState(&x, &y); - cgpoint.x = window->x + x; - cgpoint.y = window->y + y; - CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); - } else { - SDL_SetMouseFocus(NULL); - SDL_SetCursor(NULL); - } - } -} - - (void)mouseMoved:(NSEvent *)theEvent { SDL_Mouse *mouse = SDL_GetMouse(); @@ -334,15 +323,26 @@ static __inline__ void ConvertNSRect(NSRect *r) y = (int)(window->h - point.y); if (x < 0 || x >= window->w || y < 0 || y >= window->h) { - if (SDL_GetMouseFocus() == window) { - [self mouseExited:theEvent]; + if (window->flags & SDL_WINDOW_INPUT_GRABBED) { + CGPoint cgpoint; + + if (x < 0) { + x = 0; + } else if (x >= window->w) { + x = window->w - 1; + } + if (y < 0) { + y = 0; + } else if (y >= window->h) { + y = window->h - 1; + } + + cgpoint.x = window->x + x; + cgpoint.y = window->y + y; + CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); } - } else { - if (SDL_GetMouseFocus() != window) { - [self mouseEntered:theEvent]; - } - SDL_SendMouseMotion(window, 0, x, y); } + SDL_SendMouseMotion(window, 0, x, y); } - (void)mouseDragged:(NSEvent *)theEvent @@ -530,14 +530,6 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created /* Fill in the SDL window with the window data */ { NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; - NSView *contentView = [ nswindow contentView ]; - /* Create view if not already exists */ - if (!contentView) { - contentView = [[SDLView alloc] initWithFrame:rect]; - [nswindow setContentView: contentView]; - [contentView release]; - } - ConvertNSRect(&rect); window->x = (int)rect.origin.x; window->y = (int)rect.origin.y; @@ -627,6 +619,12 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) } nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:YES screen:screen]; + // Create a default view for this window + rect = [nswindow contentRectForFrameRect:[nswindow frame]]; + NSView *contentView = [[SDLView alloc] initWithFrame:rect]; + [nswindow setContentView: contentView]; + [contentView release]; + [pool release]; if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) { @@ -732,6 +730,21 @@ Cocoa_SetWindowSize(_THIS, SDL_Window * window) [pool release]; } +void +Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; + + NSSize minSize; + minSize.width = window->min_w; + minSize.height = window->min_h; + + [windata->nswindow setMinSize:minSize]; + + [pool release]; +} + void Cocoa_ShowWindow(_THIS, SDL_Window * window) { @@ -821,6 +834,23 @@ Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style) return data->nswindow; } +void +Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +{ + /* this message arrived in 10.6. You're out of luck on older OSes. */ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + if ([nswindow respondsToSelector:@selector(setStyleMask:)]) { + [nswindow setStyleMask:GetWindowStyle(window)]; + if (bordered) { + Cocoa_SetWindowTitle(_this, window); // this got blanked out. + } + } + [pool release]; +#endif +} + void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { @@ -954,11 +984,10 @@ Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) } void -Cocoa_SetWindowGrab(_THIS, SDL_Window * window) +Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { /* Move the cursor to the nearest point in the window */ - if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && - (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + if (grabbed) { int x, y; CGPoint cgpoint; diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_WM.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_WM.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_WM.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_WM.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_dyn.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_dyn.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_dyn.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_dyn.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_events.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_events.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_events.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_events.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_modes.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_modes.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_modes.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_modes.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_mouse.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_mouse.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_mouse.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_mouse.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_opengl.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_opengl.c old mode 100755 new mode 100644 index fa37850a5..3d2806bb3 --- a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_opengl.c +++ b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_opengl.c @@ -250,8 +250,7 @@ DirectFB_GL_SetSwapInterval(_THIS, int interval) int DirectFB_GL_GetSwapInterval(_THIS) { - SDL_Unsupported(); - return -1; + return 0; } void diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_opengl.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_opengl.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_render.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_render.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_render.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_render.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_shape.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_shape.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_shape.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_shape.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_video.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_video.c old mode 100755 new mode 100644 index fde8093f0..807fc85d6 --- a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_video.c +++ b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_video.c @@ -132,6 +132,8 @@ DirectFB_CreateDevice(int devindex) device->DestroyWindow = DirectFB_DestroyWindow; device->GetWindowWMInfo = DirectFB_GetWindowWMInfo; + /* !!! FIXME: implement SetWindowBordered */ + #if SDL_DIRECTFB_OPENGL device->GL_LoadLibrary = DirectFB_GL_LoadLibrary; device->GL_GetProcAddress = DirectFB_GL_GetProcAddress; diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_video.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_video.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_window.c b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_window.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_window.h b/src/eepp/helper/SDL2/src/video/directfb/SDL_DirectFB_window.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/dummy/SDL_nullevents.c b/src/eepp/helper/SDL2/src/video/dummy/SDL_nullevents.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/dummy/SDL_nullevents_c.h b/src/eepp/helper/SDL2/src/video/dummy/SDL_nullevents_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/dummy/SDL_nullframebuffer.c b/src/eepp/helper/SDL2/src/video/dummy/SDL_nullframebuffer.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/dummy/SDL_nullframebuffer_c.h b/src/eepp/helper/SDL2/src/video/dummy/SDL_nullframebuffer_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/dummy/SDL_nullvideo.c b/src/eepp/helper/SDL2/src/video/dummy/SDL_nullvideo.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/dummy/SDL_nullvideo.h b/src/eepp/helper/SDL2/src/video/dummy/SDL_nullvideo.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/nds/SDL_ndsevents.c b/src/eepp/helper/SDL2/src/video/nds/SDL_ndsevents.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/nds/SDL_ndsevents_c.h b/src/eepp/helper/SDL2/src/video/nds/SDL_ndsevents_c.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/nds/SDL_ndsvideo.c b/src/eepp/helper/SDL2/src/video/nds/SDL_ndsvideo.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/nds/SDL_ndsvideo.h b/src/eepp/helper/SDL2/src/video/nds/SDL_ndsvideo.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/nds/SDL_ndswindow.c b/src/eepp/helper/SDL2/src/video/nds/SDL_ndswindow.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/nds/SDL_ndswindow.h b/src/eepp/helper/SDL2/src/video/nds/SDL_ndswindow.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora.c b/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora.c old mode 100755 new mode 100644 index 3c3651282..46430d1bb --- a/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora.c +++ b/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora.c @@ -131,6 +131,8 @@ PND_create() device->GL_DeleteContext = PND_gl_deletecontext; device->PumpEvents = PND_PumpEvents; + /* !!! FIXME: implement SetWindowBordered */ + return device; } @@ -796,15 +798,7 @@ PND_gl_setswapinterval(_THIS, int interval) int PND_gl_getswapinterval(_THIS) { - SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; - - if (phdata->egl_initialized != SDL_TRUE) { - SDL_SetError("PND: GLES initialization failed, no OpenGL ES support"); - return -1; - } - - /* Return default swap interval value */ - return phdata->swapinterval; + return ((SDL_VideoData *) _this->driverdata)->swapinterval; } void diff --git a/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora.h b/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora_events.c b/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora_events.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora_events.h b/src/eepp/helper/SDL2/src/video/pandora/SDL_pandora_events.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitappdelegate.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitappdelegate.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitappdelegate.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitappdelegate.m old mode 100755 new mode 100644 index 9c5440220..2d263dd56 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitappdelegate.m @@ -22,15 +22,16 @@ #if SDL_VIDEO_DRIVER_UIKIT -#import "../SDL_sysvideo.h" -#import "SDL_assert.h" -#import "SDL_hints.h" -#import "../../SDL_hints_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_assert.h" +#include "SDL_hints.h" +#include "../../SDL_hints_c.h" +#include "SDL_system.h" -#import "SDL_uikitappdelegate.h" -#import "SDL_uikitopenglview.h" -#import "../../events/SDL_events_c.h" -#import "jumphack.h" +#include "SDL_uikitappdelegate.h" +#include "SDL_uikitmodes.h" +#include "../../events/SDL_events_c.h" +#include "jumphack.h" #ifdef main #undef main @@ -40,6 +41,7 @@ extern int SDL_main(int argc, char *argv[]); static int forward_argc; static char **forward_argv; static int exit_status; +static UIWindow *launch_window; int main(int argc, char **argv) { @@ -76,6 +78,91 @@ static void SDL_IdleTimerDisabledChanged(const char *name, const char *oldValue, [UIApplication sharedApplication].idleTimerDisabled = disable; } +@interface SDL_splashviewcontroller : UIViewController { + UIImageView *splash; + UIImage *splashPortrait; + UIImage *splashLandscape; +} + +- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation; +@end + +@implementation SDL_splashviewcontroller + +- (id)init +{ + self = [super init]; + if (self == nil) { + return nil; + } + + self->splash = [[UIImageView alloc] init]; + [self setView:self->splash]; + + CGSize size = [UIScreen mainScreen].bounds.size; + float height = SDL_max(size.width, size.height); + self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]]; + if (!self->splashPortrait) { + self->splashPortrait = [UIImage imageNamed:@"Default.png"]; + } + self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"]; + if (!self->splashLandscape && self->splashPortrait) { + self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage + scale: 1.0 + orientation: UIImageOrientationRight]; + } + if (self->splashPortrait) { + [self->splashPortrait retain]; + } + if (self->splashLandscape) { + [self->splashLandscape retain]; + } + + [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]]; + + return self; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + NSUInteger orientationMask = UIInterfaceOrientationMaskAll; + + // Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown; + } + return orientationMask; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient +{ + NSUInteger orientationMask = [self supportedInterfaceOrientations]; + return (orientationMask & (1 << orient)); +} + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration +{ + [self updateSplashImage:interfaceOrientation]; +} + +- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation +{ + UIImage *image; + + if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { + image = self->splashLandscape; + } else { + image = self->splashPortrait; + } + if (image) + { + splash.image = image; + } +} + +@end + + @implementation SDLUIKitDelegate /* convenience method */ @@ -100,22 +187,40 @@ static void SDL_IdleTimerDisabledChanged(const char *name, const char *oldValue, - (void)postFinishLaunch { - /* register a callback for the idletimer hint */ - SDL_SetHint(SDL_HINT_IDLE_TIMER_DISABLED, "0"); - SDL_RegisterHintChangedCb(SDL_HINT_IDLE_TIMER_DISABLED, &SDL_IdleTimerDisabledChanged); - /* run the user's application, passing argc and argv */ + SDL_iPhoneSetEventPump(SDL_TRUE); exit_status = SDL_main(forward_argc, forward_argv); + SDL_iPhoneSetEventPump(SDL_FALSE); + + /* If we showed a splash image, clean it up */ + if (launch_window) { + [launch_window release]; + launch_window = NULL; + } /* exit, passing the return status from the user's application */ + // We don't actually exit to support applications that do setup in + // their main function and then allow the Cocoa event loop to run. // exit(exit_status); } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + /* Keep the launch image up until we set a video mode */ + launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init]; + launch_window.rootViewController = splashViewController; + [launch_window addSubview:splashViewController.view]; + [launch_window makeKeyAndVisible]; + /* Set working directory to resource path */ [[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]]; + /* register a callback for the idletimer hint */ + SDL_SetHint(SDL_HINT_IDLE_TIMER_DISABLED, "0"); + SDL_RegisterHintChangedCb(SDL_HINT_IDLE_TIMER_DISABLED, &SDL_IdleTimerDisabledChanged); + [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0]; return YES; @@ -162,6 +267,17 @@ static void SDL_IdleTimerDisabledChanged(const char *name, const char *oldValue, } } +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + NSURL *fileURL = [url filePathURL]; + if (fileURL != nil) { + SDL_SendDropFile([[fileURL path] UTF8String]); + } else { + SDL_SendDropFile([[url absoluteString] UTF8String]); + } + return YES; +} + @end #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitevents.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitevents.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitevents.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitevents.m old mode 100755 new mode 100644 index 4dea87f8b..e7f0dcc63 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitevents.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitevents.m @@ -30,9 +30,20 @@ #import #include "jumphack.h" +static BOOL UIKit_EventPumpEnabled = YES; + +void +SDL_iPhoneSetEventPump(SDL_bool enabled) +{ + UIKit_EventPumpEnabled = enabled; +} + void UIKit_PumpEvents(_THIS) { + if (!UIKit_EventPumpEnabled) + return; + /* When the user presses the 'home' button on the iPod the application exits -- immediatly. @@ -46,10 +57,25 @@ UIKit_PumpEvents(_THIS) */ if (setjmp(*jump_env()) == 0) { /* if we're setting the jump, rather than jumping back */ + + /* Let the run loop run for a short amount of time: long enough for + touch events to get processed (which is important to get certain + elements of Game Center's GKLeaderboardViewController to respond + to touch input), but not long enough to introduce a significant + delay in the rest of the app. + */ + const CFTimeInterval seconds = 0.000002; + + /* Pump most event types. */ SInt32 result; do { - result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE); + result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, TRUE); } while (result == kCFRunLoopRunHandledSource); + + /* Make sure UIScrollView objects scroll properly. */ + do { + result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE); + } while(result == kCFRunLoopRunHandledSource); } } diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopengles.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopengles.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopengles.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopengles.m old mode 100755 new mode 100644 index f377b2b3c..8517cb410 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopengles.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopengles.m @@ -25,6 +25,7 @@ #include "SDL_uikitopengles.h" #include "SDL_uikitopenglview.h" #include "SDL_uikitappdelegate.h" +#include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" #include "jumphack.h" #include "../SDL_sysvideo.h" @@ -90,13 +91,9 @@ void UIKit_GL_SwapWindow(_THIS, SDL_Window * window) return; } [data->view swapBuffers]; - /* since now we've got something to draw - make the window visible */ - [data->uiwindow makeKeyAndVisible]; /* we need to let the event cycle run, or the OS won't update the OpenGL view! */ SDL_PumpEvents(); - } SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window) @@ -109,7 +106,13 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window) UIWindow *uiwindow = data->uiwindow; /* construct our view, passing in SDL's OpenGL configuration data */ - view = [[SDL_uikitopenglview alloc] initWithFrame: [uiwindow bounds] + CGRect frame; + if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) { + frame = [displaydata->uiscreen bounds]; + } else { + frame = [displaydata->uiscreen applicationFrame]; + } + view = [[SDL_uikitopenglview alloc] initWithFrame: frame scale: displaymodedata->scale retainBacking: _this->gl_config.retained_backing rBits: _this->gl_config.red_size @@ -129,11 +132,14 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window) [view->viewcontroller setView:view]; [view->viewcontroller retain]; } + [uiwindow addSubview: view]; + + // The view controller needs to be the root in order to control rotation on iOS 6.0 + if (uiwindow.rootViewController == nil) { + uiwindow.rootViewController = view->viewcontroller; + } - /* add the view to our window */ - [uiwindow addSubview: view ]; - - if ( UIKit_GL_MakeCurrent(_this, window, view) < 0 ) { + if (UIKit_GL_MakeCurrent(_this, window, view) < 0) { UIKit_GL_DeleteContext(_this, view); return NULL; } @@ -152,6 +158,10 @@ void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) /* the delegate has retained the view, this will release him */ SDL_uikitopenglview *view = (SDL_uikitopenglview *)context; if (view->viewcontroller) { + UIWindow *uiwindow = (UIWindow *)view.superview; + if (uiwindow.rootViewController == view->viewcontroller) { + uiwindow.rootViewController = nil; + } [view->viewcontroller setView:nil]; [view->viewcontroller release]; } diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.h old mode 100755 new mode 100644 index 8c1ba3c84..255ff6a4a --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.h +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.h @@ -46,6 +46,11 @@ /* format of depthRenderbuffer */ GLenum depthBufferFormat; + + id displayLink; + int animationInterval; + void (*animationCallback)(void*); + void *animationCallbackParam; } @property (nonatomic, retain, readonly) EAGLContext *context; @@ -66,6 +71,15 @@ - (void)updateFrame; +- (void)setAnimationCallback:(int)interval + callback:(void (*)(void*))callback + callbackParam:(void*)callbackParam; + +- (void)startAnimation; +- (void)stopAnimation; + +- (void)doLoop:(id)sender; + @end /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.m old mode 100755 new mode 100644 index d38b26c9b..afa4fe279 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitopenglview.m @@ -22,9 +22,10 @@ #if SDL_VIDEO_DRIVER_UIKIT -#import -#import -#import "SDL_uikitopenglview.h" +#include +#include +#include "SDL_uikitopenglview.h" +#include "SDL_uikitmessagebox.h" @implementation SDL_uikitopenglview @@ -121,7 +122,8 @@ } /* end create buffers */ - self.autoresizingMask = 0; // don't allow autoresize, since we need to do some magic in -(void)updateFrame. + self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); + self.autoresizesSubviews = YES; } return self; } @@ -147,6 +149,44 @@ } } +- (void)setAnimationCallback:(int)interval + callback:(void (*)(void*))callback + callbackParam:(void*)callbackParam +{ + [self stopAnimation]; + + animationInterval = interval; + animationCallback = callback; + animationCallbackParam = callbackParam; + + if (animationCallback) + [self startAnimation]; +} + +- (void)startAnimation +{ + // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed + // if the system version runtime check for CADisplayLink exists in -initWithCoder:. + + displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doLoop:)]; + [displayLink setFrameInterval:animationInterval]; + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; +} + +- (void)stopAnimation +{ + [displayLink invalidate]; + displayLink = nil; +} + +- (void)doLoop:(id)sender +{ + // Don't run the game loop while a messagebox is up + if (!UIKit_ShowingMessageBox()) { + animationCallback(animationCallbackParam); + } +} + - (void)setCurrentContext { [EAGLContext setCurrentContext:context]; @@ -163,6 +203,7 @@ - (void)layoutSubviews { [EAGLContext setCurrentContext:context]; + [self updateFrame]; } - (void)destroyFramebuffer diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.h old mode 100755 new mode 100644 index 4f2cea35c..1cf608b4e --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.h +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.h @@ -23,23 +23,22 @@ #include -extern BOOL SDL_UIKit_supports_multiple_displays; +#include "../SDL_sysvideo.h" -typedef struct SDL_DisplayData SDL_DisplayData; - -struct SDL_DisplayData +#ifndef __IPHONE_6_0 +// This enum isn't available in older SDKs, but we use it for our own purposes on iOS 5.1 and for the system on iOS 6.0 +enum UIInterfaceOrientationMask { - UIScreen *uiscreen; - CGFloat scale; + UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait), + UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft), + UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight), + UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown), + UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), + UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown), + UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), }; +#endif // !__IPHONE_6_0 -typedef struct SDL_DisplayModeData SDL_DisplayModeData; - -struct SDL_DisplayModeData -{ - UIScreenMode *uiscreenmode; - CGFloat scale; -}; #endif /* _SDL_uikitvideo_h */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.m old mode 100755 new mode 100644 index a08fee1c6..0c3764e01 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitvideo.m @@ -32,22 +32,16 @@ #include "SDL_uikitvideo.h" #include "SDL_uikitevents.h" +#include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" #include "SDL_uikitopengles.h" -#include "SDL_assert.h" - #define UIKITVID_DRIVER_NAME "uikit" /* Initialization/Query functions */ static int UIKit_VideoInit(_THIS); -static void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display); -static int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, - SDL_DisplayMode * mode); static void UIKit_VideoQuit(_THIS); -BOOL SDL_UIKit_supports_multiple_displays = NO; - /* DUMMY driver bootstrap functions */ static int @@ -83,10 +77,19 @@ UIKit_CreateDevice(int devindex) device->SetDisplayMode = UIKit_SetDisplayMode; device->PumpEvents = UIKit_PumpEvents; device->CreateWindow = UIKit_CreateWindow; + device->ShowWindow = UIKit_ShowWindow; + device->HideWindow = UIKit_HideWindow; + device->RaiseWindow = UIKit_RaiseWindow; device->SetWindowFullscreen = UIKit_SetWindowFullscreen; device->DestroyWindow = UIKit_DestroyWindow; device->GetWindowWMInfo = UIKit_GetWindowWMInfo; + /* !!! FIXME: implement SetWindowBordered */ + + device->SDL_HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; + device->SDL_ShowScreenKeyboard = UIKit_ShowScreenKeyboard; + device->SDL_HideScreenKeyboard = UIKit_HideScreenKeyboard; + device->SDL_IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; /* OpenGL (ES) functions */ device->GL_MakeCurrent = UIKit_GL_MakeCurrent; @@ -108,273 +111,33 @@ VideoBootStrap UIKIT_bootstrap = { }; -/* -!!! FIXME: - -The main screen should list a AxB mode for portrait orientation, and then - also list BxA for landscape mode. When setting a given resolution, we should - rotate the view's transform appropriately (extra credit if you check the - accelerometer and rotate the display so it's never upside down). - - http://iphonedevelopment.blogspot.com/2008/10/starting-in-landscape-mode-without.html - -*/ - -static int -UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode, - UIScreenMode * uiscreenmode, CGFloat scale) -{ - SDL_DisplayModeData *data = NULL; - - if (uiscreenmode != nil) { - /* Allocate the display mode data */ - data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - return -1; - } - - data->uiscreenmode = uiscreenmode; - [data->uiscreenmode retain]; - - data->scale = scale; - } - - mode->driverdata = data; - - return 0; -} - -static void -UIKit_FreeDisplayModeData(SDL_DisplayMode * mode) -{ - if (!SDL_UIKit_supports_multiple_displays) { - // Not on at least iPhoneOS 3.2 (versions prior to iPad). - SDL_assert(mode->driverdata == NULL); - } else if (mode->driverdata != NULL) { - SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata; - [data->uiscreenmode release]; - SDL_free(data); - mode->driverdata = NULL; - } -} - -static int -UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h, - UIScreenMode * uiscreenmode, CGFloat scale) -{ - SDL_DisplayMode mode; - SDL_zero(mode); - - mode.format = SDL_PIXELFORMAT_ABGR8888; - mode.refresh_rate = 0; - if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) { - return -1; - } - - mode.w = w; - mode.h = h; - if (SDL_AddDisplayMode(display, &mode)) { - return 0; - } - - // Failure case; free resources - SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode.driverdata; - - if (data != NULL) { - [data->uiscreenmode release]; - SDL_free(data); - } - - return -1; -} - -static int -UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale, - UIScreenMode * uiscreenmode, BOOL rotated) -{ - if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) { - return -1; - } - - if (rotated) { - // Add the rotated version - if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) { - return -1; - } - } - - return 0; -} - -static void -UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) -{ - SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - - if (SDL_UIKit_supports_multiple_displays) { - // availableModes showed up in 3.2 (the iPad and later). We should only - // land here for at least that version of the OS. - for (UIScreenMode *uimode in [data->uiscreen availableModes]) { - BOOL mainscreen = (data->uiscreen == [UIScreen mainScreen]); - CGSize size = [uimode size]; - int w = (int)size.width; - int h = (int)size.height; - - // Add the native screen resolution. - UIKit_AddDisplayMode(display, w, h, data->scale, uimode, mainscreen); - - if (data->scale != 1.0f) { - // Add the native screen resolution divided by its scale. - // This is so devices capable of e.g. 640x960 also advertise - // 320x480. - UIKit_AddDisplayMode(display, - (int)(w / data->scale), (int)(h / data->scale), - 1.0f, uimode, mainscreen); - } - } - } else { - const CGRect rect = [data->uiscreen bounds]; - UIKit_AddDisplayMode(display, - (int)rect.size.width, (int)rect.size.height, - 1.0f, nil, YES); - } -} - - -static int -UIKit_AddDisplay(UIScreen *uiscreen, CGSize size) -{ - // When dealing with UIKit all coordinates are specified in terms of - // what Apple refers to as points. On earlier devices without the - // so called "Retina" display, there is a one to one mapping between - // points and pixels. In other cases [UIScreen scale] indicates the - // relationship between points and pixels. Since SDL has no notion - // of points, we must compensate in all cases where dealing with such - // units. - CGFloat scale; - if ([UIScreen instancesRespondToSelector:@selector(scale)]) { - scale = [uiscreen scale]; // iOS >= 4.0 - } else { - scale = 1.0f; // iOS < 4.0 - } - - SDL_VideoDisplay display; - SDL_DisplayMode mode; - SDL_zero(mode); - mode.format = SDL_PIXELFORMAT_ABGR8888; - mode.w = (int)(size.width * scale); - mode.h = (int)(size.height * scale); - mode.refresh_rate = 0; - - UIScreenMode * uiscreenmode = nil; - // UIScreenMode showed up in 3.2 (the iPad and later). We're - // misusing this supports_multiple_displays flag here for that. - if (SDL_UIKit_supports_multiple_displays) { - uiscreenmode = [uiscreen currentMode]; - } - - if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) { - return -1; - } - - SDL_zero(display); - display.desktop_mode = mode; - display.current_mode = mode; - - /* Allocate the display data */ - SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - UIKit_FreeDisplayModeData(&display.desktop_mode); - return -1; - } - - [uiscreen retain]; - data->uiscreen = uiscreen; - data->scale = scale; - - display.driverdata = data; - SDL_AddVideoDisplay(&display); - - return 0; -} - - int UIKit_VideoInit(_THIS) { _this->gl_config.driver_loaded = 1; - // this tells us whether we are running on ios >= 3.2 - SDL_UIKit_supports_multiple_displays = [UIScreen instancesRespondToSelector:@selector(currentMode)]; - - // Add the main screen. - UIScreen *uiscreen = [UIScreen mainScreen]; - const CGSize size = [uiscreen bounds].size; - - if (UIKit_AddDisplay(uiscreen, size) < 0) { + if (UIKit_InitModes(_this) < 0) { return -1; } - - // If this is iPhoneOS < 3.2, all devices are one screen, 320x480 pixels. - // The iPad added both a larger main screen and the ability to use - // external displays. So, add the other displays (screens in UI speak). - if (SDL_UIKit_supports_multiple_displays) { - for (UIScreen *uiscreen in [UIScreen screens]) { - // Only add the other screens - if (uiscreen != [UIScreen mainScreen]) { - const CGSize size = [uiscreen bounds].size; - if (UIKit_AddDisplay(uiscreen, size) < 0) { - return -1; - } - } - } - } - - /* We're done! */ - return 0; -} - -static int -UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - if (!SDL_UIKit_supports_multiple_displays) { - // Not on at least iPhoneOS 3.2 (versions prior to iPad). - SDL_assert(mode->driverdata == NULL); - } else { - SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; - [data->uiscreen setCurrentMode:modedata->uiscreenmode]; - - CGSize size = [modedata->uiscreenmode size]; - if (size.width >= size.height) { - [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]; - } else { - [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; - } - } - return 0; } void UIKit_VideoQuit(_THIS) { - // Release Objective-C objects, so higher level doesn't free() them. - int i, j; - for (i = 0; i < _this->num_displays; i++) { - SDL_VideoDisplay *display = &_this->displays[i]; - SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - [data->uiscreen release]; - SDL_free(data); - display->driverdata = NULL; - UIKit_FreeDisplayModeData(&display->desktop_mode); - for (j = 0; j < display->num_display_modes; j++) { - SDL_DisplayMode *mode = &display->display_modes[j]; - UIKit_FreeDisplayModeData(mode); - } - } + UIKit_QuitModes(_this); +} + +/* + * iOS log support. + * + * This doesn't really have aything to do with the interfaces of the SDL video + * subsystem, but we need to stuff this into an Objective-C source code file. + */ + +void SDL_NSLog(const char *text) +{ + NSLog(@"%s", text); } #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.h old mode 100755 new mode 100644 index b9aad299a..a1f833b04 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.h +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.h @@ -22,8 +22,9 @@ #import #import "SDL_uikitviewcontroller.h" +#include "SDL_touch.h" + #define IPHONE_TOUCH_EFFICIENT_DANGEROUS -#define FIXED_MULTITOUCH #ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS #define MAX_SIMULTANEOUS_TOUCHES 5 @@ -35,12 +36,11 @@ @interface SDL_uikitview : UIView { #endif -#ifdef FIXED_MULTITOUCH - long touchId; + SDL_TouchID touchId; + SDL_FingerID leftFingerDown; #ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS UITouch *finger[MAX_SIMULTANEOUS_TOUCHES]; #endif -#endif #if SDL_IPHONE_KEYBOARD UITextField *textField; @@ -50,7 +50,7 @@ @public SDL_uikitviewcontroller *viewcontroller; } -- (CGPoint)touchLocation:(UITouch *)touch; +- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; @@ -60,6 +60,12 @@ - (void)hideKeyboard; - (void)initializeKeyboard; @property (readonly) BOOL keyboardVisible; + +SDL_bool UIKit_HasScreenKeyboardSupport(_THIS); +void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window); +void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window); +SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window); + #endif @end diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.m old mode 100755 new mode 100644 index d15aaaa33..254a96149 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitview.m @@ -22,17 +22,17 @@ #if SDL_VIDEO_DRIVER_UIKIT -#import "SDL_uikitview.h" +#include "SDL_uikitview.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_touch_c.h" #if SDL_IPHONE_KEYBOARD -#import "keyinfotable.h" -#import "SDL_uikitappdelegate.h" -#import "SDL_uikitkeyboard.h" -#import "SDL_uikitwindow.h" +#include "keyinfotable.h" +#include "SDL_uikitappdelegate.h" +#include "SDL_uikitmodes.h" +#include "SDL_uikitwindow.h" #endif @implementation SDL_uikitview @@ -50,7 +50,6 @@ [self initializeKeyboard]; #endif -#ifdef FIXED_MULTITOUCH self.multipleTouchEnabled = YES; SDL_Touch touch; @@ -69,22 +68,29 @@ touch.pressure_max = 1; touch.native_pressureres = touch.pressure_max - touch.pressure_min; - touchId = SDL_AddTouch(&touch, "IPHONE SCREEN"); -#endif return self; } -- (CGPoint)touchLocation:(UITouch *)touch +- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize { CGPoint point = [touch locationInView: self]; - CGRect frame = [self frame]; - frame = CGRectApplyAffineTransform(frame, [self transform]); - point.x /= frame.size.width; - point.y /= frame.size.height; + // Get the display scale and apply that to the input coordinates + SDL_Window *window = self->viewcontroller.window; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata; + + if (normalize) { + CGRect bounds = [self bounds]; + point.x /= bounds.size.width; + point.y /= bounds.size.height; + } else { + point.x *= displaymodedata->scale; + point.y *= displaymodedata->scale; + } return point; } @@ -93,25 +99,25 @@ NSEnumerator *enumerator = [touches objectEnumerator]; UITouch *touch = (UITouch*)[enumerator nextObject]; - if (touch) { - CGPoint locationInView = [touch locationInView: self]; + while (touch) { + if (!leftFingerDown) { + CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO]; - /* send moved event */ - SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y); + /* send moved event */ + SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y); - /* send mouse down event */ - SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT); - } + /* send mouse down event */ + SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT); -#ifdef FIXED_MULTITOUCH - while(touch) { - CGPoint locationInView = [self touchLocation:touch]; + leftFingerDown = (SDL_FingerID)touch; + } + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS - //FIXME: TODO: Using touch as the fingerId is potentially dangerous - //It is also much more efficient than storing the UITouch pointer - //and comparing it to the incoming event. - SDL_SendFingerDown(touchId, (long)touch, + // FIXME: TODO: Using touch as the fingerId is potentially dangerous + // It is also much more efficient than storing the UITouch pointer + // and comparing it to the incoming event. + SDL_SendFingerDown(touchId, (SDL_FingerID)touch, SDL_TRUE, locationInView.x, locationInView.y, 1); #else @@ -126,10 +132,8 @@ } } #endif - touch = (UITouch*)[enumerator nextObject]; } -#endif } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event @@ -137,15 +141,14 @@ NSEnumerator *enumerator = [touches objectEnumerator]; UITouch *touch = (UITouch*)[enumerator nextObject]; - if (touch) { - /* send mouse up */ - SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT); - } - -#ifdef FIXED_MULTITOUCH while(touch) { - CGPoint locationInView = [self touchLocation:touch]; + if ((SDL_FingerID)touch == leftFingerDown) { + /* send mouse up */ + SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT); + leftFingerDown = 0; + } + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS SDL_SendFingerDown(touchId, (long)touch, SDL_FALSE, locationInView.x, locationInView.y, @@ -162,10 +165,8 @@ } } #endif - touch = (UITouch*)[enumerator nextObject]; } -#endif } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event @@ -183,17 +184,15 @@ NSEnumerator *enumerator = [touches objectEnumerator]; UITouch *touch = (UITouch*)[enumerator nextObject]; - if (touch) { - CGPoint locationInView = [touch locationInView: self]; + while (touch) { + if ((SDL_FingerID)touch == leftFingerDown) { + CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO]; - /* send moved event */ - SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y); - } - -#ifdef FIXED_MULTITOUCH - while(touch) { - CGPoint locationInView = [self touchLocation:touch]; + /* send moved event */ + SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y); + } + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS SDL_SendTouchMotion(touchId, (long)touch, SDL_FALSE, locationInView.x, locationInView.y, @@ -209,10 +208,8 @@ } } #endif - touch = (UITouch*)[enumerator nextObject]; } -#endif } /* @@ -316,7 +313,7 @@ { SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN); SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RETURN); - [self hideKeyboard]; + SDL_StopTextInput(); return YES; } @@ -344,29 +341,28 @@ static SDL_uikitview * getWindowView(SDL_Window * window) return view; } -int SDL_iPhoneKeyboardShow(SDL_Window * window) +SDL_bool UIKit_HasScreenKeyboardSupport(_THIS) { - SDL_uikitview *view = getWindowView(window); - if (view == nil) { - return -1; - } - - [view showKeyboard]; - return 0; + return SDL_TRUE; } -int SDL_iPhoneKeyboardHide(SDL_Window * window) +void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window) { SDL_uikitview *view = getWindowView(window); - if (view == nil) { - return -1; + if (view != nil) { + [view showKeyboard]; } - - [view hideKeyboard]; - return 0; } -SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window) +void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_uikitview *view = getWindowView(window); + if (view != nil) { + [view hideKeyboard]; + } +} + +SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window) { SDL_uikitview *view = getWindowView(window); if (view == nil) { @@ -376,49 +372,6 @@ SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window) return view.keyboardVisible; } -int SDL_iPhoneKeyboardToggle(SDL_Window * window) -{ - SDL_uikitview *view = getWindowView(window); - if (view == nil) { - return -1; - } - - if (SDL_iPhoneKeyboardIsShown(window)) { - SDL_iPhoneKeyboardHide(window); - } - else { - SDL_iPhoneKeyboardShow(window); - } - return 0; -} - -#else - -/* stubs, used if compiled without keyboard support */ - -int SDL_iPhoneKeyboardShow(SDL_Window * window) -{ - SDL_SetError("Not compiled with keyboard support"); - return -1; -} - -int SDL_iPhoneKeyboardHide(SDL_Window * window) -{ - SDL_SetError("Not compiled with keyboard support"); - return -1; -} - -SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window) -{ - return 0; -} - -int SDL_iPhoneKeyboardToggle(SDL_Window * window) -{ - SDL_SetError("Not compiled with keyboard support"); - return -1; -} - #endif /* SDL_IPHONE_KEYBOARD */ #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.h old mode 100755 new mode 100644 index d5551ed81..2c4ea7efe --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.h @@ -31,8 +31,9 @@ @property (readwrite) SDL_Window *window; - (id)initWithSDLWindow:(SDL_Window *)_window; -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient; - (void)loadView; -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation; +- (void)viewDidLayoutSubviews; +- (NSUInteger)supportedInterfaceOrientations; +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient; @end diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.m old mode 100755 new mode 100644 index 7b452ed3b..3b8cb6565 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitviewcontroller.m @@ -28,9 +28,11 @@ #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" -#include "SDL_uikitwindow.h" #include "SDL_uikitviewcontroller.h" #include "SDL_uikitvideo.h" +#include "SDL_uikitmodes.h" +#include "SDL_uikitwindow.h" + @implementation SDL_uikitviewcontroller @@ -43,112 +45,82 @@ return nil; } self.window = _window; + return self; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient -{ - const char *orientationsCString; - if ((orientationsCString = SDL_GetHint(SDL_HINT_ORIENTATIONS)) != NULL) { - BOOL rotate = NO; - NSString *orientationsNSString = [NSString stringWithCString:orientationsCString - encoding:NSUTF8StringEncoding]; - NSArray *orientations = [orientationsNSString componentsSeparatedByCharactersInSet: - [NSCharacterSet characterSetWithCharactersInString:@" "]]; - - switch (orient) { - case UIInterfaceOrientationLandscapeLeft: - rotate = [orientations containsObject:@"LandscapeLeft"]; - break; - - case UIInterfaceOrientationLandscapeRight: - rotate = [orientations containsObject:@"LandscapeRight"]; - break; - - case UIInterfaceOrientationPortrait: - rotate = [orientations containsObject:@"Portrait"]; - break; - - case UIInterfaceOrientationPortraitUpsideDown: - rotate = [orientations containsObject:@"PortraitUpsideDown"]; - break; - - default: break; - } - - return rotate; - } - - if (self->window->flags & SDL_WINDOW_RESIZABLE) { - return YES; // any orientation is okay. - } - - // If not resizable, allow device to orient to other matching sizes - // (that is, let the user turn the device upside down...same screen - // dimensions, but it lets the user place the device where it's most - // comfortable in relation to its physical buttons, headphone jack, etc). - switch (orient) { - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - return (self->window->w >= self->window->h); - - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - return (self->window->h >= self->window->w); - - default: break; - } - - return NO; // Nothing else is acceptable. -} - - (void)loadView { // do nothing. } -// Send a resized event when the orientation changes. -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +- (void)viewDidLayoutSubviews { - const UIInterfaceOrientation toInterfaceOrientation = [self interfaceOrientation]; - SDL_WindowData *data = self->window->driverdata; - UIWindow *uiwindow = data->uiwindow; - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window); - SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; - SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata; - UIScreen *uiscreen = displaydata->uiscreen; - const int noborder = (self->window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)); - CGRect frame = noborder ? [uiscreen bounds] : [uiscreen applicationFrame]; - const CGSize size = frame.size; - int w, h; - - switch (toInterfaceOrientation) { - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - w = (size.width < size.height) ? size.width : size.height; - h = (size.width > size.height) ? size.width : size.height; - break; - - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - w = (size.width > size.height) ? size.width : size.height; - h = (size.width < size.height) ? size.width : size.height; - break; - - default: - SDL_assert(0 && "Unexpected interface orientation!"); - return; + if (self->window->flags & SDL_WINDOW_RESIZABLE) { + SDL_WindowData *data = self->window->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window); + SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata; + const CGSize size = data->view.bounds.size; + int w, h; + + w = (int)(size.width * displaymodedata->scale); + h = (int)(size.height * displaymodedata->scale); + + SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h); } - - w = (int)(w * displaymodedata->scale); - h = (int)(h * displaymodedata->scale); - - [uiwindow setFrame:frame]; - [data->view setFrame:frame]; - [data->view updateFrame]; - SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h); } +- (NSUInteger)supportedInterfaceOrientations +{ + NSUInteger orientationMask = 0; + + const char *orientationsCString; + if ((orientationsCString = SDL_GetHint(SDL_HINT_ORIENTATIONS)) != NULL) { + BOOL rotate = NO; + NSString *orientationsNSString = [NSString stringWithCString:orientationsCString + encoding:NSUTF8StringEncoding]; + NSArray *orientations = [orientationsNSString componentsSeparatedByCharactersInSet: + [NSCharacterSet characterSetWithCharactersInString:@" "]]; + + if ([orientations containsObject:@"LandscapeLeft"]) { + orientationMask |= UIInterfaceOrientationMaskLandscapeLeft; + } + if ([orientations containsObject:@"LandscapeRight"]) { + orientationMask |= UIInterfaceOrientationMaskLandscapeRight; + } + if ([orientations containsObject:@"Portrait"]) { + orientationMask |= UIInterfaceOrientationMaskPortrait; + } + if ([orientations containsObject:@"PortraitUpsideDown"]) { + orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown; + } + + } else if (self->window->flags & SDL_WINDOW_RESIZABLE) { + orientationMask = UIInterfaceOrientationMaskAll; // any orientation is okay. + } else { + if (self->window->w >= self->window->h) { + orientationMask |= UIInterfaceOrientationMaskLandscape; + } + if (self->window->h >= self->window->w) { + orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown); + } + } + + // Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown; + } + return orientationMask; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient +{ + NSUInteger orientationMask = [self supportedInterfaceOrientations]; + return (orientationMask & (1 << orient)); +} + +@end + #endif /* SDL_VIDEO_DRIVER_UIKIT */ -@end +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.h b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.h old mode 100755 new mode 100644 index 99f6ed20e..925443453 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.h +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.h @@ -29,6 +29,9 @@ typedef struct SDL_WindowData SDL_WindowData; extern int UIKit_CreateWindow(_THIS, SDL_Window * window); +extern void UIKit_ShowWindow(_THIS, SDL_Window * window); +extern void UIKit_HideWindow(_THIS, SDL_Window * window); +extern void UIKit_RaiseWindow(_THIS, SDL_Window * window); extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern void UIKit_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, diff --git a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.m b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.m old mode 100755 new mode 100644 index 60037b518..ec0beda01 --- a/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.m +++ b/src/eepp/helper/SDL2/src/video/uikit/SDL_uikitwindow.m @@ -33,6 +33,7 @@ #include "SDL_uikitvideo.h" #include "SDL_uikitevents.h" +#include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" #import "SDL_uikitappdelegate.h" @@ -65,70 +66,58 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo window->x = 0; window->y = 0; - /* Get frame dimensions in pixels */ - int width = (int)(uiwindow.frame.size.width * displaymodedata->scale); - int height = (int)(uiwindow.frame.size.height * displaymodedata->scale); - - /* We can pick either width or height here and we'll rotate the - screen to match, so we pick the closest to what we wanted. - */ - if (window->w >= window->h) { - if (uiwindow.frame.size.width > uiwindow.frame.size.height) { - window->w = width; - window->h = height; - } else { - window->w = height; - window->h = width; - } + CGRect bounds; + if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) { + bounds = [displaydata->uiscreen bounds]; } else { - if (uiwindow.frame.size.width > uiwindow.frame.size.height) { - window->w = height; - window->h = width; - } else { - window->w = width; - window->h = height; - } + bounds = [displaydata->uiscreen applicationFrame]; } + + /* Get frame dimensions in pixels */ + int width = (int)(bounds.size.width * displaymodedata->scale); + int height = (int)(bounds.size.height * displaymodedata->scale); + + // Make sure the width/height are oriented correctly + if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) { + int temp = width; + width = height; + height = temp; + } + + window->w = width; + window->h = height; } window->driverdata = data; /* only one window on iOS, always shown */ window->flags &= ~SDL_WINDOW_HIDDEN; - window->flags |= SDL_WINDOW_SHOWN; // SDL_WINDOW_BORDERLESS controls whether status bar is hidden. // This is only set if the window is on the main screen. Other screens // just force the window to have the borderless flag. - if ([UIScreen mainScreen] != displaydata->uiscreen) { + if (displaydata->uiscreen == [UIScreen mainScreen]) { + window->flags |= SDL_WINDOW_INPUT_FOCUS; // always has input focus + + if ([UIApplication sharedApplication].statusBarHidden) { + window->flags |= SDL_WINDOW_BORDERLESS; + } else { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } + } else { window->flags &= ~SDL_WINDOW_RESIZABLE; // window is NEVER resizeable window->flags &= ~SDL_WINDOW_INPUT_FOCUS; // never has input focus window->flags |= SDL_WINDOW_BORDERLESS; // never has a status bar. - } else { - window->flags |= SDL_WINDOW_INPUT_FOCUS; // always has input focus - - if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) { - [UIApplication sharedApplication].statusBarHidden = YES; - } else { - [UIApplication sharedApplication].statusBarHidden = NO; - } - - //const UIDeviceOrientation o = [[UIDevice currentDevice] orientation]; - //const BOOL landscape = (o == UIDeviceOrientationLandscapeLeft) || - // (o == UIDeviceOrientationLandscapeRight); - //const BOOL rotate = ( ((window->w > window->h) && (!landscape)) || - // ((window->w < window->h) && (landscape)) ); - - // The View Controller will handle rotating the view when the - // device orientation changes. This will trigger resize events, if - // appropriate. - SDL_uikitviewcontroller *controller; - controller = [SDL_uikitviewcontroller alloc]; - data->viewcontroller = [controller initWithSDLWindow:window]; - [data->viewcontroller setTitle:@"SDL App"]; // !!! FIXME: hook up SDL_SetWindowTitle() - // !!! FIXME: if (rotate), force a "resize" right at the start } + // The View Controller will handle rotating the view when the + // device orientation changes. This will trigger resize events, if + // appropriate. + SDL_uikitviewcontroller *controller; + controller = [SDL_uikitviewcontroller alloc]; + data->viewcontroller = [controller initWithSDLWindow:window]; + [data->viewcontroller setTitle:@"SDL App"]; // !!! FIXME: hook up SDL_SetWindowTitle() + return 0; } @@ -148,13 +137,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) return -1; } - // Non-mainscreen windows must be force to borderless, as there's no - // status bar there, and we want to get the right dimensions later in - // this function. - if (external) { - window->flags |= SDL_WINDOW_BORDERLESS; - } - // If monitor has a resolution of 0x0 (hasn't been explicitly set by the // user, so it's in standby), try to force the display to a resolution // that most closely matches the desired window size. @@ -184,14 +166,31 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) } } } + + if (data->uiscreen == [UIScreen mainScreen]) { + if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) { + [UIApplication sharedApplication].statusBarHidden = YES; + } else { + [UIApplication sharedApplication].statusBarHidden = NO; + } + } + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + if (window->w > window->h) { + if (!UIKit_IsDisplayLandscape(data->uiscreen)) { + [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]; + } + } else if (window->w < window->h) { + if (UIKit_IsDisplayLandscape(data->uiscreen)) { + [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; + } + } + } /* ignore the size user requested, and make a fullscreen window */ // !!! FIXME: can we have a smaller view? UIWindow *uiwindow = [UIWindow alloc]; - if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) - uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]]; - else - uiwindow = [uiwindow initWithFrame:[data->uiscreen applicationFrame]]; + uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]]; // put the window on an external display if appropriate. This implicitly // does [uiwindow setframe:[uiscreen bounds]], so don't do it on the @@ -210,6 +209,32 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) } +void +UIKit_ShowWindow(_THIS, SDL_Window * window) +{ + UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; + + [uiwindow makeKeyAndVisible]; +} + +void +UIKit_HideWindow(_THIS, SDL_Window * window) +{ + UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; + + uiwindow.hidden = YES; +} + +void +UIKit_RaiseWindow(_THIS, SDL_Window * window) +{ + // We don't currently offer a concept of "raising" the SDL window, since + // we only allow one per display, in the iOS fashion. + // However, we use this entry point to rebind the context to the view + // during OnWindowRestored processing. + _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx); +} + void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { @@ -219,21 +244,26 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display if (fullscreen) { [UIApplication sharedApplication].statusBarHidden = YES; - uiwindow.frame = [displaydata->uiscreen bounds]; } else { [UIApplication sharedApplication].statusBarHidden = NO; - uiwindow.frame = [displaydata->uiscreen applicationFrame]; + } + + CGRect bounds; + if (fullscreen) { + bounds = [displaydata->uiscreen bounds]; + } else { + bounds = [displaydata->uiscreen applicationFrame]; } /* Get frame dimensions in pixels */ - int width = (int)(uiwindow.frame.size.width * displaymodedata->scale); - int height = (int)(uiwindow.frame.size.height * displaymodedata->scale); + int width = (int)(bounds.size.width * displaymodedata->scale); + int height = (int)(bounds.size.height * displaymodedata->scale); /* We can pick either width or height here and we'll rotate the screen to match, so we pick the closest to what we wanted. */ if (window->w >= window->h) { - if (uiwindow.frame.size.width > uiwindow.frame.size.height) { + if (width > height) { window->w = width; window->h = height; } else { @@ -241,7 +271,7 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display window->h = width; } } else { - if (uiwindow.frame.size.width > uiwindow.frame.size.height) { + if (width > height) { window->w = height; window->h = width; } else { @@ -279,6 +309,20 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) } } +int +SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam) +{ + SDL_WindowData *data = window ? (SDL_WindowData *)window->driverdata : NULL; + + if (!data || !data->view) { + SDL_SetError("Invalid window or view not set"); + return -1; + } + + [data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam]; + return 0; +} + #endif /* SDL_VIDEO_DRIVER_UIKIT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/uikit/keyinfotable.h b/src/eepp/helper/SDL2/src/video/uikit/keyinfotable.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_vkeys.h b/src/eepp/helper/SDL2/src/video/windows/SDL_vkeys.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsclipboard.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsclipboard.c old mode 100755 new mode 100644 index f3b6c6ec7..dcd7de80f --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsclipboard.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsclipboard.c @@ -92,11 +92,7 @@ WIN_SetClipboardText(_THIS, const char *text) 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); @@ -150,13 +146,7 @@ WIN_HasClipboardText(_THIS) void WIN_CheckClipboardUpdate(struct SDL_VideoData * data) { - DWORD count; - -#ifdef _WIN32_WCE - count = 0; -#else - count = GetClipboardSequenceNumber(); -#endif + const DWORD count = GetClipboardSequenceNumber(); if (count != data->clipboard_count) { if (data->clipboard_count) { SDL_SendClipboardUpdate(); diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsclipboard.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsclipboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsevents.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsevents.c old mode 100755 new mode 100644 index d844fba20..0193062e2 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsevents.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsevents.c @@ -29,6 +29,10 @@ #include "../../events/SDL_events_c.h" #include "../../events/SDL_touch_c.h" +/* Dropfile support */ +#include + + /*#define WMMSG_DEBUG*/ @@ -164,15 +168,31 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 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); } + + if(SDL_GetMouse()->relative_mode) { + LONG cx, cy; + RECT rect; + GetWindowRect(hwnd, &rect); + + cx = (rect.left + rect.right) / 2; + cy = (rect.top + rect.bottom) / 2; + + /* Make an absurdly small clip rect */ + rect.left = cx-1; + rect.right = cx+1; + rect.top = cy-1; + rect.bottom = cy+1; + + ClipCursor(&rect); + } + /* * FIXME: Update keyboard state */ @@ -191,23 +211,30 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_MOUSEMOVE: -#ifdef _WIN32_WCE - /* transform coords for VGA, WVGA... */ - { - SDL_VideoData *videodata = data->videodata; - if(videodata->CoordTransform) { - 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 + if(SDL_GetMouse()->relative_mode) + break; SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam)); break; + case WM_INPUT: + { + HRAWINPUT hRawInput = (HRAWINPUT)lParam; + RAWINPUT inp; + UINT size = sizeof(inp); + GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER)); + + /* Mouse data */ + if(inp.header.dwType == RIM_TYPEMOUSE) + { + RAWMOUSE* mouse = &inp.data.mouse; + + if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) + SDL_SendMouseMotion(data->window, 1, (int)mouse->lLastX, (int)mouse->lLastY); + + } + break; + } + case WM_LBUTTONDOWN: SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT); break; @@ -399,16 +426,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) RECT size; int x, y; int w, h; + int min_w, min_h; int style; BOOL menu; /* If we allow resizing, let the resize happen naturally */ - if(SDL_IsShapedWindow(data->window)) + 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); @@ -417,37 +441,44 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Calculate current size of our window */ SDL_GetWindowSize(data->window, &w, &h); + SDL_GetWindowMinimumSize(data->window, &min_w, &min_h); + + /* Store in min_w and min_h difference between current size and minimal + size so we don't need to call AdjustWindowRectEx twice */ + min_w -= w; + min_h -= 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; + if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) { + info->ptMinTrackSize.x = w + min_w; + info->ptMinTrackSize.y = h + min_h; + } else { + 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; @@ -600,7 +631,29 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return 0; } break; - } + + case WM_DROPFILES: + { + UINT i; + HDROP drop = (HDROP) wParam; + UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0); + for (i = 0; i < count; ++i) { + UINT size = DragQueryFile(drop, i, NULL, 0) + 1; + LPTSTR buffer = SDL_stack_alloc(TCHAR, size); + if (buffer) { + if (DragQueryFile(drop, i, buffer, size)) { + char *file = WIN_StringToUTF8(buffer); + SDL_SendDropFile(file); + SDL_free(file); + } + SDL_stack_free(buffer); + } + } + DragFinish(drop); + return 0; + } + break; + } /* If there's a window proc, assume it's going to handle messages */ if (data->wndproc) { diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsevents.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsevents.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsframebuffer.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsframebuffer.c old mode 100755 new mode 100644 index cf28add64..5efab7662 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsframebuffer.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsframebuffer.c @@ -24,18 +24,12 @@ #include "SDL_windowsvideo.h" -#ifndef _WIN32_WCE -#define HAVE_GETDIBITS -#endif - int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; size_t size; LPBITMAPINFO info; -#ifdef HAVE_GETDIBITS HBITMAP hbm; -#endif /* Free the old framebuffer surface */ if (data->mdc) { @@ -49,7 +43,6 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, voi size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD); info = (LPBITMAPINFO)SDL_stack_alloc(Uint8, size); -#ifdef HAVE_GETDIBITS SDL_memset(info, 0, size); info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -69,7 +62,6 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, voi *format = SDL_MasksToPixelFormatEnum(bpp, masks[0], masks[1], masks[2], 0); } if (*format == SDL_PIXELFORMAT_UNKNOWN) -#endif { /* We'll use RGB format for now */ *format = SDL_PIXELFORMAT_RGB888; diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsframebuffer.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsframebuffer.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowskeyboard.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowskeyboard.c old mode 100755 new mode 100644 index 3530faf35..182741bdd --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowskeyboard.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowskeyboard.c @@ -22,10 +22,6 @@ #if SDL_VIDEO_DRIVER_WINDOWS -#ifdef _WIN32_WCE -#define SDL_DISABLE_WINDOWS_IME -#endif - #include "SDL_windowsvideo.h" #include "../../events/SDL_keyboard_c.h" @@ -572,20 +568,20 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData) DWORD dwVer = pVerFixedInfo->dwFileVersionMS; dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16; - if (videodata->GetReadingString || - dwLang == LANG_CHT && ( + 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)) + dwVer == MAKEIMEVERSION(6, 0))) || - dwLang == LANG_CHS && ( + ((dwLang == LANG_CHS) && ( dwVer == MAKEIMEVERSION(4, 1) || dwVer == MAKEIMEVERSION(4, 2) || - dwVer == MAKEIMEVERSION(5, 3))) { + dwVer == MAKEIMEVERSION(5, 3)))) { dwRet[0] = dwVer | dwLang; dwRet[1] = pVerFixedInfo->dwFileVersionLS; SDL_free(lpVerBuffer); @@ -1050,7 +1046,6 @@ STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BO 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); @@ -1133,7 +1128,7 @@ STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) 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}; + static const 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)) diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowskeyboard.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowskeyboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmodes.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmodes.c old mode 100755 new mode 100644 index 0f1083f6a..9e844aa43 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmodes.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmodes.c @@ -34,9 +34,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) { SDL_DisplayModeData *data; DEVMODE devmode; -#ifndef _WIN32_WCE HDC hdc; -#endif devmode.dmSize = sizeof(devmode); devmode.dmDriverExtra = 0; @@ -59,17 +57,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) 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)]; @@ -105,9 +93,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) } else if (bmi->bmiHeader.biBitCount == 4) { mode->format = SDL_PIXELFORMAT_INDEX4LSB; } - } else -#endif /* _WIN32_WCE */ - { + } else { /* FIXME: Can we tell what this will be? */ if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { switch (devmode.dmBitsPerPel) { @@ -233,18 +219,11 @@ WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) { SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->current_mode.driverdata; -#ifdef _WIN32_WCE - // WINCE: DEVMODE.dmPosition not found, or may be mingw32ce bug - rect->x = 0; - rect->y = 0; - rect->w = _this->windows->w; - rect->h = _this->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; } @@ -278,14 +257,6 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) 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); diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmodes.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmodes.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmouse.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmouse.c old mode 100755 new mode 100644 index 73103c4c7..3b3b95f85 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmouse.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmouse.c @@ -102,6 +102,45 @@ WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) return cursor; } +static SDL_Cursor * +WIN_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor; + LPCTSTR name; + + switch(id) + { + default: + SDL_assert(0); + return NULL; + case SDL_SYSTEM_CURSOR_ARROW: name = IDC_ARROW; break; + case SDL_SYSTEM_CURSOR_IBEAM: name = IDC_IBEAM; break; + case SDL_SYSTEM_CURSOR_WAIT: name = IDC_WAIT; break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: name = IDC_CROSS; break; + case SDL_SYSTEM_CURSOR_WAITARROW: name = IDC_WAIT; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: name = IDC_SIZENWSE; break; + case SDL_SYSTEM_CURSOR_SIZENESW: name = IDC_SIZENESW; break; + case SDL_SYSTEM_CURSOR_SIZEWE: name = IDC_SIZEWE; break; + case SDL_SYSTEM_CURSOR_SIZENS: name = IDC_SIZENS; break; + case SDL_SYSTEM_CURSOR_SIZEALL: name = IDC_SIZEALL; break; + case SDL_SYSTEM_CURSOR_NO: name = IDC_NO; break; + case SDL_SYSTEM_CURSOR_HAND: name = IDC_HAND; break; + } + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + HICON hicon; + + hicon = LoadCursor(NULL, name); + + cursor->driverdata = hicon; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + static void WIN_FreeCursor(SDL_Cursor * cursor) { @@ -140,8 +179,48 @@ WIN_WarpMouse(SDL_Window * window, int x, int y) static int WIN_SetRelativeMouseMode(SDL_bool enabled) { - SDL_Unsupported(); - return -1; + RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */ + HWND hWnd; + hWnd = GetActiveWindow(); + + rawMouse.hwndTarget = hWnd; + if(!enabled) { + rawMouse.dwFlags |= RIDEV_REMOVE; + rawMouse.hwndTarget = NULL; + } + + + /* (Un)register raw input for mice */ + if(RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) { + + /* Only return an error when registering. If we unregister and fail, then + it's probably that we unregistered twice. That's OK. */ + if(enabled) { + SDL_Unsupported(); + return -1; + } + } + + if(enabled) { + LONG cx, cy; + RECT rect; + GetWindowRect(hWnd, &rect); + + cx = (rect.left + rect.right) / 2; + cy = (rect.top + rect.bottom) / 2; + + /* Make an absurdly small clip rect */ + rect.left = cx-1; + rect.right = cx+1; + rect.top = cy-1; + rect.bottom = cy+1; + + ClipCursor(&rect); + } + else + ClipCursor(NULL); + + return 0; } void @@ -150,6 +229,7 @@ WIN_InitMouse(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); mouse->CreateCursor = WIN_CreateCursor; + mouse->CreateSystemCursor = WIN_CreateSystemCursor; mouse->ShowCursor = WIN_ShowCursor; mouse->FreeCursor = WIN_FreeCursor; mouse->WarpMouse = WIN_WarpMouse; diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmouse.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsmouse.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.c old mode 100755 new mode 100644 index 5674d903b..f6029f6e5 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.c @@ -36,7 +36,7 @@ #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_FLAGS_ARB 0x2094 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 @@ -61,6 +61,11 @@ #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #endif +#ifndef WGL_EXT_create_context_es_profile +#define WGL_EXT_create_context_es_profile +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#endif + typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, @@ -112,10 +117,8 @@ WIN_GL_LoadLibrary(_THIS, const char *path) 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"); + _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC)) + GetProcAddress(handle, "wglShareLists"); if (!_this->gl_data->wglGetProcAddress || !_this->gl_data->wglCreateContext || @@ -341,7 +344,7 @@ WIN_GL_InitExtensions(_THIS, HDC hdc) } /* Check for WGL_ARB_pixel_format */ - _this->gl_data->WGL_ARB_pixel_format = 0; + _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE; if (HasExtension("WGL_ARB_pixel_format", extensions)) { _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *) (HDC, const int *, @@ -354,16 +357,20 @@ WIN_GL_InitExtensions(_THIS, HDC hdc) if ((_this->gl_data->wglChoosePixelFormatARB != NULL) && (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) { - _this->gl_data->WGL_ARB_pixel_format = 1; + _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE; } } /* Check for WGL_EXT_swap_control */ + _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE; 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"); + if (HasExtension("WGL_EXT_swap_control_tear", extensions)) { + _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE; + } } else { _this->gl_data->wglSwapIntervalEXT = NULL; _this->gl_data->wglGetSwapIntervalEXT = NULL; @@ -397,7 +404,7 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) WIN_GL_InitExtensions(_this, hdc); - if (_this->gl_data->WGL_ARB_pixel_format) { + if (_this->gl_data->HAS_WGL_ARB_pixel_format) { _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pixel_format, &matching); @@ -519,10 +526,22 @@ SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window) { HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; - HGLRC context; + HGLRC context, share_context; - if (_this->gl_config.major_version < 3) { + if (_this->gl_config.share_with_current_context) { + share_context = (HGLRC)(_this->current_glctx); + } else { + share_context = 0; + } + + if (_this->gl_config.major_version < 3 && + _this->gl_config.profile_mask == 0 && + _this->gl_config.flags == 0) { + /* Create legacy context */ context = _this->gl_data->wglCreateContext(hdc); + if( share_context != 0 ) { + _this->gl_data->wglShareLists(share_context, context); + } } else { PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; HGLRC temp_context = _this->gl_data->wglCreateContext(hdc); @@ -567,7 +586,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) attribs[iattr++] = 0; /* Create the GL 3.x context */ - context = wglCreateContextAttribsARB(hdc, 0, attribs); + context = wglCreateContextAttribsARB(hdc, share_context, attribs); /* Delete the GL 2.x context */ _this->gl_data->wglDeleteContext(temp_context); } @@ -594,6 +613,11 @@ WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) HDC hdc; int status; + if (!_this->gl_data) { + SDL_SetError("OpenGL not initialized"); + return -1; + } + if (window) { hdc = ((SDL_WindowData *) window->driverdata)->hdc; } else { @@ -611,24 +635,29 @@ WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) int WIN_GL_SetSwapInterval(_THIS, int interval) { - if (_this->gl_data->wglSwapIntervalEXT) { - _this->gl_data->wglSwapIntervalEXT(interval); - return 0; + int retval = -1; + if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) { + SDL_SetError("Negative swap interval unsupported in this GL"); + } else if (_this->gl_data->wglSwapIntervalEXT) { + if (_this->gl_data->wglSwapIntervalEXT(interval) == TRUE) { + retval = 0; + } else { + WIN_SetError("wglSwapIntervalEXT()"); + } } else { SDL_Unsupported(); - return -1; } + return retval; } int WIN_GL_GetSwapInterval(_THIS) { + int retval = 0; if (_this->gl_data->wglGetSwapIntervalEXT) { - return _this->gl_data->wglGetSwapIntervalEXT(); - } else { - SDL_Unsupported(); - return -1; + retval = _this->gl_data->wglGetSwapIntervalEXT(); } + return retval; } void @@ -642,6 +671,9 @@ WIN_GL_SwapWindow(_THIS, SDL_Window * window) void WIN_GL_DeleteContext(_THIS, SDL_GLContext context) { + if (!_this->gl_data) { + return; + } _this->gl_data->wglDeleteContext((HGLRC) context); } diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.h old mode 100755 new mode 100644 index 4a63915cd..31b25ec3c --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.h +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsopengl.h @@ -27,12 +27,14 @@ struct SDL_GLDriverData { - int WGL_ARB_pixel_format; + SDL_bool HAS_WGL_ARB_pixel_format; + SDL_bool HAS_WGL_EXT_swap_control_tear; 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 * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2); BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc, const int *piAttribIList, const FLOAT * pfAttribFList, @@ -44,7 +46,7 @@ struct SDL_GLDriverData UINT nAttributes, const int *piAttributes, int *piValues); - void (WINAPI * wglSwapIntervalEXT) (int interval); + BOOL (WINAPI * wglSwapIntervalEXT) (int interval); int (WINAPI * wglGetSwapIntervalEXT) (void); }; diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsshape.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsshape.c old mode 100755 new mode 100644 index 10e0a75a7..f49ff8057 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsshape.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsshape.c @@ -65,11 +65,14 @@ Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShape SDL_ShapeData *data; HRGN mask_region = NULL; - if (shaper == NULL || shape == NULL) + if( (shaper == NULL) || + (shape == NULL) || + ((shape->format->Amask == 0) && (shape_mode->mode != ShapeModeColorKey)) || + (shape->w != shaper->window->w) || + (shape->h != shaper->window->h) ) { 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); diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsshape.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsshape.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.c old mode 100755 new mode 100644 index 73227efc5..b044e6d2a --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.c @@ -51,11 +51,6 @@ WIN_DeleteDevice(SDL_VideoDevice * device) SDL_VideoData *data = (SDL_VideoData *) device->driverdata; SDL_UnregisterApp(); -#ifdef _WIN32_WCE - if(data->hAygShell) { - SDL_UnloadObject(data->hAygShell); - } -#endif if (data->userDLL) { SDL_UnloadObject(data->userDLL); } @@ -88,15 +83,6 @@ WIN_CreateDevice(int devindex) } device->driverdata = data; -#ifdef _WIN32_WCE - data->hAygShell = SDL_LoadObject("\\windows\\aygshell.dll"); - if(0 == data->hAygShell) - data->hAygShell = SDL_LoadObject("aygshell.dll"); - data->SHFullScreen = (0 != data->hAygShell ? - (PFNSHFullScreen) SDL_LoadFunction(data->hAygShell, "SHFullScreen") : 0); - data->CoordTransform = NULL; -#endif - data->userDLL = SDL_LoadObject("USER32.DLL"); if (data->userDLL) { data->CloseTouchInputHandle = (BOOL (WINAPI *)( HTOUCHINPUT )) SDL_LoadFunction(data->userDLL, "CloseTouchInputHandle"); @@ -125,6 +111,7 @@ WIN_CreateDevice(int devindex) device->MaximizeWindow = WIN_MaximizeWindow; device->MinimizeWindow = WIN_MinimizeWindow; device->RestoreWindow = WIN_RestoreWindow; + device->SetWindowBordered = WIN_SetWindowBordered; device->SetWindowFullscreen = WIN_SetWindowFullscreen; device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.h old mode 100755 new mode 100644 index 23dbc8553..2be2d2563 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.h +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowsvideo.h @@ -27,7 +27,7 @@ #include "../../core/windows/SDL_windows.h" -#if defined(_MSC_VER) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) #include #else #include "SDL_msctf.h" @@ -115,12 +115,6 @@ typedef struct SDL_VideoData { int render; -#ifdef _WIN32_WCE - void* hAygShell; - PFNSHFullScreen SHFullScreen; - PFCoordTransform CoordTransform; -#endif - const SDL_Scancode *key_layout; DWORD clipboard_count; diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.c b/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.c old mode 100755 new mode 100644 index aa9ec220d..bb6a786a9 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.c +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.c @@ -29,6 +29,9 @@ #include "SDL_windowsvideo.h" #include "SDL_windowswindow.h" +/* Dropfile support */ +#include + /* This is included after SDL_windowsvideo.h, which includes windows.h */ #include "SDL_syswm.h" @@ -74,7 +77,6 @@ static int SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_WindowData *data; /* Allocate the window data */ @@ -186,6 +188,9 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM)); } + /* Enable dropping files */ + DragAcceptFiles(hwnd, TRUE); + /* All done! */ return 0; } @@ -193,7 +198,6 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) int WIN_CreateWindow(_THIS, SDL_Window * window) { - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); HWND hwnd; RECT rect; DWORD style = STYLE_BASIC; @@ -326,10 +330,7 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) } 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); @@ -341,10 +342,9 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon); } -void -WIN_SetWindowPosition(_THIS, SDL_Window * window) +static void +WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags) { - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; RECT rect; DWORD style; @@ -364,103 +364,40 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window) 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); x = window->x + rect.left; y = window->y + rect.top; - SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE)); + SetWindowPos(hwnd, top, x, y, w, h, flags); +} + +void +WIN_SetWindowPosition(_THIS, SDL_Window * window) +{ + WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE); } 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)); + WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE); } -#ifdef _WIN32_WCE -void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible) -{ - SDL_WindowData* windowdata = (SDL_WindowData*) window->driverdata; - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - - 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); - } else { - 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); - - } - } -} -#endif /* _WIN32_WCE */ - 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 @@ -481,13 +418,6 @@ 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); } @@ -495,14 +425,25 @@ 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_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + + if (bordered) { + style &= ~STYLE_BORDERLESS; + style |= STYLE_NORMAL; + } else { + style &= ~STYLE_NORMAL; + style |= STYLE_BORDERLESS; + } + + SetWindowLong(hwnd, GWL_STYLE, style); + SetWindowPos(hwnd, hwnd, window->x, window->y, window->w, window->h, SWP_FRAMECHANGED | SWP_NOREPOSITION | SWP_NOZORDER |SWP_NOACTIVATE | SWP_NOSENDCHANGING); } void @@ -547,11 +488,7 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, rect.top = 0; rect.right = window->windowed.w; rect.bottom = window->windowed.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); @@ -565,10 +502,6 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) { -#ifdef _WIN32_WCE - SDL_Unsupported(); - return -1; -#else SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; HDC hdc; @@ -583,16 +516,11 @@ WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) DeleteDC(hdc); } return succeeded ? 0 : -1; -#endif } int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { -#ifdef _WIN32_WCE - SDL_Unsupported(); - return -1; -#else SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; HDC hdc; @@ -607,16 +535,14 @@ WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) DeleteDC(hdc); } return succeeded ? 0 : -1; -#endif } void -WIN_SetWindowGrab(_THIS, SDL_Window * window) +WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && - (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + if (grabbed) { RECT rect; GetClientRect(hwnd, &rect); ClientToScreen(hwnd, (LPPOINT) & rect); @@ -633,9 +559,6 @@ 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); @@ -679,7 +602,6 @@ SDL_HelperWindowCreate(void) { HINSTANCE hInstance = GetModuleHandle(NULL); WNDCLASS wce; - HWND hWndParent = NULL; /* Make sure window isn't created twice. */ if (SDL_HelperWindow != NULL) { @@ -699,17 +621,12 @@ SDL_HelperWindowCreate(void) 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, + CW_USEDEFAULT, HWND_MESSAGE, NULL, hInstance, NULL); if (SDL_HelperWindow == NULL) { UnregisterClass(SDL_HelperWindowClassName, hInstance); diff --git a/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.h b/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.h old mode 100755 new mode 100644 index a6514470c..542f6ea65 --- a/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.h +++ b/src/eepp/helper/SDL2/src/video/windows/SDL_windowswindow.h @@ -23,15 +23,6 @@ #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; @@ -57,10 +48,11 @@ 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_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void WIN_SetWindowGrab(_THIS, SDL_Window * window); +extern void WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void WIN_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11clipboard.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11clipboard.c old mode 100755 new mode 100644 index 60d6bd859..765dfa209 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11clipboard.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11clipboard.c @@ -54,6 +54,7 @@ X11_SetClipboardText(_THIS, const char *text) Display *display = ((SDL_VideoData *) _this->driverdata)->display; Atom format; Window window; + Atom XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0); /* Get the SDL window that will own the selection */ window = GetWindow(_this); @@ -68,6 +69,11 @@ X11_SetClipboardText(_THIS, const char *text) XA_CUT_BUFFER0, format, 8, PropModeReplace, (const unsigned char *)text, SDL_strlen(text)); + if (XA_CLIPBOARD != None && + XGetSelectionOwner(display, XA_CLIPBOARD) != window) { + XSetSelectionOwner(display, XA_CLIPBOARD, window, CurrentTime); + } + if (XGetSelectionOwner(display, XA_PRIMARY) != window) { XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime); } @@ -89,13 +95,18 @@ X11_GetClipboardText(_THIS) unsigned long overflow; unsigned char *src; char *text; + Atom XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0); + if (XA_CLIPBOARD == None) { + SDL_SetError("Couldn't access X clipboard"); + return NULL; + } text = NULL; /* Get the window that holds the selection */ window = GetWindow(_this); format = TEXT_FORMAT; - owner = XGetSelectionOwner(display, XA_PRIMARY); + owner = XGetSelectionOwner(display, XA_CLIPBOARD); if ((owner == None) || (owner == window)) { owner = DefaultRootWindow(display); selection = XA_CUT_BUFFER0; @@ -103,7 +114,7 @@ X11_GetClipboardText(_THIS) /* Request that the selection owner copy the data to our window */ owner = window; selection = XInternAtom(display, "SDL_SELECTION", False); - XConvertSelection(display, XA_PRIMARY, format, selection, owner, + XConvertSelection(display, XA_CLIPBOARD, format, selection, owner, CurrentTime); /* FIXME: Should we have a timeout here? */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11clipboard.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11clipboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11dyn.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11dyn.c old mode 100755 new mode 100644 index 2ec9b7d9c..25b654d83 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11dyn.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11dyn.c @@ -77,35 +77,38 @@ static x11dynlib x11libs[] = { {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE} }; -static void -X11_GetSym(const char *fnname, int *rc, void **fn) +static void * +X11_GetSym(const char *fnname, int *pHasModule) { int i; + void *fn = NULL; for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { if (x11libs[i].lib != NULL) { - *fn = SDL_LoadFunction(x11libs[i].lib, fnname); - if (*fn != NULL) + fn = SDL_LoadFunction(x11libs[i].lib, fnname); + if (fn != NULL) break; } } #if DEBUG_DYNAMIC_X11 - if (*fn != NULL) - printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, - *fn); + if (fn != NULL) + printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, fn); else printf("X11: Symbol '%s' NOT FOUND!\n", fnname); #endif - if (*fn == NULL) - *rc = 0; /* kill this module. */ + if (fn == NULL) + *pHasModule = 0; /* kill this module. */ + + return fn; } /* Define all the function pointers and wrappers... */ #define SDL_X11_MODULE(modname) #define SDL_X11_SYM(rc,fn,params,args,ret) \ - static rc (*p##fn) params = NULL; \ + typedef rc (*SDL_DYNX11FN_##fn) params; \ + static SDL_DYNX11FN_##fn p##fn = NULL; \ rc fn params { ret p##fn args ; } #include "SDL_x11sym.h" #undef SDL_X11_MODULE @@ -114,8 +117,10 @@ X11_GetSym(const char *fnname, int *rc, void **fn) /* Annoying varargs entry point... */ #ifdef X_HAVE_UTF8_STRING -XIC(*pXCreateIC) (XIM,...) = NULL; -char *(*pXGetICValues) (XIC, ...) = NULL; +typedef XIC(*SDL_DYNX11FN_XCreateIC) (XIM,...); +SDL_DYNX11FN_XCreateIC pXCreateIC = NULL; +typedef char *(*SDL_DYNX11FN_XGetICValues) (XIC, ...); +SDL_DYNX11FN_XGetICValues pXGetICValues = NULL; #endif /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ @@ -184,15 +189,16 @@ SDL_X11_LoadSymbols(void) #undef SDL_X11_SYM #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname; -#define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn); +#define SDL_X11_SYM(a,fn,x,y,z) p##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod); #include "SDL_x11sym.h" #undef SDL_X11_MODULE #undef SDL_X11_SYM #ifdef X_HAVE_UTF8_STRING - X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC); - X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8, - (void **) &pXGetICValues); + pXCreateIC = (SDL_DYNX11FN_XCreateIC) + X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8); + pXGetICValues = (SDL_DYNX11FN_XGetICValues) + X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8); #endif if (SDL_X11_HAVE_BASEXLIB) { diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11dyn.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11dyn.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11events.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11events.c old mode 100755 new mode 100644 index a85622d2a..480bb3149 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11events.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11events.c @@ -28,6 +28,7 @@ #include #include /* For INT_MAX */ +#include "SDL_x11video.h" #include "SDL_x11video.h" #include "SDL_x11touch.h" #include "SDL_x11xinput2.h" @@ -46,6 +47,8 @@ #include #endif +/*#define DEBUG_XEVENTS*/ + /* Check to see if this is a repeated key. (idea shamelessly lifted from GII -- thanks guys! :) */ @@ -107,6 +110,47 @@ static void X11_HandleGenericEvent(SDL_VideoData *videodata,XEvent event) #endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */ +static void +X11_DispatchFocusIn(SDL_WindowData *data) +{ +#ifdef DEBUG_XEVENTS + printf("window %p: Dispatching FocusIn\n", data); +#endif + SDL_SetKeyboardFocus(data->window); +#ifdef X_HAVE_UTF8_STRING + if (data->ic) { + XSetICFocus(data->ic); + } +#endif +} + +static void +X11_DispatchFocusOut(SDL_WindowData *data) +{ +#ifdef DEBUG_XEVENTS + printf("window %p: Dispatching FocusOut\n", data); +#endif + SDL_SetKeyboardFocus(NULL); +#ifdef X_HAVE_UTF8_STRING + if (data->ic) { + XUnsetICFocus(data->ic); + } +#endif +} + +static void +X11_DispatchMapNotify(SDL_WindowData *data) +{ + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); +} + +static void +X11_DispatchUnmapNotify(SDL_WindowData *data) +{ + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); +} static void X11_DispatchEvent(_THIS) @@ -147,6 +191,11 @@ X11_DispatchEvent(_THIS) } #endif +#if 0 + printf("type = %d display = %d window = %d\n", + xevent.type, xevent.xany.display, xevent.xany.window); +#endif + data = NULL; if (videodata && videodata->windowlist) { for (i = 0; i < videodata->numwindows; ++i) { @@ -161,16 +210,12 @@ X11_DispatchEvent(_THIS) return; } -#if 0 - printf("type = %d display = %d window = %d\n", - xevent.type, xevent.xany.display, xevent.xany.window); -#endif switch (xevent.type) { /* Gaining mouse coverage? */ case EnterNotify:{ #ifdef DEBUG_XEVENTS - printf("EnterNotify! (%d,%d,%d)\n", + printf("window %p: EnterNotify! (%d,%d,%d)\n", data, xevent.xcrossing.x, xevent.xcrossing.y, xevent.xcrossing.mode); @@ -185,7 +230,7 @@ X11_DispatchEvent(_THIS) /* Losing mouse coverage? */ case LeaveNotify:{ #ifdef DEBUG_XEVENTS - printf("LeaveNotify! (%d,%d,%d)\n", + printf("window %p: LeaveNotify! (%d,%d,%d)\n", data, xevent.xcrossing.x, xevent.xcrossing.y, xevent.xcrossing.mode); @@ -204,36 +249,48 @@ X11_DispatchEvent(_THIS) /* Gaining input focus? */ case FocusIn:{ + if (xevent.xfocus.detail == NotifyInferior) { #ifdef DEBUG_XEVENTS - printf("FocusIn!\n"); + printf("window %p: FocusIn (NotifierInferior, ignoring)\n", data); #endif - SDL_SetKeyboardFocus(data->window); -#ifdef X_HAVE_UTF8_STRING - if (data->ic) { - XSetICFocus(data->ic); + break; } +#ifdef DEBUG_XEVENTS + printf("window %p: FocusIn!\n", data); #endif + if (data->pending_focus == PENDING_FOCUS_OUT && + data->window == SDL_GetKeyboardFocus()) { + /* We want to reset the keyboard here, because we may have + missed keyboard messages after our previous FocusOut. + */ + SDL_ResetKeyboard(); + } + data->pending_focus = PENDING_FOCUS_IN; + data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_IN_TIME; } break; /* Losing input focus? */ case FocusOut:{ + if (xevent.xfocus.detail == NotifyInferior) { + /* We still have focus if a child gets focus */ #ifdef DEBUG_XEVENTS - printf("FocusOut!\n"); + printf("window %p: FocusOut (NotifierInferior, ignoring)\n", data); #endif - SDL_SetKeyboardFocus(NULL); -#ifdef X_HAVE_UTF8_STRING - if (data->ic) { - XUnsetICFocus(data->ic); + break; } +#ifdef DEBUG_XEVENTS + printf("window %p: FocusOut!\n", data); #endif + data->pending_focus = PENDING_FOCUS_OUT; + data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_OUT_TIME; } break; /* Generated upon EnterWindow and FocusIn */ case KeymapNotify:{ #ifdef DEBUG_XEVENTS - printf("KeymapNotify!\n"); + printf("window %p: KeymapNotify!\n", data); #endif /* FIXME: X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector); @@ -244,7 +301,7 @@ X11_DispatchEvent(_THIS) /* Has the keyboard layout changed? */ case MappingNotify:{ #ifdef DEBUG_XEVENTS - printf("MappingNotify!\n"); + printf("window %p: MappingNotify!\n", data); #endif X11_UpdateKeymap(_this); } @@ -258,7 +315,7 @@ X11_DispatchEvent(_THIS) Status status = 0; #ifdef DEBUG_XEVENTS - printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); + printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode); #endif SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); #if 1 @@ -297,7 +354,7 @@ X11_DispatchEvent(_THIS) KeyCode keycode = xevent.xkey.keycode; #ifdef DEBUG_XEVENTS - printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); + printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode); #endif if (X11_KeyRepeat(display, &xevent)) { /* We're about to get a repeated key down, ignore the key up */ @@ -310,43 +367,67 @@ X11_DispatchEvent(_THIS) /* Have we been iconified? */ case UnmapNotify:{ #ifdef DEBUG_XEVENTS - printf("UnmapNotify!\n"); + printf("window %p: UnmapNotify!\n", data); #endif - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); + X11_DispatchUnmapNotify(data); } break; /* Have we been restored? */ case MapNotify:{ #ifdef DEBUG_XEVENTS - printf("MapNotify!\n"); + printf("window %p: MapNotify!\n", data); #endif - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); + X11_DispatchMapNotify(data); } break; /* Have we been resized or moved? */ case ConfigureNotify:{ #ifdef DEBUG_XEVENTS - printf("ConfigureNotify! (resize: %dx%d)\n", + printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data, + xevent.xconfigure.x, xevent.xconfigure.y, xevent.xconfigure.width, xevent.xconfigure.height); #endif - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, - xevent.xconfigure.x, xevent.xconfigure.y); - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, - xevent.xconfigure.width, - xevent.xconfigure.height); + if (xevent.xconfigure.x != data->last_xconfigure.x || + xevent.xconfigure.y != data->last_xconfigure.y) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, + xevent.xconfigure.x, xevent.xconfigure.y); + } + if (xevent.xconfigure.width != data->last_xconfigure.width || + xevent.xconfigure.height != data->last_xconfigure.height) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, + xevent.xconfigure.width, + xevent.xconfigure.height); + } + data->last_xconfigure = xevent.xconfigure; } break; /* Have we been requested to quit (or another client message?) */ case ClientMessage:{ - if ((xevent.xclient.format == 32) && + if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent.xclient.format == 32) && + (xevent.xclient.data.l[0] == videodata->_NET_WM_PING)) { + Window root = DefaultRootWindow(display); + +#ifdef DEBUG_XEVENTS + printf("window %p: _NET_WM_PING\n", data); +#endif + xevent.xclient.window = root; + XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent); + break; + } + + else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent.xclient.format == 32) && (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) { +#ifdef DEBUG_XEVENTS + printf("window %p: WM_DELETE_WINDOW\n", data); +#endif SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + break; } } break; @@ -354,7 +435,7 @@ X11_DispatchEvent(_THIS) /* Do we need to refresh ourselves? */ case Expose:{ #ifdef DEBUG_XEVENTS - printf("Expose (count = %d)\n", xevent.xexpose.count); + printf("window %p: Expose (count = %d)\n", data, xevent.xexpose.count); #endif SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } @@ -364,7 +445,7 @@ X11_DispatchEvent(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); if(!mouse->relative_mode) { #ifdef DEBUG_MOTION - printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y); + printf("window %p: X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y); #endif SDL_SendMouseMotion(data->window, 0, xevent.xmotion.x, xevent.xmotion.y); @@ -397,7 +478,7 @@ X11_DispatchEvent(_THIS) char *name = XGetAtomName(display, xevent.xproperty.atom); if (name) { - printf("PropertyNotify: %s %s\n", name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed"); + printf("window %p: PropertyNotify: %s %s\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed"); XFree(name); } @@ -460,7 +541,26 @@ X11_DispatchEvent(_THIS) } } } -#endif + if (status == Success) { + XFree(propdata); + } +#endif /* DEBUG_XEVENTS */ + + if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) { + /* Get the new state from the window manager. + Compositing window managers can alter visibility of windows + without ever mapping / unmapping them, so we handle that here, + because they use the NETWM protocol to notify us of changes. + */ + Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window); + if ((flags^data->window->flags) & SDL_WINDOW_HIDDEN) { + if (flags & SDL_WINDOW_HIDDEN) { + X11_DispatchUnmapNotify(data); + } else { + X11_DispatchMapNotify(data); + } + } + } } break; @@ -475,7 +575,7 @@ X11_DispatchEvent(_THIS) req = &xevent.xselectionrequest; #ifdef DEBUG_XEVENTS - printf("SelectionRequest (requestor = %ld, target = %ld)\n", + printf("window %p: SelectionRequest (requestor = %ld, target = %ld)\n", data, req->requestor, req->target); #endif @@ -505,7 +605,7 @@ X11_DispatchEvent(_THIS) case SelectionNotify: { #ifdef DEBUG_XEVENTS - printf("SelectionNotify (requestor = %ld, target = %ld)\n", + printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data, xevent.xselection.requestor, xevent.xselection.target); #endif videodata->selection_waiting = SDL_FALSE; @@ -514,13 +614,36 @@ X11_DispatchEvent(_THIS) default:{ #ifdef DEBUG_XEVENTS - printf("Unhandled event %d\n", xevent.type); + printf("window %p: Unhandled event %d\n", data, xevent.type); #endif } break; } } +static void +X11_HandleFocusChanges(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + int i; + + if (videodata && videodata->windowlist) { + for (i = 0; i < videodata->numwindows; ++i) { + SDL_WindowData *data = videodata->windowlist[i]; + if (data && data->pending_focus != PENDING_FOCUS_NONE) { + Uint32 now = SDL_GetTicks(); + if ( (int)(data->pending_focus_time-now) <= 0 ) { + if ( data->pending_focus == PENDING_FOCUS_IN ) { + X11_DispatchFocusIn(data); + } else { + X11_DispatchFocusOut(data); + } + data->pending_focus = PENDING_FOCUS_NONE; + } + } + } + } +} /* Ack! XPending() actually performs a blocking read if no events available */ static int X11_Pending(Display * display) @@ -573,8 +696,12 @@ X11_PumpEvents(_THIS) while (X11_Pending(data->display)) { X11_DispatchEvent(_this); } + + /* FIXME: Only need to do this when there are pending focus changes */ + X11_HandleFocusChanges(_this); + /*Dont process evtouch events if XInput2 multitouch is supported*/ - if(X11_Xinput2IsMutitouchSupported()) { + if(X11_Xinput2IsMultitouchSupported()) { return; } diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11events.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11events.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11framebuffer.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11framebuffer.c old mode 100755 new mode 100644 index 9eb015e34..ca8ef33e4 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11framebuffer.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11framebuffer.c @@ -154,33 +154,68 @@ X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; int i; - SDL_Rect *rect; - + int x, y, w ,h; #ifndef NO_SHARED_MEMORY if (data->use_mitshm) { for (i = 0; i < numrects; ++i) { - rect = &rects[i]; + x = rects[i].x; + y = rects[i].y; + w = rects[i].w; + h = rects[i].h; - if (rect->w == 0 || rect->h == 0) { /* Clipped? */ + if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) { + /* Clipped? */ continue; } + if (x < 0) + { + x += w; + w += rects[i].x; + } + if (y < 0) + { + y += h; + h += rects[i].y; + } + if (x + w > window->w) + w = window->w - x; + if (y + h > window->h) + h = window->h - y; + XShmPutImage(display, data->xwindow, data->gc, data->ximage, - rect->x, rect->y, - rect->x, rect->y, rect->w, rect->h, False); + x, y, x, y, w, h, False); } } else #endif /* !NO_SHARED_MEMORY */ { for (i = 0; i < numrects; ++i) { - rect = &rects[i]; + x = rects[i].x; + y = rects[i].y; + w = rects[i].w; + h = rects[i].h; - if (rect->w == 0 || rect->h == 0) { /* Clipped? */ + if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) { + /* Clipped? */ continue; } + if (x < 0) + { + x += w; + w += rects[i].x; + } + if (y < 0) + { + y += h; + h += rects[i].y; + } + if (x + w > window->w) + w = window->w - x; + if (y + h > window->h) + h = window->h - y; + XPutImage(display, data->xwindow, data->gc, data->ximage, - rect->x, rect->y, - rect->x, rect->y, rect->w, rect->h); + x, y, x, y, w, h); } } diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11framebuffer.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11framebuffer.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11keyboard.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11keyboard.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11keyboard.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11keyboard.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.c old mode 100755 new mode 100644 index 2560004b1..a752d5f2a --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.c @@ -22,10 +22,22 @@ #if SDL_VIDEO_DRIVER_X11 +#include "SDL_hints.h" #include "SDL_x11video.h" /*#define X11MODES_DEBUG*/ +/* I'm becoming more and more convinced that the application should never + * use XRandR, and it's the window manager's responsibility to track and + * manage display modes for fullscreen windows. Right now XRandR is completely + * broken with respect to window manager behavior on every window manager that + * I can find. For example, on Unity 3D if you show a fullscreen window while + * the resolution is changing (within ~250 ms) your window will retain the + * fullscreen state hint but be decorated and windowed. +*/ +#define XRANDR_DISABLED_BY_DEFAULT + + static int get_visualinfo(Display * display, int screen, XVisualInfo * vinfo) { @@ -132,67 +144,6 @@ X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo) return SDL_PIXELFORMAT_UNKNOWN; } -int -X11_InitModes(_THIS) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - int screen; - - for (screen = 0; screen < ScreenCount(data->display); ++screen) { - XVisualInfo vinfo; - SDL_VideoDisplay display; - SDL_DisplayData *displaydata; - SDL_DisplayMode mode; - XPixmapFormatValues *pixmapFormats; - int i, n; - - if (get_visualinfo(data->display, screen, &vinfo) < 0) { - continue; - } - - mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo); - if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) { - /* We don't support palettized modes now */ - continue; - } - mode.w = DisplayWidth(data->display, screen); - mode.h = DisplayHeight(data->display, screen); - mode.refresh_rate = 0; - mode.driverdata = NULL; - - displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); - if (!displaydata) { - continue; - } - displaydata->screen = screen; - displaydata->visual = vinfo.visual; - displaydata->depth = vinfo.depth; - - displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8; - pixmapFormats = XListPixmapFormats(data->display, &n); - if (pixmapFormats) { - for (i = 0; i < n; ++i) { - if (pixmapFormats[i].depth == displaydata->depth) { - displaydata->scanline_pad = pixmapFormats[i].scanline_pad; - break; - } - } - XFree(pixmapFormats); - } - - SDL_zero(display); - display.desktop_mode = mode; - display.current_mode = mode; - display.driverdata = displaydata; - SDL_AddVideoDisplay(&display); - } - if (_this->num_displays == 0) { - SDL_SetError("No available displays"); - return -1; - } - return 0; -} - /* Global for the error handler */ int vm_event, vm_error = -1; @@ -208,12 +159,18 @@ CheckXinerama(Display * display, int *major, int *minor) *major = *minor = 0; /* Allow environment override */ - env = getenv("SDL_VIDEO_X11_XINERAMA"); + env = SDL_GetHint(SDL_HINT_VIDEO_X11_XINERAMA); if (env && !SDL_atoi(env)) { +#ifdef X11MODES_DEBUG + printf("Xinerama disabled due to hint\n"); +#endif return SDL_FALSE; } if (!SDL_X11_HAVE_XINERAMA) { +#ifdef X11MODES_DEBUG + printf("Xinerama support not available\n"); +#endif return SDL_FALSE; } @@ -221,8 +178,14 @@ CheckXinerama(Display * display, int *major, int *minor) if (!XineramaQueryExtension(display, &event_base, &error_base) || !XineramaQueryVersion(display, major, minor) || !XineramaIsActive(display)) { +#ifdef X11MODES_DEBUG + printf("Xinerama not active on the display\n"); +#endif return SDL_FALSE; } +#ifdef X11MODES_DEBUG + printf("Xinerama available at version %d.%d!\n", *major, *minor); +#endif return SDL_TRUE; } #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ @@ -237,21 +200,87 @@ CheckXRandR(Display * display, int *major, int *minor) *major = *minor = 0; /* Allow environment override */ - env = getenv("SDL_VIDEO_X11_XRANDR"); - if (env && !SDL_atoi(env)) { + env = SDL_GetHint(SDL_HINT_VIDEO_X11_XRANDR); +#ifdef XRANDR_DISABLED_BY_DEFAULT + if (!env || !SDL_atoi(env)) { +#ifdef X11MODES_DEBUG + printf("XRandR disabled by default due to window manager issues\n"); +#endif return SDL_FALSE; } +#else + if (env && !SDL_atoi(env)) { +#ifdef X11MODES_DEBUG + printf("XRandR disabled due to hint\n"); +#endif + return SDL_FALSE; + } +#endif /* XRANDR_ENABLED_BY_DEFAULT */ if (!SDL_X11_HAVE_XRANDR) { +#ifdef X11MODES_DEBUG + printf("XRandR support not available\n"); +#endif return SDL_FALSE; } /* Query the extension version */ if (!XRRQueryVersion(display, major, minor)) { +#ifdef X11MODES_DEBUG + printf("XRandR not active on the display\n"); +#endif return SDL_FALSE; } +#ifdef X11MODES_DEBUG + printf("XRandR available at version %d.%d!\n", *major, *minor); +#endif return SDL_TRUE; } + +#define XRANDR_ROTATION_LEFT (1 << 1) +#define XRANDR_ROTATION_RIGHT (1 << 3) + +static int +CalculateXRandRRefreshRate(const XRRModeInfo *info) +{ + return (info->hTotal + && info->vTotal) ? (info->dotClock / (info->hTotal * info->vTotal)) : 0; +} + +static SDL_bool +SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *output_info, + RRMode modeID, SDL_DisplayMode *mode) +{ + int i; + for (i = 0; i < res->nmode; ++i) { + if (res->modes[i].id == modeID) { + XRRCrtcInfo *crtc; + Rotation rotation = 0; + const XRRModeInfo *info = &res->modes[i]; + + crtc = XRRGetCrtcInfo(display, res, output_info->crtc); + if (crtc) { + rotation = crtc->rotation; + XRRFreeCrtcInfo(crtc); + } + + if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) { + mode->w = info->height; + mode->h = info->width; + } else { + mode->w = info->width; + mode->h = info->height; + } + mode->refresh_rate = CalculateXRandRRefreshRate(info); + ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID; +#ifdef X11MODES_DEBUG + printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate); +#endif + return SDL_TRUE; + } + } + return SDL_FALSE; +} #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ #if SDL_VIDEO_DRIVER_X11_XVIDMODE @@ -264,12 +293,18 @@ CheckVidMode(Display * display, int *major, int *minor) *major = *minor = 0; /* Allow environment override */ - env = getenv("SDL_VIDEO_X11_XVIDMODE"); + env = SDL_GetHint(SDL_HINT_VIDEO_X11_XVIDMODE); if (env && !SDL_atoi(env)) { +#ifdef X11MODES_DEBUG + printf("XVidMode disabled due to hint\n"); +#endif return SDL_FALSE; } if (!SDL_X11_HAVE_XVIDMODE) { +#ifdef X11MODES_DEBUG + printf("XVidMode support not available\n"); +#endif return SDL_FALSE; } @@ -277,8 +312,14 @@ CheckVidMode(Display * display, int *major, int *minor) vm_error = -1; if (!XF86VidModeQueryExtension(display, &vm_event, &vm_error) || !XF86VidModeQueryVersion(display, major, minor)) { +#ifdef X11MODES_DEBUG + printf("XVidMode not active on the display\n"); +#endif return SDL_FALSE; } +#ifdef X11MODES_DEBUG + printf("XVidMode available at version %d.%d!\n", *major, *minor); +#endif return SDL_TRUE; } @@ -309,67 +350,269 @@ Bool XF86VidModeGetModeInfo(Display * dpy, int scr, } static int -calculate_rate(XF86VidModeModeInfo * info) +CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info) { return (info->htotal && info->vtotal) ? (1000 * info->dotclock / (info->htotal * info->vtotal)) : 0; } -static void -save_mode(Display * display, SDL_DisplayData * data) +SDL_bool +SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode) { - XF86VidModeGetModeInfo(display, data->screen, - &data->saved_mode); - XF86VidModeGetViewPort(display, data->screen, - &data->saved_view.x, - &data->saved_view.y); + mode->w = info->hdisplay; + mode->h = info->vdisplay; + mode->refresh_rate = CalculateXVidModeRefreshRate(info); + ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info; + return SDL_TRUE; } +#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ -/* -static void -restore_mode(Display * display, SDL_DisplayData * data) +int +X11_InitModes(_THIS) { - XF86VidModeModeInfo mode; + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + int screen, screencount; +#if SDL_VIDEO_DRIVER_X11_XINERAMA + int xinerama_major, xinerama_minor; + int use_xinerama = 0; + XineramaScreenInfo *xinerama = NULL; +#endif +#if SDL_VIDEO_DRIVER_X11_XRANDR + int xrandr_major, xrandr_minor; + int use_xrandr = 0; + XRRScreenResources *res = NULL; +#endif +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + int vm_major, vm_minor; + int use_vidmode = 0; +#endif - if (XF86VidModeGetModeInfo(display, data->screen, &mode)) { - if (SDL_memcmp(&mode, &data->saved_mode, sizeof(mode)) != 0) { - XF86VidModeSwitchToMode(display, data->screen, &data->saved_mode); +#if SDL_VIDEO_DRIVER_X11_XINERAMA + /* Query Xinerama extention + * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012) + * or newer of the Nvidia binary drivers + */ + if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) { + xinerama = XineramaQueryScreens(data->display, &screencount); + if (xinerama) { + use_xinerama = xinerama_major * 100 + xinerama_minor; } } - if ((data->saved_view.x != 0) || (data->saved_view.y != 0)) { - XF86VidModeSetViewPort(display, data->screen, - data->saved_view.x, - data->saved_view.y); + if (!xinerama) { + screencount = ScreenCount(data->display); + } +#else + screencount = ScreenCount(data->display); +#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ + +#if SDL_VIDEO_DRIVER_X11_XRANDR + /* require at least XRandR v1.2 */ + if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) && + (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 2))) { + use_xrandr = xrandr_major * 100 + xrandr_minor; + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + if (CheckVidMode(data->display, &vm_major, &vm_minor)) { + use_vidmode = vm_major * 100 + vm_minor; } -} -*/ #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ + for (screen = 0; screen < screencount; ++screen) { + XVisualInfo vinfo; + SDL_VideoDisplay display; + SDL_DisplayData *displaydata; + SDL_DisplayMode mode; + SDL_DisplayModeData *modedata; + XPixmapFormatValues *pixmapFormats; + int i, n; + +#if SDL_VIDEO_DRIVER_X11_XINERAMA + if (xinerama) { + if (get_visualinfo(data->display, 0, &vinfo) < 0) { + continue; + } + } else { + if (get_visualinfo(data->display, screen, &vinfo) < 0) { + continue; + } + } +#else + if (get_visualinfo(data->display, screen, &vinfo) < 0) { + continue; + } +#endif + + displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + continue; + } + + mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo); + if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) { + /* We don't support palettized modes now */ + SDL_free(displaydata); + continue; + } +#if SDL_VIDEO_DRIVER_X11_XINERAMA + if (xinerama) { + mode.w = xinerama[screen].width; + mode.h = xinerama[screen].height; + } else { + mode.w = DisplayWidth(data->display, screen); + mode.h = DisplayHeight(data->display, screen); + } +#else + mode.w = DisplayWidth(data->display, screen); + mode.h = DisplayHeight(data->display, screen); +#endif + mode.refresh_rate = 0; + + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + SDL_free(displaydata); + continue; + } + mode.driverdata = modedata; + +#if SDL_VIDEO_DRIVER_X11_XINERAMA + /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active, + * there's only one screen available. So we force the screen number to zero and + * let Xinerama specific code handle specific functionality using displaydata->xinerama_info + */ + if (use_xinerama) { + displaydata->screen = 0; + displaydata->use_xinerama = use_xinerama; + displaydata->xinerama_info = xinerama[screen]; + displaydata->xinerama_screen = screen; + } + else displaydata->screen = screen; +#else + displaydata->screen = screen; +#endif + displaydata->visual = vinfo.visual; + displaydata->depth = vinfo.depth; + + displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8; + pixmapFormats = XListPixmapFormats(data->display, &n); + if (pixmapFormats) { + for (i = 0; i < n; ++i) { + if (pixmapFormats[i].depth == displaydata->depth) { + displaydata->scanline_pad = pixmapFormats[i].scanline_pad; + break; + } + } + XFree(pixmapFormats); + } + +#if SDL_VIDEO_DRIVER_X11_XINERAMA + if (use_xinerama) { + displaydata->x = xinerama[screen].x_org; + displaydata->y = xinerama[screen].y_org; + } + else +#endif + { + displaydata->x = 0; + displaydata->y = 0; + } + +#if SDL_VIDEO_DRIVER_X11_XRANDR + if (use_xrandr) { + res = XRRGetScreenResources(data->display, RootWindow(data->display, displaydata->screen)); + } + if (res) { + XRROutputInfo *output_info; + XRRCrtcInfo *crtc; + int output; + + for (output = 0; output < res->noutput; output++) { + output_info = XRRGetOutputInfo(data->display, res, res->outputs[output]); + if (!output_info || !output_info->crtc || + output_info->connection == RR_Disconnected) { + XRRFreeOutputInfo(output_info); + continue; + } + + /* Is this the output that corresponds to the current screen? + We're checking the crtc position, but that may not be a valid test + in all cases. Anybody want to give this some love? + */ + crtc = XRRGetCrtcInfo(data->display, res, output_info->crtc); + if (!crtc || crtc->x != displaydata->x || crtc->y != displaydata->y) { + XRRFreeOutputInfo(output_info); + XRRFreeCrtcInfo(crtc); + continue; + } + + displaydata->use_xrandr = use_xrandr; + displaydata->xrandr_output = res->outputs[output]; + SetXRandRModeInfo(data->display, res, output_info, crtc->mode, &mode); + + XRRFreeOutputInfo(output_info); + XRRFreeCrtcInfo(crtc); + break; + } +#ifdef X11MODES_DEBUG + if (output == res->noutput) { + printf("Couldn't find XRandR CRTC at %d,%d\n", displaydata->x, displaydata->y); + } +#endif + XRRFreeScreenResources(res); + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + if (!displaydata->use_xrandr && +#if SDL_VIDEO_DRIVER_X11_XINERAMA + /* XVidMode only works on the screen at the origin */ + (!displaydata->use_xinerama || + (displaydata->x == 0 && displaydata->y == 0)) && +#endif + use_vidmode) { + displaydata->use_vidmode = use_vidmode; + if (displaydata->use_xinerama) { + displaydata->vidmode_screen = 0; + } else { + displaydata->vidmode_screen = screen; + } + XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode); + } +#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ + + SDL_zero(display); + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + SDL_AddVideoDisplay(&display); + } + +#if SDL_VIDEO_DRIVER_X11_XINERAMA + if (xinerama) XFree(xinerama); +#endif + + if (_this->num_displays == 0) { + SDL_SetError("No available displays"); + return -1; + } + return 0; +} + void X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; -#if SDL_VIDEO_DRIVER_X11_XINERAMA - int xinerama_major, xinerama_minor; - int screens; - XineramaScreenInfo * xinerama; -#endif -#if SDL_VIDEO_DRIVER_X11_XRANDR - int xrandr_major, xrandr_minor; - int nsizes, nrates; - XRRScreenSize *sizes; - short *rates; -#endif #if SDL_VIDEO_DRIVER_X11_XVIDMODE - int vm_major, vm_minor; int nmodes; XF86VidModeModeInfo ** modes; #endif int screen_w; int screen_h; SDL_DisplayMode mode; + SDL_DisplayModeData *modedata; /* Unfortunately X11 requires the window to be created with the correct * visual and depth ahead of time, but the SDL API allows you to create @@ -380,328 +623,101 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) mode.format = sdl_display->current_mode.format; mode.driverdata = NULL; - data->use_xinerama = 0; - data->use_xrandr = 0; - data->use_vidmode = 0; screen_w = DisplayWidth(display, data->screen); screen_h = DisplayHeight(display, data->screen); #if SDL_VIDEO_DRIVER_X11_XINERAMA - /* Query Xinerama extention */ - if (CheckXinerama(display, &xinerama_major, &xinerama_minor)) { -#ifdef X11MODES_DEBUG - printf("X11 detected Xinerama:\n"); -#endif - xinerama = XineramaQueryScreens(display, &screens); - if (xinerama) { - int i; - for (i = 0; i < screens; i++) { -#ifdef X11MODES_DEBUG - printf("xinerama %d: %dx%d+%d+%d\n", - xinerama[i].screen_number, - xinerama[i].width, xinerama[i].height, - xinerama[i].x_org, xinerama[i].y_org); -#endif - if (xinerama[i].screen_number == data->screen) { - data->use_xinerama = - xinerama_major * 100 + xinerama_minor; - data->xinerama_info = xinerama[i]; - } - } - XFree(xinerama); - } - - if (data->use_xinerama) { - /* Add the full xinerama mode */ - if (screen_w > data->xinerama_info.width || - screen_h > data->xinerama_info.height) { - mode.w = screen_w; - mode.h = screen_h; - mode.refresh_rate = 0; - SDL_AddDisplayMode(sdl_display, &mode); - } - - /* Add the head xinerama mode */ - mode.w = data->xinerama_info.width; - mode.h = data->xinerama_info.height; + if (data->use_xinerama) { + /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0 */ + if (!data->xinerama_info.x_org && !data->xinerama_info.y_org && + (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) { + mode.w = screen_w; + mode.h = screen_h; mode.refresh_rate = 0; + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (modedata) { + *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; + } + mode.driverdata = modedata; SDL_AddDisplayMode(sdl_display, &mode); } } #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ #if SDL_VIDEO_DRIVER_X11_XRANDR - /* XRandR */ - /* require at least XRandR v1.0 (arbitrary) */ - if (CheckXRandR(display, &xrandr_major, &xrandr_minor) - && xrandr_major >= 1) { -#ifdef X11MODES_DEBUG - fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n", - xrandr_major, xrandr_minor); -#endif + if (data->use_xrandr) { + XRRScreenResources *res; - /* save the screen configuration since we must reference it - each time we toggle modes. - */ - data->screen_config = - XRRGetScreenInfo(display, RootWindow(display, data->screen)); + res = XRRGetScreenResources (display, RootWindow(display, data->screen)); + if (res) { + SDL_DisplayModeData *modedata; + XRROutputInfo *output_info; + int i; - /* retrieve the list of resolution */ - sizes = XRRConfigSizes(data->screen_config, &nsizes); - if (nsizes > 0) { - int i, j; - for (i = 0; i < nsizes; i++) { - mode.w = sizes[i].width; - mode.h = sizes[i].height; + output_info = XRRGetOutputInfo(display, res, data->xrandr_output); + if (output_info && output_info->connection != RR_Disconnected) { + for (i = 0; i < output_info->nmode; ++i) { + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + continue; + } + mode.driverdata = modedata; - rates = XRRConfigRates(data->screen_config, i, &nrates); - for (j = 0; j < nrates; ++j) { - mode.refresh_rate = rates[j]; -#ifdef X11MODES_DEBUG - fprintf(stderr, - "XRANDR: mode = %4d[%d], w = %4d, h = %4d, rate = %4d\n", - i, j, mode.w, mode.h, mode.refresh_rate); -#endif - SDL_AddDisplayMode(sdl_display, &mode); + if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) { + SDL_AddDisplayMode(sdl_display, &mode); + } else { + SDL_free(modedata); + } } } - - data->use_xrandr = xrandr_major * 100 + xrandr_minor; - data->saved_size = - XRRConfigCurrentConfiguration(data->screen_config, - &data->saved_rotation); - data->saved_rate = XRRConfigCurrentRate(data->screen_config); + XRRFreeOutputInfo(output_info); + XRRFreeScreenResources(res); } + return; } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ #if SDL_VIDEO_DRIVER_X11_XVIDMODE - /* XVidMode */ - if (!data->use_xrandr && -#if SDL_VIDEO_DRIVER_X11_XINERAMA - (!data->use_xinerama || data->xinerama_info.screen_number == 0) && -#endif - CheckVidMode(display, &vm_major, &vm_minor) && - XF86VidModeGetAllModeLines(display, data->screen, &nmodes, &modes)) { + if (data->use_vidmode && + XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) { int i; #ifdef X11MODES_DEBUG printf("VidMode modes: (unsorted)\n"); for (i = 0; i < nmodes; ++i) { - printf("Mode %d: %d x %d @ %d\n", i, + printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i, modes[i]->hdisplay, modes[i]->vdisplay, - calculate_rate(modes[i])); + CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags); } #endif for (i = 0; i < nmodes; ++i) { - mode.w = modes[i]->hdisplay; - mode.h = modes[i]->vdisplay; - mode.refresh_rate = calculate_rate(modes[i]); - SDL_AddDisplayMode(sdl_display, &mode); + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + continue; + } + mode.driverdata = modedata; + + if (SetXVidModeModeInfo(modes[i], &mode)) { + SDL_AddDisplayMode(sdl_display, &mode); + } else { + SDL_free(modedata); + } } XFree(modes); - - data->use_vidmode = vm_major * 100 + vm_minor; - save_mode(display, data); + return; } #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ if (!data->use_xrandr && !data->use_vidmode) { - mode.w = screen_w; - mode.h = screen_h; - mode.refresh_rate = 0; + /* Add the desktop mode */ + mode = sdl_display->desktop_mode; + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (modedata) { + *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; + } + mode.driverdata = modedata; SDL_AddDisplayMode(sdl_display, &mode); } -#ifdef X11MODES_DEBUG - if (data->use_xinerama) { - printf("Xinerama is enabled\n"); - } - - if (data->use_xrandr) { - printf("XRandR is enabled\n"); - } - - if (data->use_vidmode) { - printf("VidMode is enabled\n"); - } -#endif /* X11MODES_DEBUG */ -} - -static void -get_real_resolution(Display * display, SDL_DisplayData * data, int *w, int *h, - int *rate) -{ -#if SDL_VIDEO_DRIVER_X11_XRANDR - if (data->use_xrandr) { - int nsizes; - XRRScreenSize *sizes; - - sizes = XRRConfigSizes(data->screen_config, &nsizes); - if (nsizes > 0) { - int cur_size; - Rotation cur_rotation; - - cur_size = - XRRConfigCurrentConfiguration(data->screen_config, - &cur_rotation); - *w = sizes[cur_size].width; - *h = sizes[cur_size].height; - *rate = XRRConfigCurrentRate(data->screen_config); -#ifdef X11MODES_DEBUG - fprintf(stderr, - "XRANDR: get_real_resolution: w = %d, h = %d, rate = %d\n", - *w, *h, *rate); -#endif - return; - } - } -#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (data->use_vidmode) { - XF86VidModeModeInfo mode; - - if (XF86VidModeGetModeInfo(display, data->screen, &mode)) { - *w = mode.hdisplay; - *h = mode.vdisplay; - *rate = calculate_rate(&mode); - return; - } - } -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (data->use_xinerama) { - *w = data->xinerama_info.width; - *h = data->xinerama_info.height; - *rate = 0; - return; - } -#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ - - *w = DisplayWidth(display, data->screen); - *h = DisplayHeight(display, data->screen); - *rate = 0; -} - -static void -set_best_resolution(Display * display, SDL_DisplayData * data, int w, int h, - int rate) -{ - int real_w, real_h, real_rate; - - /* check current mode so we can avoid uneccessary mode changes */ - get_real_resolution(display, data, &real_w, &real_h, &real_rate); - if (w == real_w && h == real_h && (!rate || rate == real_rate)) { - return; - } -#if SDL_VIDEO_DRIVER_X11_XRANDR - if (data->use_xrandr) { -#ifdef X11MODES_DEBUG - fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", - w, h); -#endif - int i, nsizes, nrates; - int best; - int best_rate; - XRRScreenSize *sizes; - short *rates; - - /* find the smallest resolution that is at least as big as the user requested */ - best = -1; - sizes = XRRConfigSizes(data->screen_config, &nsizes); - for (i = 0; i < nsizes; ++i) { - if (sizes[i].width < w || sizes[i].height < h) { - continue; - } - if (sizes[i].width == w && sizes[i].height == h) { - best = i; - break; - } - if (best == -1 || - (sizes[i].width < sizes[best].width) || - (sizes[i].width == sizes[best].width - && sizes[i].height < sizes[best].height)) { - best = i; - } - } - - if (best >= 0) { - best_rate = 0; - rates = XRRConfigRates(data->screen_config, best, &nrates); - for (i = 0; i < nrates; ++i) { - if (rates[i] == rate) { - best_rate = rate; - break; - } - if (!rate) { - /* Higher is better, right? */ - if (rates[i] > best_rate) { - best_rate = rates[i]; - } - } else { - if (SDL_abs(rates[i] - rate) < SDL_abs(best_rate - rate)) { - best_rate = rates[i]; - } - } - } - XRRSetScreenConfigAndRate(display, data->screen_config, - RootWindow(display, data->screen), best, - data->saved_rotation, best_rate, - CurrentTime); - } - return; - } -#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (data->use_vidmode) { - XF86VidModeModeInfo ** modes; - int i, nmodes; - int best; - - if (XF86VidModeGetAllModeLines(display, data->screen, &nmodes, &modes)) { - best = -1; - for (i = 0; i < nmodes; ++i) { - if (modes[i]->hdisplay < w || modes[i]->vdisplay < h) { - continue; - } - if (best == -1 || - (modes[i]->hdisplay < modes[best]->hdisplay) || - (modes[i]->hdisplay == modes[best]->hdisplay - && modes[i]->vdisplay < modes[best]->vdisplay)) { - best = i; - continue; - } - if ((modes[i]->hdisplay == modes[best]->hdisplay) && - (modes[i]->vdisplay == modes[best]->vdisplay)) { - if (!rate) { - /* Higher is better, right? */ - if (calculate_rate(modes[i]) > - calculate_rate(modes[best])) { - best = i; - } - } else { - if (SDL_abs(calculate_rate(modes[i]) - rate) < - SDL_abs(calculate_rate(modes[best]) - rate)) { - best = i; - } - } - } - } - if (best >= 0) { -#ifdef X11MODES_DEBUG - printf("Best Mode %d: %d x %d @ %d\n", best, - modes[best]->hdisplay, modes[best]->vdisplay, - calculate_rate(modes[best])); -#endif - XF86VidModeSwitchToMode(display, data->screen, modes[best]); - } - XFree(modes); - } - return; - } -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ } int @@ -709,8 +725,57 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode { Display *display = ((SDL_VideoData *) _this->driverdata)->display; SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + +#if SDL_VIDEO_DRIVER_X11_XRANDR + if (data->use_xrandr) { + XRRScreenResources *res; + XRROutputInfo *output_info; + XRRCrtcInfo *crtc; + Status status; + + res = XRRGetScreenResources (display, RootWindow(display, data->screen)); + if (!res) { + SDL_SetError("Couldn't get XRandR screen resources"); + return -1; + } + + output_info = XRRGetOutputInfo(display, res, data->xrandr_output); + if (!output_info || output_info->connection == RR_Disconnected) { + SDL_SetError("Couldn't get XRandR output info"); + XRRFreeScreenResources(res); + return -1; + } + + crtc = XRRGetCrtcInfo(display, res, output_info->crtc); + if (!crtc) { + SDL_SetError("Couldn't get XRandR crtc info"); + XRRFreeOutputInfo(output_info); + XRRFreeScreenResources(res); + return -1; + } + + status = XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime, + crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation, + &data->xrandr_output, 1); + + XRRFreeCrtcInfo(crtc); + XRRFreeOutputInfo(output_info); + XRRFreeScreenResources(res); + + if (status != Success) { + SDL_SetError("XRRSetCrtcConfig failed"); + return -1; + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + if (data->use_vidmode) { + XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode); + } +#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ - set_best_resolution(display, data, mode->w, mode->h, mode->refresh_rate); return 0; } @@ -719,6 +784,31 @@ X11_QuitModes(_THIS) { } +int +X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect) +{ + Display *display = ((SDL_VideoData *) _this->driverdata)->display; + SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; + + rect->x = data->x; + rect->y = data->y; + rect->w = sdl_display->current_mode.w; + rect->h = sdl_display->current_mode.h; + +#if SDL_VIDEO_DRIVER_X11_XINERAMA + /* Get the real current bounds of the display */ + if (data->use_xinerama) { + int screencount; + XineramaScreenInfo *xinerama = XineramaQueryScreens(display, &screencount); + if (xinerama) { + rect->x = xinerama[data->xinerama_screen].x_org; + rect->y = xinerama[data->xinerama_screen].y_org; + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ + return 0; +} + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.h old mode 100755 new mode 100644 index 6943634fb..5e2d016e8 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11modes.h @@ -29,6 +29,8 @@ typedef struct Visual *visual; int depth; int scanline_pad; + int x; + int y; int use_xinerama; int use_xrandr; @@ -36,23 +38,31 @@ typedef struct #if SDL_VIDEO_DRIVER_X11_XINERAMA XineramaScreenInfo xinerama_info; + int xinerama_screen; #endif + #if SDL_VIDEO_DRIVER_X11_XRANDR - XRRScreenConfiguration *screen_config; - int saved_size; - Rotation saved_rotation; - short saved_rate; + RROutput xrandr_output; #endif + #if SDL_VIDEO_DRIVER_X11_XVIDMODE - XF86VidModeModeInfo saved_mode; - struct - { - int x, y; - } saved_view; + int vidmode_screen; #endif } SDL_DisplayData; +typedef struct +{ +#if SDL_VIDEO_DRIVER_X11_XRANDR + RRMode xrandr_mode; +#endif + +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + XF86VidModeModeInfo vm_mode; +#endif + +} SDL_DisplayModeData; + extern int X11_InitModes(_THIS); extern void X11_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int X11_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); @@ -63,6 +73,7 @@ extern int X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo); extern Uint32 X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo); +extern int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect); #endif /* _SDL_x11modes_h */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11mouse.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11mouse.c old mode 100755 new mode 100644 index d9454bd8a..40ac0c211 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11mouse.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11mouse.c @@ -22,6 +22,7 @@ #if SDL_VIDEO_DRIVER_X11 +#include #include "SDL_assert.h" #include "SDL_x11video.h" #include "SDL_x11mouse.h" @@ -218,6 +219,47 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) return cursor; } +static SDL_Cursor * +X11_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor; + unsigned int shape; + + switch(id) + { + default: + SDL_assert(0); + return NULL; + // X Font Cursors reference: + // http://tronche.com/gui/x/xlib/appendix/b/ + case SDL_SYSTEM_CURSOR_ARROW: shape = XC_arrow; break; + case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; break; + case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break; + case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break; + case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break; + case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break; + case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break; + case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break; + case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; break; + case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; break; + } + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + Cursor x11_cursor; + + x11_cursor = XCreateFontCursor(GetDisplay(), shape); + + cursor->driverdata = (void*)x11_cursor; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + static void X11_FreeCursor(SDL_Cursor * cursor) { @@ -288,6 +330,7 @@ X11_InitMouse(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); mouse->CreateCursor = X11_CreateCursor; + mouse->CreateSystemCursor = X11_CreateSystemCursor; mouse->ShowCursor = X11_ShowCursor; mouse->FreeCursor = X11_FreeCursor; mouse->WarpMouse = X11_WarpMouse; diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11mouse.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11mouse.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.c old mode 100755 new mode 100644 index 90b1e73b9..2899ac288 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.c @@ -29,6 +29,7 @@ #if SDL_VIDEO_OPENGL_GLX #include "SDL_loadso.h" +#include "SDL_x11opengles.h" #if defined(__IRIX__) /* IRIX doesn't have a GL library versioning system */ @@ -59,6 +60,12 @@ #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D #endif +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#endif + #ifndef GLX_ARB_create_context #define GLX_ARB_create_context #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 @@ -75,6 +82,7 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, Bool direct, const int *attrib_list); +#endif #ifndef GLX_ARB_create_context_profile #define GLX_ARB_create_context_profile @@ -90,18 +98,23 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, #define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 #define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 #endif -#endif #ifndef GLX_EXT_create_context_es2_profile #define GLX_EXT_create_context_es2_profile +#ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002 #endif +#endif #ifndef GLX_EXT_swap_control #define GLX_SWAP_INTERVAL_EXT 0x20F1 #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 #endif +#ifndef GLX_EXT_swap_control_tear +#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 +#endif + #define OPENGL_REQUIRES_DLOPEN #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) #include @@ -122,6 +135,31 @@ X11_GL_LoadLibrary(_THIS, const char *path) { void *handle; + if (_this->gl_data) { + SDL_SetError("OpenGL context already created"); + return -1; + } + + /* If SDL_GL_CONTEXT_EGL has been changed to 1, switch over to X11_GLES functions */ + if (_this->gl_config.use_egl == 1) { +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + _this->GL_LoadLibrary = X11_GLES_LoadLibrary; + _this->GL_GetProcAddress = X11_GLES_GetProcAddress; + _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; + _this->GL_CreateContext = X11_GLES_CreateContext; + _this->GL_MakeCurrent = X11_GLES_MakeCurrent; + _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; + _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; + _this->GL_SwapWindow = X11_GLES_SwapWindow; + _this->GL_DeleteContext = X11_GLES_DeleteContext; + return X11_GLES_LoadLibrary(_this, path); +#else + SDL_SetError("SDL not configured with OpenGL ES/EGL support"); + return -1; +#endif + } + + /* Load the OpenGL library */ if (path == NULL) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); @@ -290,11 +328,15 @@ X11_GL_InitExtensions(_THIS) extensions = NULL; } - /* Check for GLX_EXT_swap_control */ + /* Check for GLX_EXT_swap_control(_tear) */ + _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE; if (HasExtension("GLX_EXT_swap_control", extensions)) { _this->gl_data->glXSwapIntervalEXT = (int (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT"); + if (HasExtension("GLX_EXT_swap_control_tear", extensions)) { + _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE; + } } /* Check for GLX_MESA_swap_control */ @@ -317,6 +359,11 @@ X11_GL_InitExtensions(_THIS) _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE; } + /* Check for GLX_EXT_visual_info */ + if (HasExtension("GLX_EXT_visual_info", extensions)) { + _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE; + } + if (context) { _this->gl_data->glXMakeCurrent(display, None, NULL); _this->gl_data->glXDestroyContext(display, context); @@ -332,9 +379,10 @@ int X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig) { int i = 0; + const int MAX_ATTRIBUTES = 64; /* assert buffer is large enough to hold all SDL attributes. */ - SDL_assert(size >= 32); + SDL_assert(size >= MAX_ATTRIBUTES); /* Setup our GLX attributes according to the gl_config. */ if( for_FBConfig ) { @@ -412,7 +460,17 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si GLX_SLOW_VISUAL_EXT; } + // If we're supposed to use DirectColor visuals, and we've got the EXT_visual_info + // extension, then add GLX_X_VISUAL_TYPE_EXT. + if (X11_UseDirectColorVisuals() && + _this->gl_data->HAS_GLX_EXT_visual_info) { + attribs[i++] = GLX_X_VISUAL_TYPE_EXT; + attribs[i++] = GLX_DIRECT_COLOR_EXT; + } + attribs[i++] = None; + + SDL_assert(i <= MAX_ATTRIBUTES); return i; } @@ -424,7 +482,7 @@ X11_GL_GetVisual(_THIS, Display * display, int screen) /* 64 seems nice. */ int attribs[64]; - int i = X11_GL_GetAttributes(_this,display,screen,attribs,64,SDL_FALSE); + X11_GL_GetAttributes(_this,display,screen,attribs,64,SDL_FALSE); if (!_this->gl_data) { /* The OpenGL library wasn't loaded, SDL_GetError() should have info */ @@ -448,7 +506,13 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) XWindowAttributes xattr; XVisualInfo v, *vinfo; int n; - GLXContext context = NULL; + GLXContext context = NULL, share_context; + + if (_this->gl_config.share_with_current_context) { + share_context = (GLXContext)(_this->current_glctx); + } else { + share_context = NULL; + } /* We do this to create a clean separation between X and GLX errors. */ XSync(display, False); @@ -457,9 +521,12 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) v.visualid = XVisualIDFromVisual(xattr.visual); vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n); if (vinfo) { - if (_this->gl_config.major_version < 3) { + if (_this->gl_config.major_version < 3 && + _this->gl_config.profile_mask == 0 && + _this->gl_config.flags == 0) { + /* Create legacy context */ context = - _this->gl_data->glXCreateContext(display, vinfo, NULL, True); + _this->gl_data->glXCreateContext(display, vinfo, share_context, True); } else { /* If we want a GL 3.0 context or later we need to get a temporary context to grab the new context creation function */ @@ -469,7 +536,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) SDL_SetError("Could not create GL context"); return NULL; } else { - /* max 8 attributes plus terminator */ + /* max 8 attributes plus terminator */ int attribs[9] = { GLX_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, @@ -477,21 +544,21 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) _this->gl_config.minor_version, 0 }; - int iattr = 4; + int iattr = 4; - /* SDL profile bits match GLX profile bits */ - if( _this->gl_config.profile_mask != 0 ) { - attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[iattr++] = _this->gl_config.profile_mask; - } + /* SDL profile bits match GLX profile bits */ + if( _this->gl_config.profile_mask != 0 ) { + attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB; + attribs[iattr++] = _this->gl_config.profile_mask; + } - /* SDL flags match GLX flags */ - if( _this->gl_config.flags != 0 ) { - attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB; - attribs[iattr++] = _this->gl_config.flags; - } + /* SDL flags match GLX flags */ + if( _this->gl_config.flags != 0 ) { + attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB; + attribs[iattr++] = _this->gl_config.flags; + } - attribs[iattr++] = 0; + attribs[iattr++] = 0; /* Get a pointer to the context creation function for GL 3.0 */ PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = @@ -532,7 +599,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) context = glXCreateContextAttribs(display, framebuffer_config[0], - NULL, True, attribs); + share_context, True, attribs); _this->gl_data->glXDestroyContext(display, temp_context); } @@ -565,6 +632,11 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) GLXContext glx_context = (GLXContext) context; int status; + if (!_this->gl_data) { + SDL_SetError("OpenGL not initialized"); + return -1; + } + status = 0; if (!_this->gl_data->glXMakeCurrent(display, drawable, glx_context)) { SDL_SetError("Unable to make GL context current"); @@ -587,9 +659,11 @@ static int swapinterval = -1; int X11_GL_SetSwapInterval(_THIS, int interval) { - int status; + int status = -1; - if (_this->gl_data->glXSwapIntervalEXT) { + if ((interval < 0) && (!_this->gl_data->HAS_GLX_EXT_swap_control_tear)) { + SDL_SetError("Negative swap interval unsupported in this GL"); + } else if (_this->gl_data->glXSwapIntervalEXT) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; const SDL_WindowData *windowdata = (SDL_WindowData *) _this->current_glwin->driverdata; @@ -597,7 +671,6 @@ X11_GL_SetSwapInterval(_THIS, int interval) status = _this->gl_data->glXSwapIntervalEXT(display,drawable,interval); if (status != 0) { SDL_SetError("glxSwapIntervalEXT failed"); - status = -1; } else { swapinterval = interval; } @@ -605,7 +678,6 @@ X11_GL_SetSwapInterval(_THIS, int interval) status = _this->gl_data->glXSwapIntervalMESA(interval); if (status != 0) { SDL_SetError("glxSwapIntervalMESA failed"); - status = -1; } else { swapinterval = interval; } @@ -613,13 +685,11 @@ X11_GL_SetSwapInterval(_THIS, int interval) status = _this->gl_data->glXSwapIntervalSGI(interval); if (status != 0) { SDL_SetError("glxSwapIntervalSGI failed"); - status = -1; } else { swapinterval = interval; } } else { SDL_Unsupported(); - status = -1; } return status; } @@ -632,10 +702,23 @@ X11_GL_GetSwapInterval(_THIS) const SDL_WindowData *windowdata = (SDL_WindowData *) _this->current_glwin->driverdata; Window drawable = windowdata->xwindow; - unsigned int value = 0; + unsigned int allow_late_swap_tearing = 0; + unsigned int interval = 0; + + if (_this->gl_data->HAS_GLX_EXT_swap_control_tear) { + _this->gl_data->glXQueryDrawable(display, drawable, + GLX_LATE_SWAPS_TEAR_EXT, + &allow_late_swap_tearing); + } + _this->gl_data->glXQueryDrawable(display, drawable, - GLX_SWAP_INTERVAL_EXT, &value); - return (int) value; + GLX_SWAP_INTERVAL_EXT, &interval); + + if ((allow_late_swap_tearing) && (interval > 0)) { + return -((int) interval); + } + + return (int) interval; } else if (_this->gl_data->glXGetSwapIntervalMESA) { return _this->gl_data->glXGetSwapIntervalMESA(); } else { @@ -658,6 +741,9 @@ X11_GL_DeleteContext(_THIS, SDL_GLContext context) Display *display = ((SDL_VideoData *) _this->driverdata)->display; GLXContext glx_context = (GLXContext) context; + if (!_this->gl_data) { + return; + } _this->gl_data->glXDestroyContext(display, glx_context); XSync(display, False); } diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.h old mode 100755 new mode 100644 index cbdbd3e0a..a786b773e --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengl.h @@ -30,6 +30,8 @@ struct SDL_GLDriverData { SDL_bool HAS_GLX_EXT_visual_rating; + SDL_bool HAS_GLX_EXT_visual_info; + SDL_bool HAS_GLX_EXT_swap_control_tear; void *(*glXGetProcAddress) (const GLubyte*); XVisualInfo *(*glXChooseVisual) (Display*,int,int*); diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.c old mode 100755 new mode 100644 index 6b5a8bedb..6cced5e3f --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.c @@ -24,6 +24,7 @@ #include "SDL_x11video.h" #include "SDL_x11opengles.h" +#include "SDL_x11opengl.h" #define DEFAULT_EGL "libEGL.so" #define DEFAULT_OGL_ES2 "libGLESv2.so" @@ -71,22 +72,14 @@ X11_GLES_GetProcAddress(_THIS, const char *proc) void X11_GLES_UnloadLibrary(_THIS) { - if (_this->gl_config.driver_loaded) { + if ((_this->gles_data) && (_this->gl_config.driver_loaded)) { _this->gles_data->eglTerminate(_this->gles_data->egl_display); dlclose(_this->gl_config.dll_handle); dlclose(_this->gles_data->egl_dll_handle); - _this->gles_data->eglGetProcAddress = NULL; - _this->gles_data->eglChooseConfig = NULL; - _this->gles_data->eglCreateContext = NULL; - _this->gles_data->eglCreateWindowSurface = NULL; - _this->gles_data->eglDestroyContext = NULL; - _this->gles_data->eglDestroySurface = NULL; - _this->gles_data->eglMakeCurrent = NULL; - _this->gles_data->eglSwapBuffers = NULL; - _this->gles_data->eglGetDisplay = NULL; - _this->gles_data->eglTerminate = NULL; + SDL_free(_this->gles_data); + _this->gles_data = NULL; _this->gl_config.dll_handle = NULL; _this->gl_config.driver_loaded = 0; @@ -101,10 +94,30 @@ X11_GLES_LoadLibrary(_THIS, const char *path) SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - if (_this->gles_data->egl_active) { + if (_this->gles_data) { SDL_SetError("OpenGL ES context already created"); return -1; } + + /* If SDL_GL_CONTEXT_EGL has been changed to 0, switch over to X11_GL functions */ + if (_this->gl_config.use_egl == 0) { +#if SDL_VIDEO_OPENGL_GLX + _this->GL_LoadLibrary = X11_GL_LoadLibrary; + _this->GL_GetProcAddress = X11_GL_GetProcAddress; + _this->GL_UnloadLibrary = X11_GL_UnloadLibrary; + _this->GL_CreateContext = X11_GL_CreateContext; + _this->GL_MakeCurrent = X11_GL_MakeCurrent; + _this->GL_SetSwapInterval = X11_GL_SetSwapInterval; + _this->GL_GetSwapInterval = X11_GL_GetSwapInterval; + _this->GL_SwapWindow = X11_GL_SwapWindow; + _this->GL_DeleteContext = X11_GL_DeleteContext; + return X11_GL_LoadLibrary(_this, path); +#else + SDL_SetError("SDL not configured with OpenGL/GLX support"); + return -1; +#endif + } + #ifdef RTLD_GLOBAL dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; #else @@ -115,7 +128,7 @@ X11_GLES_LoadLibrary(_THIS, const char *path) if ((dlsym(handle, "eglChooseConfig") == NULL) && (path == NULL)) { dlclose(handle); - path = getenv("SDL_VIDEO_GL_DRIVER"); + path = getenv("SDL_VIDEO_EGL_DRIVER"); if (path == NULL) { path = DEFAULT_EGL; } @@ -130,6 +143,12 @@ X11_GLES_LoadLibrary(_THIS, const char *path) /* Unload the old driver and reset the pointers */ X11_GLES_UnloadLibrary(_this); + _this->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData)); + if (!_this->gles_data) { + SDL_OutOfMemory(); + return -1; + } + /* Load new function pointers */ LOAD_FUNC(eglGetDisplay); LOAD_FUNC(eglInitialize); @@ -204,12 +223,9 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) VisualID visual_id; int i; - /* load the gl driver from a default path */ - if (!_this->gl_config.driver_loaded) { - /* no driver has been loaded, use default (ourselves) */ - if (X11_GLES_LoadLibrary(_this, NULL) < 0) { - return NULL; - } + if (!_this->gles_data) { + /* The EGL library wasn't loaded, SDL_GetError() should have info */ + return NULL; } i = 0; @@ -324,7 +340,6 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window) return NULL; } - _this->gles_data->egl_active = 1; _this->gles_data->egl_swapinterval = 0; if (X11_GLES_MakeCurrent(_this, window, context) < 0) { @@ -343,6 +358,11 @@ X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) // SDL_WindowData *data = (SDL_WindowData *) window->driverdata; // Display *display = data->videodata->display; + if (!_this->gles_data) { + SDL_SetError("OpenGL not initialized"); + return -1; + } + retval = 1; if (!_this->gles_data->eglMakeCurrent(_this->gles_data->egl_display, _this->gles_data->egl_surface, @@ -359,7 +379,7 @@ X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) int X11_GLES_SetSwapInterval(_THIS, int interval) { - if (_this->gles_data->egl_active != 1) { + if (_this->gles_data) { SDL_SetError("OpenGL ES context not active"); return -1; } @@ -378,7 +398,7 @@ X11_GLES_SetSwapInterval(_THIS, int interval) int X11_GLES_GetSwapInterval(_THIS) { - if (_this->gles_data->egl_active != 1) { + if (_this->gles_data) { SDL_SetError("OpenGL ES context not active"); return -1; } @@ -397,6 +417,10 @@ void X11_GLES_DeleteContext(_THIS, SDL_GLContext context) { /* Clean up GLES and EGL */ + if (!_this->gles_data) { + return; + } + if (_this->gles_data->egl_context != EGL_NO_CONTEXT || _this->gles_data->egl_surface != EGL_NO_SURFACE) { _this->gles_data->eglMakeCurrent(_this->gles_data->egl_display, @@ -417,11 +441,9 @@ X11_GLES_DeleteContext(_THIS, SDL_GLContext context) _this->gles_data->egl_surface = EGL_NO_SURFACE; } } - _this->gles_data->egl_active = 0; -/* crappy fix */ + /* crappy fix */ X11_GLES_UnloadLibrary(_this); - } #endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_ES */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.h old mode 100755 new mode 100644 index a9c2a2dc8..3806b93aa --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11opengles.h @@ -18,7 +18,12 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#include "SDL_config.h" +#ifndef _SDL_x11opengles_h +#define _SDL_x11opengles_h + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 #include #include #include @@ -30,7 +35,6 @@ typedef struct SDL_PrivateGLESData { - int egl_active; /* to stop switching drivers while we have a valid context */ XVisualInfo *egl_visualinfo; void *egl_dll_handle; EGLDisplay egl_display; @@ -92,3 +96,9 @@ extern int X11_GLES_SetSwapInterval(_THIS, int interval); extern int X11_GLES_GetSwapInterval(_THIS); extern void X11_GLES_SwapWindow(_THIS, SDL_Window * window); extern void X11_GLES_DeleteContext(_THIS, SDL_GLContext context); + +#endif /* SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 */ + +#endif /* _SDL_x11opengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11shape.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11shape.c old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11shape.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11shape.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11sym.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11sym.h old mode 100755 new mode 100644 index 1e2a6f223..673142e3c --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11sym.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11sym.h @@ -23,15 +23,21 @@ SDL_X11_MODULE(BASEXLIB) SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return) +SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return) +SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return) SDL_X11_SYM(int,XAutoRepeatOn,(Display* a),(a),return) SDL_X11_SYM(int,XAutoRepeatOff,(Display* a),(a),return) SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return) +SDL_X11_SYM(Bool,XCheckIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return) +SDL_X11_SYM(int,XClearWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return) SDL_X11_SYM(int,XConvertSelection,(Display* a,Atom b,Atom c,Atom d,Window e,Time f),(a,b,c,d,e,f),return) SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *data,unsigned int width,unsigned int height),(dpy,d,data,width,height),return) SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return) SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return) +SDL_X11_SYM(Cursor,XCreateFontCursor,(Display* a,unsigned int b),(a,b),return) +SDL_X11_SYM(XFontSet,XCreateFontSet,(Display* a, _Xconst char* b, char*** c, int* d, char** e),(a,b,c,d,e),return) SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return) SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j),(a,b,c,d,e,f,g,h,i,j),return) SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return) @@ -39,15 +45,21 @@ SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return) SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return) SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XDisplayKeycodes,(Display* a,int* b,int* c),(a,b,c),return) +SDL_X11_SYM(int,XDrawRectangle,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return) SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a),(a),return) +SDL_X11_SYM(int,XDrawString,(Display* a,Drawable b,GC c,int d,int e,_Xconst char* f,int g),(a,b,c,d,e,f,g),return) SDL_X11_SYM(int,XEventsQueued,(Display* a,int b),(a,b),return) +SDL_X11_SYM(int,XFillRectangle,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return) SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event,Window w),(event,w),return) SDL_X11_SYM(int,XFlush,(Display* a),(a),return) SDL_X11_SYM(int,XFree,(void*a),(a),return) SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return) +SDL_X11_SYM(void,XFreeFontSet,(Display* a, XFontSet b),(a,b),) SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return) +SDL_X11_SYM(int,XFreeFont,(Display* a, XFontStruct* b),(a,b),return) SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return) SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return) +SDL_X11_SYM(void,XFreeStringList,(char** a),(a),) SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return) SDL_X11_SYM(int,XGetInputFocus,(Display *a,Window *b,int *c),(a,b,c),return) SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return) @@ -59,14 +71,17 @@ SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* SDL_X11_SYM(int,XGetWindowProperty,(Display* a,Window b,Atom c,long d,long e,Bool f,Atom g,Atom* h,int* i,unsigned long* j,unsigned long *k,unsigned char **l),(a,b,c,d,e,f,g,h,i,j,k,l),return) SDL_X11_SYM(XWMHints*,XGetWMHints,(Display* a,Window b),(a,b),return) SDL_X11_SYM(Status,XGetWMNormalHints,(Display *a,Window b, XSizeHints *c, long *d),(a,b,c,d),return) +SDL_X11_SYM(int,XIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return) SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XGrabPointer,(Display* a,Window b,Bool c,unsigned int d,int e,int f,Window g,Cursor h,Time i),(a,b,c,d,e,f,g,h,i),return) SDL_X11_SYM(int,XGrabServer,(Display* a),(a),return) SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return) SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return) SDL_X11_SYM(char*,XKeysymToString,(KeySym a),(a),return) +SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return) SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return) SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return) +SDL_X11_SYM(XFontStruct*,XLoadQueryFont,(Display* a,_Xconst char* b),(a,b),return) SDL_X11_SYM(KeySym,XLookupKeysym,(XKeyEvent* a,int b),(a,b),return) SDL_X11_SYM(int,XLookupString,(XKeyEvent* a,char* b,int c,KeySym* d,XComposeStatus* e),(a,b,c,d,e),return) SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return) @@ -75,33 +90,44 @@ SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return) SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return) SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return) +SDL_X11_SYM(Status,XInitThreads,(void),(),return) SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return) SDL_X11_SYM(int,XPending,(Display* a),(a),return) SDL_X11_SYM(int,XPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j),(a,b,c,d,e,f,g,h,i,j),return) SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return) SDL_X11_SYM(Bool,XQueryPointer,(Display* a,Window b,Window* c,Window* d,int* e,int* f,int* g,int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return) SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return) +SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return) SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return) SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return) SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return) SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return) SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return) +SDL_X11_SYM(int,XSetForeground,(Display* a,GC b,unsigned long c),(a,b,c),return) SDL_X11_SYM(XIOErrorHandler,XSetIOErrorHandler,(XIOErrorHandler a),(a),return) +SDL_X11_SYM(int,XSetInputFocus,(Display *a,Window b,int c,Time d),(a,b,c,d),return) SDL_X11_SYM(int,XSetSelectionOwner,(Display* a,Atom b,Window c,Time d),(a,b,c,d),return) SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return) SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),) +SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return) SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),) SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),) SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return) +SDL_X11_SYM(int,XStoreName,(Display* a,Window b,_Xconst char* c),(a,b,c),return) SDL_X11_SYM(Status,XStringListToTextProperty,(char** a,int b,XTextProperty* c),(a,b,c),return) SDL_X11_SYM(int,XSync,(Display* a,Bool b),(a,b),return) +SDL_X11_SYM(int,XTextExtents,(XFontStruct* a,_Xconst char* b,int c,int* d,int* e,int* f,XCharStruct* g),(a,b,c,d,e,f,g),return) +SDL_X11_SYM(Bool,XTranslateCoordinates,(Display *a,Window b,Window c,int d,int e,int* f,int* g,Window* h),(a,b,c,d,e,f,g,h),return) SDL_X11_SYM(int,XUndefineCursor,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XUngrabKeyboard,(Display* a,Time b),(a,b),return) SDL_X11_SYM(int,XUngrabPointer,(Display* a,Time b),(a,b),return) SDL_X11_SYM(int,XUngrabServer,(Display* a),(a),return) +SDL_X11_SYM(int,XUninstallColormap,(Display* a,Colormap b),(a,b),return) +SDL_X11_SYM(int,XUnloadFont,(Display* a,Font b),(a,b),return) SDL_X11_SYM(int,XUnmapWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned int f,unsigned int g,int h,int i),(a,b,c,d,e,f,g,h,i),return) +SDL_X11_SYM(int,XWindowEvent,(Display* a,Window b,long c,XEvent* d),(a,b,c,d),return) SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return) #if SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return) @@ -157,6 +183,8 @@ SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),) SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),) SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return) SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return) +SDL_X11_SYM(void,Xutf8DrawString,(Display *a, Drawable b, XFontSet c, GC d, int e, int f, _Xconst char *g, int h),(a,b,c,d,e,f,g,h),) +SDL_X11_SYM(int,Xutf8TextExtents,(XFontSet a, _Xconst char* b, int c, XRectangle* d, XRectangle* e),(a,b,c,d,e),return) #endif #ifndef NO_SHARED_MEMORY @@ -228,6 +256,15 @@ SDL_X11_SYM(short *,XRRConfigRates,(XRRScreenConfiguration *config,int sizeID,in SDL_X11_SYM(XRRScreenSize *,XRRConfigSizes,(XRRScreenConfiguration *config,int *nsizes),(config,nsizes),return) SDL_X11_SYM(Status,XRRSetScreenConfigAndRate,(Display *dpy,XRRScreenConfiguration *config,Drawable draw,int size_index,Rotation rotation,short rate,Time timestamp),(dpy,config,draw,size_index,rotation,rate,timestamp),return) SDL_X11_SYM(void,XRRFreeScreenConfigInfo,(XRRScreenConfiguration *config),(config),) +SDL_X11_SYM(void,XRRSetScreenSize,(Display *dpy, Window window,int width, int height,int mmWidth, int mmHeight),(dpy,window,width,height,mmWidth,mmHeight),) +SDL_X11_SYM(Status,XRRGetScreenSizeRange,(Display *dpy, Window window,int *minWidth, int *minHeight, int *maxWidth, int *maxHeight),(dpy,window,minWidth,minHeight,maxWidth,maxHeight),return) +SDL_X11_SYM(XRRScreenResources *,XRRGetScreenResources,(Display *dpy, Window window),(dpy, window),return) +SDL_X11_SYM(void,XRRFreeScreenResources,(XRRScreenResources *resources),(resources),) +SDL_X11_SYM(XRROutputInfo *,XRRGetOutputInfo,(Display *dpy, XRRScreenResources *resources, RROutput output),(dpy,resources,output),return) +SDL_X11_SYM(void,XRRFreeOutputInfo,(XRROutputInfo *outputInfo),(outputInfo),) +SDL_X11_SYM(XRRCrtcInfo *,XRRGetCrtcInfo,(Display *dpy, XRRScreenResources *resources, RRCrtc crtc),(dpy,resources,crtc),return) +SDL_X11_SYM(void,XRRFreeCrtcInfo,(XRRCrtcInfo *crtcInfo),(crtcInfo),) +SDL_X11_SYM(Status,XRRSetCrtcConfig,(Display *dpy, XRRScreenResources *resources, RRCrtc crtc, Time timestamp, int x, int y, RRMode mode, Rotation rotation, RROutput *outputs, int noutputs),(dpy,resources,crtc,timestamp,x,y,mode,rotation,outputs,noutputs),return) #endif /* MIT-SCREEN-SAVER support */ @@ -251,6 +288,7 @@ SDL_X11_SYM(Bool,XF86VidModeGetViewPort,(Display *a,int b,int *c,int *d),(a,b,c, SDL_X11_SYM(Bool,XF86VidModeQueryExtension,(Display *a,int *b,int *c),(a,b,c),return) SDL_X11_SYM(Bool,XF86VidModeQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) SDL_X11_SYM(Bool,XF86VidModeSwitchToMode,(Display *a,int b,XF86VidModeModeInfo *c),(a,b,c),return) +SDL_X11_SYM(Bool,XF86VidModeLockModeSwitch,(Display *a,int b,int c),(a,b,c),return) #endif /* *INDENT-ON* */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11touch.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11touch.c old mode 100755 new mode 100644 index ddef89a66..17927e392 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11touch.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11touch.c @@ -39,13 +39,14 @@ X11_InitTouch(_THIS) /*Initilized Xinput2 multitouch * and return in order to not initialize * evtouch also*/ - if(X11_Xinput2IsMutitouchSupported()) { + if(X11_Xinput2IsMultitouchSupported()) { X11_InitXinput2Multitouch(_this); return; } #ifdef SDL_INPUT_LINUXEV FILE *fd; fd = fopen("/proc/bus/input/devices","r"); + if (!fd) return; int i = 0; int tsfd; diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11touch.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11touch.h old mode 100755 new mode 100644 diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.c old mode 100755 new mode 100644 index 690fd6d0a..52a996a53 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.c @@ -111,14 +111,40 @@ X11_DeleteDevice(SDL_VideoDevice * device) } SDL_free(data->windowlist); SDL_free(device->driverdata); -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - SDL_free(device->gles_data); -#endif SDL_free(device); SDL_X11_UnloadSymbols(); } +/* An error handler to reset the vidmode and then call the default handler. */ +static SDL_bool safety_net_triggered = SDL_FALSE; +static int (*orig_x11_errhandler) (Display *, XErrorEvent *) = NULL; +static int +X11_SafetyNetErrHandler(Display * d, XErrorEvent * e) +{ + /* if we trigger an error in our error handler, don't try again. */ + if (!safety_net_triggered) { + safety_net_triggered = SDL_TRUE; + SDL_VideoDevice *device = SDL_GetVideoDevice(); + if (device != NULL) { + int i; + for (i = 0; i < device->num_displays; i++) { + SDL_VideoDisplay *display = &device->displays[i]; + if (SDL_memcmp(&display->current_mode, &display->desktop_mode, + sizeof (SDL_DisplayMode)) != 0) { + X11_SetDisplayMode(device, display, &display->desktop_mode); + } + } + } + } + + if (orig_x11_errhandler != NULL) { + return orig_x11_errhandler(d, e); /* probably terminate. */ + } + + return 0; +} + static SDL_VideoDevice * X11_CreateDevice(int devindex) { @@ -130,6 +156,10 @@ X11_CreateDevice(int devindex) return NULL; } + // Need for threading gl calls. This is also required for the proprietary nVidia + // driver to be threaded. + XInitThreads(); + /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { @@ -144,14 +174,6 @@ X11_CreateDevice(int devindex) } device->driverdata = data; -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - device->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData)); - if (!device->gles_data) { - SDL_OutOfMemory(); - return NULL; - } -#endif - /* FIXME: Do we need this? if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) || (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) { @@ -175,6 +197,7 @@ X11_CreateDevice(int devindex) } #endif if (data->display == NULL) { + SDL_free(device->driverdata); SDL_free(device); SDL_SetError("Couldn't open X11 display"); return NULL; @@ -183,10 +206,15 @@ X11_CreateDevice(int devindex) XSynchronize(data->display, True); #endif + /* Hook up an X11 error handler to recover the desktop resolution. */ + safety_net_triggered = SDL_FALSE; + orig_x11_errhandler = XSetErrorHandler(X11_SafetyNetErrHandler); + /* Set the function pointers */ device->VideoInit = X11_VideoInit; device->VideoQuit = X11_VideoQuit; device->GetDisplayModes = X11_GetDisplayModes; + device->GetDisplayBounds = X11_GetDisplayBounds; device->SetDisplayMode = X11_SetDisplayMode; device->SuspendScreenSaver = X11_SuspendScreenSaver; device->PumpEvents = X11_PumpEvents; @@ -203,6 +231,7 @@ X11_CreateDevice(int devindex) device->MaximizeWindow = X11_MaximizeWindow; device->MinimizeWindow = X11_MinimizeWindow; device->RestoreWindow = X11_RestoreWindow; + device->SetWindowBordered = X11_SetWindowBordered; device->SetWindowFullscreen = X11_SetWindowFullscreen; device->SetWindowGammaRamp = X11_SetWindowGammaRamp; device->SetWindowGrab = X11_SetWindowGrab; @@ -226,8 +255,7 @@ X11_CreateDevice(int devindex) device->GL_GetSwapInterval = X11_GL_GetSwapInterval; device->GL_SwapWindow = X11_GL_SwapWindow; device->GL_DeleteContext = X11_GL_DeleteContext; -#endif -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 device->GL_LoadLibrary = X11_GLES_LoadLibrary; device->GL_GetProcAddress = X11_GLES_GetProcAddress; device->GL_UnloadLibrary = X11_GLES_UnloadLibrary; @@ -342,15 +370,20 @@ X11_VideoInit(_THIS) /* Look up some useful Atoms */ #define GET_ATOM(X) data->X = XInternAtom(data->display, #X, False) + GET_ATOM(WM_PROTOCOLS); GET_ATOM(WM_DELETE_WINDOW); GET_ATOM(_NET_WM_STATE); GET_ATOM(_NET_WM_STATE_HIDDEN); + GET_ATOM(_NET_WM_STATE_FOCUSED); GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); GET_ATOM(_NET_WM_STATE_FULLSCREEN); + GET_ATOM(_NET_WM_ALLOWED_ACTIONS); + GET_ATOM(_NET_WM_ACTION_FULLSCREEN); GET_ATOM(_NET_WM_NAME); GET_ATOM(_NET_WM_ICON_NAME); GET_ATOM(_NET_WM_ICON); + GET_ATOM(_NET_WM_PING); GET_ATOM(UTF8_STRING); /* Detect the window manager */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.h old mode 100755 new mode 100644 index 59234296f..5c092048f --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11video.h @@ -80,15 +80,20 @@ typedef struct SDL_VideoData SDL_bool net_wm; /* Useful atoms */ + Atom WM_PROTOCOLS; Atom WM_DELETE_WINDOW; Atom _NET_WM_STATE; Atom _NET_WM_STATE_HIDDEN; + Atom _NET_WM_STATE_FOCUSED; Atom _NET_WM_STATE_MAXIMIZED_VERT; Atom _NET_WM_STATE_MAXIMIZED_HORZ; Atom _NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_ALLOWED_ACTIONS; + Atom _NET_WM_ACTION_FULLSCREEN; Atom _NET_WM_NAME; Atom _NET_WM_ICON_NAME; Atom _NET_WM_ICON; + Atom _NET_WM_PING; Atom UTF8_STRING; SDL_Scancode key_layout[256]; diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.c old mode 100755 new mode 100644 index ece345a24..308768c85 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.c @@ -22,6 +22,7 @@ #if SDL_VIDEO_DRIVER_X11 +#include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_keyboard_c.h" @@ -38,22 +39,30 @@ #include "SDL_timer.h" #include "SDL_syswm.h" +#include "SDL_assert.h" #define _NET_WM_STATE_REMOVE 0l #define _NET_WM_STATE_ADD 1l #define _NET_WM_STATE_TOGGLE 2l -static SDL_bool -X11_IsWindowOldFullscreen(_THIS, SDL_Window * window) +static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win) { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + return ev->type == MapNotify && ev->xmap.window == *((Window*)win); +} +static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win) +{ + return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win); +} +static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win) +{ + return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win); +} - /* ICCCM2.0-compliant window managers can handle fullscreen windows */ - if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) { - return SDL_TRUE; - } else { - return SDL_FALSE; - } +static SDL_bool +X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + return (data->fswindow != 0); } static SDL_bool @@ -71,20 +80,126 @@ X11_IsWindowMapped(_THIS, SDL_Window * window) } } -static int -X11_GetWMStateProperty(_THIS, SDL_Window * window, Atom atoms[3]) +#if 0 +static SDL_bool +X11_IsActionAllowed(SDL_Window *window, Atom action) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS; + Atom type; + Display *display = data->videodata->display; + int form; + unsigned long remain; + unsigned long len, i; + Atom *list; + SDL_bool ret = SDL_FALSE; + + if (XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success) + { + for (i=0; idriverdata; + Display *display = videodata->display; + Atom _NET_WM_STATE = videodata->_NET_WM_STATE; + /*Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN;*/ + Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; + Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; + Atom atoms[5]; int count = 0; - if (window->flags & SDL_WINDOW_FULLSCREEN) { - atoms[count++] = data->_NET_WM_STATE_FULLSCREEN; + /* The window manager sets this property, we shouldn't set it. + If we did, this would indicate to the window manager that we don't + actually want to be mapped during XMapRaised(), which would be bad. + * + if (flags & SDL_WINDOW_HIDDEN) { + atoms[count++] = _NET_WM_STATE_HIDDEN; } - if (window->flags & SDL_WINDOW_MAXIMIZED) { - atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_VERT; - atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_HORZ; + */ + if (flags & SDL_WINDOW_INPUT_FOCUS) { + atoms[count++] = _NET_WM_STATE_FOCUSED; } - return count; + if (flags & SDL_WINDOW_MAXIMIZED) { + atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT; + atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ; + } + if (flags & SDL_WINDOW_FULLSCREEN) { + atoms[count++] = _NET_WM_STATE_FULLSCREEN; + } + if (count > 0) { + XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, (unsigned char *)atoms, count); + } else { + XDeleteProperty(display, xwindow, _NET_WM_STATE); + } +} + +Uint32 +X11_GetNetWMState(_THIS, Window xwindow) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + Display *display = videodata->display; + Atom _NET_WM_STATE = videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; + Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; + Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; + Atom actualType; + int actualFormat; + unsigned long i, numItems, bytesAfter; + unsigned char *propertyValue = NULL; + long maxLength = 1024; + Uint32 flags = 0; + + if (XGetWindowProperty(display, xwindow, _NET_WM_STATE, + 0l, maxLength, False, XA_ATOM, &actualType, + &actualFormat, &numItems, &bytesAfter, + &propertyValue) == Success) { + Atom *atoms = (Atom *) propertyValue; + int maximized = 0; + int fullscreen = 0; + + for (i = 0; i < numItems; ++i) { + if (atoms[i] == _NET_WM_STATE_HIDDEN) { + flags |= SDL_WINDOW_HIDDEN; + } else if (atoms[i] == _NET_WM_STATE_FOCUSED) { + flags |= SDL_WINDOW_INPUT_FOCUS; + } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) { + maximized |= 1; + } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { + maximized |= 2; + } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) { + fullscreen = 1; + } + } + if (maximized == 3) { + flags |= SDL_WINDOW_MAXIMIZED; + } else if (fullscreen == 1) { + flags |= SDL_WINDOW_FULLSCREEN; + } + XFree(propertyValue); + } + + /* FIXME, check the size hints for resizable */ + /*flags |= SDL_WINDOW_RESIZABLE;*/ + + return flags; } static int @@ -155,42 +270,7 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) data->colormap = attrib.colormap; } - { - Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; - Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; - Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; - Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; - Atom actualType; - int actualFormat; - unsigned long i, numItems, bytesAfter; - unsigned char *propertyValue = NULL; - long maxLength = 1024; - - if (XGetWindowProperty(data->videodata->display, w, _NET_WM_STATE, - 0l, maxLength, False, XA_ATOM, &actualType, - &actualFormat, &numItems, &bytesAfter, - &propertyValue) == Success) { - Atom *atoms = (Atom *) propertyValue; - int maximized = 0; - int fullscreen = 0; - - for (i = 0; i < numItems; ++i) { - if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) { - maximized |= 1; - } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { - maximized |= 2; - } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) { - fullscreen = 1; - } - } - if (maximized == 3) { - window->flags |= SDL_WINDOW_MAXIMIZED; - } else if (fullscreen == 1) { - window->flags |= SDL_WINDOW_FULLSCREEN; - } - XFree(propertyValue); - } - } + window->flags |= X11_GetNetWMState(_this, w); { Window FocalWindow; @@ -199,6 +279,9 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) if (FocalWindow==w) { window->flags |= SDL_WINDOW_INPUT_FOCUS; + } + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { SDL_SetKeyboardFocus(data->window); } @@ -207,46 +290,42 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) } } - /* FIXME: How can I tell? - { - DWORD style = GetWindowLong(hwnd, GWL_STYLE); - if (style & WS_VISIBLE) { - 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_MINIMIZE) { - window->flags |= SDL_WINDOW_MINIMIZED; - } else { - window->flags &= ~SDL_WINDOW_MINIMIZED; - } - } - if (GetFocus() == hwnd) { - int index = data->videodata->keyboard; - window->flags |= SDL_WINDOW_INPUT_FOCUS; - SDL_SetKeyboardFocus(index, 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); - } - } - */ - /* All done! */ window->driverdata = data; return 0; } +static void +SetWindowBordered(Display *display, int screen, Window window, SDL_bool border) +{ + /* + * this code used to check for KWM_WIN_DECORATION, but KDE hasn't + * supported it for years and years. It now respects _MOTIF_WM_HINTS. + * Gnome is similar: just use the Motif atom. + */ + + Atom WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True); + if (WM_HINTS != None) { + /* Hints used by Motif compliant window managers */ + struct + { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; + } MWMHints = { + (1L << 1), 0, border ? 1 : 0, 0, 0 + }; + + XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32, + PropModeReplace, (unsigned char *) &MWMHints, + sizeof(MWMHints) / 4); + } else { /* set the transient hints instead, if necessary */ + XSetTransientForHint(display, window, RootWindow(display, screen)); + } +} + int X11_CreateWindow(_THIS, SDL_Window * window) { @@ -259,42 +338,28 @@ X11_CreateWindow(_THIS, SDL_Window * window) int depth; XSetWindowAttributes xattr; Window w; - XSizeHints sizehints; - XWMHints wmhints; - XClassHint classhints; + XSizeHints *sizehints; + XWMHints *wmhints; + XClassHint *classhints; Atom _NET_WM_WINDOW_TYPE; Atom _NET_WM_WINDOW_TYPE_NORMAL; Atom _NET_WM_PID; - int wmstate_count; - Atom wmstate_atoms[3]; Uint32 fevent = 0; -#if SDL_VIDEO_DRIVER_X11_XINERAMA -/* FIXME - if ( use_xinerama ) { - x = xinerama_info.x_org; - y = xinerama_info.y_org; - } -*/ +#if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + if (window->flags & SDL_WINDOW_OPENGL) { + XVisualInfo *vinfo; + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + if (_this->gl_config.use_egl == 1) { + vinfo = X11_GLES_GetVisual(_this, display, screen); + } else #endif + { #if SDL_VIDEO_OPENGL_GLX - if (window->flags & SDL_WINDOW_OPENGL) { - XVisualInfo *vinfo; - - vinfo = X11_GL_GetVisual(_this, display, screen); - if (!vinfo) { - return -1; - } - visual = vinfo->visual; - depth = vinfo->depth; - XFree(vinfo); - } else + vinfo = X11_GL_GetVisual(_this, display, screen); #endif -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if (window->flags & SDL_WINDOW_OPENGL) { - XVisualInfo *vinfo; - - vinfo = X11_GLES_GetVisual(_this, display, screen); + } if (!vinfo) { return -1; } @@ -403,7 +468,12 @@ X11_CreateWindow(_THIS, SDL_Window * window) return -1; } #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if (window->flags & SDL_WINDOW_OPENGL) { + if ((window->flags & SDL_WINDOW_OPENGL) && (_this->gl_config.use_egl == 1)) { + if (!_this->gles_data) { + XDestroyWindow(display, w); + return -1; + } + /* Create the GLES window surface */ _this->gles_data->egl_surface = _this->gles_data->eglCreateWindowSurface(_this->gles_data-> @@ -413,116 +483,43 @@ X11_CreateWindow(_THIS, SDL_Window * window) if (_this->gles_data->egl_surface == EGL_NO_SURFACE) { SDL_SetError("Could not create GLES window surface"); + XDestroyWindow(display, w); return -1; } } #endif - if (window->flags & SDL_WINDOW_BORDERLESS) { - SDL_bool set; - Atom WM_HINTS; - - /* We haven't modified the window manager hints yet */ - set = SDL_FALSE; - - /* First try to set MWM hints */ - WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True); - if (WM_HINTS != None) { - /* Hints used by Motif compliant window managers */ - struct - { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; - } MWMHints = { - (1L << 1), 0, 0, 0, 0}; - - XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32, - PropModeReplace, (unsigned char *) &MWMHints, - sizeof(MWMHints) / 4); - set = SDL_TRUE; - } - /* Now try to set KWM hints */ - WM_HINTS = XInternAtom(display, "KWM_WIN_DECORATION", True); - if (WM_HINTS != None) { - long KWMHints = 0; - - XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32, - PropModeReplace, - (unsigned char *) &KWMHints, - sizeof(KWMHints) / 4); - set = SDL_TRUE; - } - /* Now try to set GNOME hints */ - WM_HINTS = XInternAtom(display, "_WIN_HINTS", True); - if (WM_HINTS != None) { - long GNOMEHints = 0; - - XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32, - PropModeReplace, - (unsigned char *) &GNOMEHints, - sizeof(GNOMEHints) / 4); - set = SDL_TRUE; - } - /* Finally set the transient hints if necessary */ - if (!set) { - XSetTransientForHint(display, w, RootWindow(display, screen)); - } - } else { - SDL_bool set; - Atom WM_HINTS; - - /* We haven't modified the window manager hints yet */ - set = SDL_FALSE; - - /* First try to unset MWM hints */ - WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True); - if (WM_HINTS != None) { - XDeleteProperty(display, w, WM_HINTS); - set = SDL_TRUE; - } - /* Now try to unset KWM hints */ - WM_HINTS = XInternAtom(display, "KWM_WIN_DECORATION", True); - if (WM_HINTS != None) { - XDeleteProperty(display, w, WM_HINTS); - set = SDL_TRUE; - } - /* Now try to unset GNOME hints */ - WM_HINTS = XInternAtom(display, "_WIN_HINTS", True); - if (WM_HINTS != None) { - XDeleteProperty(display, w, WM_HINTS); - set = SDL_TRUE; - } - /* Finally unset the transient hints if necessary */ - if (!set) { - XDeleteProperty(display, w, XA_WM_TRANSIENT_FOR); - } - } + SetWindowBordered(display, screen, w, + (window->flags & SDL_WINDOW_BORDERLESS) == 0); + sizehints = XAllocSizeHints(); /* Setup the normal size hints */ - sizehints.flags = 0; + sizehints->flags = 0; if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - sizehints.min_width = sizehints.max_width = window->w; - sizehints.min_height = sizehints.max_height = window->h; - sizehints.flags |= (PMaxSize | PMinSize); + sizehints->min_width = sizehints->max_width = window->w; + sizehints->min_height = sizehints->max_height = window->h; + sizehints->flags |= (PMaxSize | PMinSize); } - sizehints.x = window->x; - sizehints.y = window->y; - sizehints.flags |= USPosition; + sizehints->x = window->x; + sizehints->y = window->y; + sizehints->flags |= USPosition; /* Setup the input hints so we get keyboard input */ - wmhints.input = True; - wmhints.flags = InputHint; + wmhints = XAllocWMHints(); + wmhints->input = True; + wmhints->flags = InputHint; /* Setup the class hints so we can get an icon (AfterStep) */ - classhints.res_name = data->classname; - classhints.res_class = data->classname; + classhints = XAllocClassHint(); + classhints->res_name = data->classname; + classhints->res_class = data->classname; /* Set the size, input and class hints, and define WM_CLIENT_MACHINE and WM_LOCALE_NAME */ - XSetWMProperties(display, w, NULL, NULL, NULL, 0, &sizehints, &wmhints, &classhints); + XSetWMProperties(display, w, NULL, NULL, NULL, 0, sizehints, wmhints, classhints); + XFree(sizehints); + XFree(wmhints); + XFree(classhints); /* Set the PID related to the window for the given hostname, if possible */ if (data->pid > 0) { _NET_WM_PID = XInternAtom(display, "_NET_WM_PID", False); @@ -531,14 +528,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) } /* Set the window manager state */ - wmstate_count = X11_GetWMStateProperty(_this, window, wmstate_atoms); - if (wmstate_count > 0) { - XChangeProperty(display, w, data->_NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, - (unsigned char *)wmstate_atoms, wmstate_count); - } else { - XDeleteProperty(display, w, data->_NET_WM_STATE); - } + X11_SetNetWMState(_this, w, window->flags); /* Let the window manager know we're a "normal" window */ _NET_WM_WINDOW_TYPE = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); @@ -547,8 +537,14 @@ X11_CreateWindow(_THIS, SDL_Window * window) PropModeReplace, (unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1); - /* Allow the window to be deleted by the window manager */ - XSetWMProtocols(display, w, &data->WM_DELETE_WINDOW, 1); + + { + Atom protocols[] = { + data->WM_DELETE_WINDOW, /* Allow window to be deleted by the WM */ + data->_NET_WM_PING, /* Respond so WM knows we're alive */ + }; + XSetWMProtocols(display, w, protocols, sizeof (protocols) / sizeof (protocols[0])); + } if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) { XDestroyWindow(display, w); @@ -729,6 +725,7 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 32, PropModeReplace, (unsigned char *) propdata, propsize); } + SDL_free(propdata); SDL_FreeSurface(surface); } else { XDeleteProperty(display, data->xwindow, _NET_WM_ICON); @@ -752,8 +749,9 @@ X11_SetWindowSize(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; - if (SDL_IsShapedWindow(window)) + if (SDL_IsShapedWindow(window)) { X11_ResizeWindowShape(window); + } if (!(window->flags & SDL_WINDOW_RESIZABLE)) { /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the XResizeWindow, thus we must set the size hints to adjust the window size.*/ @@ -762,25 +760,96 @@ X11_SetWindowSize(_THIS, SDL_Window * window) XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - sizehints->min_width = sizehints->max_height = window->w; + sizehints->min_width = sizehints->max_width = window->w; sizehints->min_height = sizehints->max_height = window->h; XSetWMNormalHints(display, data->xwindow, sizehints); XFree(sizehints); - } else + + /* From Pierre-Loup: + For the windowed resize problem; WMs each have their little quirks with + that. When you change the size hints, they get a ConfigureNotify event + with the WM_NORMAL_SIZE_HINTS Atom. They all save the hints then, but + they don't all resize the window right away to enforce the new hints. + Those who do properly do it are: + + - XFWM + - metacity + - KWin + + These are great. Now, others are more problematic as you could observe + first hand. Compiz/Unity only falls into the code that does it on select + actions, such as window move, raise, map, etc. + + WindowMaker is even more difficult and will _only_ do it on map. + + Awesome only does it on user-initiated moves as far as I can tell. + + Your raise workaround only fixes compiz/Unity. With that all "modern" + window managers are covered. Trying to Hide/Show on windowed resize + (UnMap/Map) fixes both Unity and WindowMaker, but introduces subtle + problems with transitioning from Windowed to Fullscreen on Unity. Since + some window moves happen after the transitions to fullscreen, that forces + SDL to fall from windowed to fullscreen repeatedly and it sometimes leaves + itself in a state where the fullscreen window is slightly offset by what + used to be the window decoration titlebar. + */ + XRaiseWindow(display, data->xwindow); + } else { XResizeWindow(display, data->xwindow, window->w, window->h); + } XFlush(display); } +void +X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +{ + const SDL_bool focused = ((window->flags & SDL_WINDOW_INPUT_FOCUS) != 0); + const SDL_bool visible = ((window->flags & SDL_WINDOW_HIDDEN) == 0); + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + XEvent event; + + SetWindowBordered(display, displaydata->screen, data->xwindow, bordered); + XFlush(display); + XIfEvent(display, &event, &isConfigureNotify, (XPointer)&data->xwindow); + + if (visible) { + XWindowAttributes attr; + do { + XSync(display, False); + XGetWindowAttributes(display, data->xwindow, &attr); + } while (attr.map_state != IsViewable); + + if (focused) { + XSetInputFocus(display, data->xwindow, RevertToParent, CurrentTime); + } + } + + /* make sure these don't make it to the real event queue if they fired here. */ + XSync(display, False); + XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); + XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); +} + void X11_ShowWindow(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; + XEvent event; - XMapRaised(display, data->xwindow); - XFlush(display); + if (!X11_IsWindowMapped(_this, window)) { + XMapRaised(display, data->xwindow); + /* Blocking wait for "MapNotify" event. + * We use XIfEvent because XWindowEvent takes a mask rather than a type, + * and XCheckTypedWindowEvent doesn't block */ + XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); + XFlush(display); + } } void @@ -788,9 +857,14 @@ X11_HideWindow(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; + XEvent event; - XUnmapWindow(display, data->xwindow); - XFlush(display); + if (X11_IsWindowMapped(_this, window)) { + XUnmapWindow(display, data->xwindow); + /* Blocking wait for "UnmapNotify" event */ + XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); + XFlush(display); + } } void @@ -813,7 +887,6 @@ SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; - Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; if (X11_IsWindowMapped(_this, window)) { XEvent e; @@ -832,22 +905,15 @@ SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) XSendEvent(display, RootWindow(display, displaydata->screen), 0, SubstructureNotifyMask | SubstructureRedirectMask, &e); } else { - int count = 0; - Atom atoms[3]; + Uint32 flags; - if (window->flags & SDL_WINDOW_FULLSCREEN) { - atoms[count++] = _NET_WM_STATE_FULLSCREEN; - } + flags = window->flags; if (maximized) { - atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT; - atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ; - } - if (count > 0) { - XChangeProperty(display, data->xwindow, _NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)atoms, count); + flags |= SDL_WINDOW_MAXIMIZED; } else { - XDeleteProperty(display, data->xwindow, _NET_WM_STATE); + flags &= ~SDL_WINDOW_MAXIMIZED; } + X11_SetNetWMState(_this, data->xwindow, flags); } XFlush(display); } @@ -877,20 +943,39 @@ X11_RestoreWindow(_THIS, SDL_Window * window) X11_ShowWindow(_this, window); } -void -X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) +/* This asks the Window Manager to handle fullscreen for us. Most don't do it right, though. */ +static void +X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; Display *display = data->videodata->display; Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; - Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; - Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; if (X11_IsWindowMapped(_this, window)) { XEvent e; + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we + can be resized to the fullscreen resolution (or reset so we're not resizable again) */ + XSizeHints *sizehints = XAllocSizeHints(); + long flags = 0; + XGetWMNormalHints(display, data->xwindow, sizehints, &flags); + /* set the resize flags on */ + if (fullscreen) { + /* we are going fullscreen so turn the flags off */ + sizehints->flags &= ~(PMinSize | PMaxSize); + } else { + /* Reset the min/max width height to make the window non-resizable again */ + sizehints->flags |= PMinSize | PMaxSize; + sizehints->min_width = sizehints->max_width = window->windowed.w; + sizehints->min_height = sizehints->max_height = window->windowed.h; + } + XSetWMNormalHints(display, data->xwindow, sizehints); + XFree(sizehints); + } + SDL_zero(e); e.xany.type = ClientMessage; e.xclient.message_type = _NET_WM_STATE; @@ -904,26 +989,186 @@ X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, XSendEvent(display, RootWindow(display, displaydata->screen), 0, SubstructureNotifyMask | SubstructureRedirectMask, &e); } else { - int count = 0; - Atom atoms[3]; + Uint32 flags; + flags = window->flags; if (fullscreen) { - atoms[count++] = _NET_WM_STATE_FULLSCREEN; - } - if (window->flags & SDL_WINDOW_MAXIMIZED) { - atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT; - atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ; - } - if (count > 0) { - XChangeProperty(display, data->xwindow, _NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)atoms, count); + flags |= SDL_WINDOW_FULLSCREEN; } else { - XDeleteProperty(display, data->xwindow, _NET_WM_STATE); + flags &= ~SDL_WINDOW_FULLSCREEN; + } + X11_SetNetWMState(_this, data->xwindow, flags); + } + + if (data->visual->class == DirectColor) { + if ( fullscreen ) { + XInstallColormap(display, data->colormap); + } else { + XUninstallColormap(display, data->colormap); } } + XFlush(display); } +static __inline__ int +maxint(const int a, const int b) +{ + return (a > b ? a : b); +} + + +/* This handles fullscreen itself, outside the Window Manager. */ +static void +X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; + Visual *visual = data->visual; + Display *display = data->videodata->display; + const int screen = displaydata->screen; + Window root = RootWindow(display, screen); + const int def_vis = (visual == DefaultVisual(display, screen)); + unsigned long xattrmask = 0; + XSetWindowAttributes xattr; + XEvent ev; + SDL_Rect rect; + + if ( data->fswindow ) { + return; /* already fullscreen, I hope. */ + } + + X11_GetDisplayBounds(_this, _display, &rect); + + SDL_zero(xattr); + xattr.override_redirect = True; + xattrmask |= CWOverrideRedirect; + xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0; + xattrmask |= CWBackPixel; + xattr.border_pixel = 0; + xattrmask |= CWBorderPixel; + xattr.colormap = data->colormap; + xattrmask |= CWColormap; + + data->fswindow = XCreateWindow(display, root, + rect.x, rect.y, rect.w, rect.h, 0, + displaydata->depth, InputOutput, + visual, xattrmask, &xattr); + + XSelectInput(display, data->fswindow, StructureNotifyMask); + XSetWindowBackground(display, data->fswindow, 0); + XInstallColormap(display, data->colormap); + XClearWindow(display, data->fswindow); + XMapRaised(display, data->fswindow); + + /* Make sure the fswindow is in view by warping mouse to the corner */ + XUngrabPointer(display, CurrentTime); + XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); + + /* Wait to be mapped, filter Unmap event out if it arrives. */ + XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow); + XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow); + +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + if ( displaydata->use_vidmode ) { + XF86VidModeLockModeSwitch(display, screen, True); + } +#endif + + SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE); + + /* Center actual window within our cover-the-screen window. */ + XReparentWindow(display, data->xwindow, data->fswindow, + (rect.w - window->w) / 2, (rect.h - window->h) / 2); + + /* Center mouse in the fullscreen window. */ + rect.x += (rect.w / 2); + rect.y += (rect.h / 2); + XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); + + /* Wait to be mapped, filter Unmap event out if it arrives. */ + XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); + XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); + + SDL_UpdateWindowGrab(window); +} + +static void +X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; + Display *display = data->videodata->display; + const int screen = displaydata->screen; + Window root = RootWindow(display, screen); + Window fswindow = data->fswindow; + XEvent ev; + + if (!data->fswindow) { + return; /* already not fullscreen, I hope. */ + } + + data->fswindow = None; + +#if SDL_VIDEO_DRIVER_X11_VIDMODE + if ( displaydata->use_vidmode ) { + XF86VidModeLockModeSwitch(display, screen, False); + } +#endif + + SDL_UpdateWindowGrab(window); + + XReparentWindow(display, data->xwindow, root, window->x, window->y); + + /* flush these events so they don't confuse normal event handling */ + XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); + XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); + + SetWindowBordered(display, screen, data->xwindow, + (window->flags & SDL_WINDOW_BORDERLESS) == 0); + + XUnmapWindow(display, fswindow); + + /* Wait to be unmapped. */ + XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow); + XDestroyWindow(display, fswindow); +} + + +void +X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) +{ + /* !!! FIXME: SDL_Hint? */ + SDL_bool legacy = SDL_FALSE; + const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN"); + if (env) { + legacy = SDL_atoi(env); + } else { + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; + if ( displaydata->use_vidmode ) { + legacy = SDL_TRUE; /* the new stuff only works with XRandR. */ + } else if ( !videodata->net_wm ) { + legacy = SDL_TRUE; /* The window manager doesn't support it */ + } else { + /* !!! FIXME: look at the window manager name, and blacklist certain ones? */ + /* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */ + legacy = SDL_FALSE; /* try the new way. */ + } + } + + if (legacy) { + if (fullscreen) { + X11_BeginWindowFullscreenLegacy(_this, window, _display); + } else { + X11_EndWindowFullscreenLegacy(_this, window, _display); + } + } else { + X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); + } +} + + int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) { @@ -994,17 +1239,21 @@ X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) } void -X11_SetWindowGrab(_THIS, SDL_Window * window) +X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; SDL_bool oldstyle_fullscreen; + SDL_bool grab_keyboard; + const char *hint; - /* ICCCM2.0-compliant window managers can handle fullscreen windows */ - oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window); + /* ICCCM2.0-compliant window managers can handle fullscreen windows + If we're using XVidMode to change resolution we need to confine + the cursor so we don't pan around the virtual desktop. + */ + oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window); - if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen) - && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + if (oldstyle_fullscreen || grabbed) { /* Try to grab the mouse */ for (;;) { int result = @@ -1013,19 +1262,31 @@ X11_SetWindowGrab(_THIS, SDL_Window * window) if (result == GrabSuccess) { break; } - SDL_Delay(100); + SDL_Delay(50); } /* Raise the window if we grab the mouse */ XRaiseWindow(display, data->xwindow); /* Now grab the keyboard */ - XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, - GrabModeAsync, CurrentTime); + hint = SDL_GetHint(SDL_HINT_GRAB_KEYBOARD); + if (hint && SDL_atoi(hint)) { + grab_keyboard = SDL_TRUE; + } else { + /* We need to do this with the old style override_redirect + fullscreen window otherwise we won't get keyboard focus. + */ + grab_keyboard = oldstyle_fullscreen; + } + if (grab_keyboard) { + XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + } } else { XUngrabPointer(display, CurrentTime); XUngrabKeyboard(display, CurrentTime); } + XSync(display, False); } void diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.h old mode 100755 new mode 100644 index f3cb48efc..d65e08127 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11window.h @@ -23,10 +23,25 @@ #ifndef _SDL_x11window_h #define _SDL_x11window_h +/* We need to queue the focus in/out changes because they may occur during + video mode changes and we can respond to them by triggering more mode + changes. +*/ +#define PENDING_FOCUS_IN_TIME 200 +#define PENDING_FOCUS_OUT_TIME 200 + +typedef enum +{ + PENDING_FOCUS_NONE, + PENDING_FOCUS_IN, + PENDING_FOCUS_OUT +} PendingFocusEnum; + typedef struct { SDL_Window *window; Window xwindow; + Window fswindow; /* used if we can't have the WM handle fullscreen. */ Visual *visual; Colormap colormap; #ifndef NO_SHARED_MEMORY @@ -38,9 +53,15 @@ typedef struct GC gc; XIC ic; SDL_bool created; + PendingFocusEnum pending_focus; + Uint32 pending_focus_time; + XConfigureEvent last_xconfigure; struct SDL_VideoData *videodata; } SDL_WindowData; +extern void X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags); +extern Uint32 X11_GetNetWMState(_THIS, Window xwindow); + extern int X11_CreateWindow(_THIS, SDL_Window * window); extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); extern char *X11_GetWindowTitle(_THIS, Window xwindow); @@ -54,9 +75,10 @@ extern void X11_RaiseWindow(_THIS, SDL_Window * window); extern void X11_MaximizeWindow(_THIS, SDL_Window * window); extern void X11_MinimizeWindow(_THIS, SDL_Window * window); extern void X11_RestoreWindow(_THIS, SDL_Window * window); +extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); -extern void X11_SetWindowGrab(_THIS, SDL_Window * window); +extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void X11_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.c b/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.c index 30742f8d4..94f7599a5 100644 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.c +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.c @@ -29,16 +29,19 @@ #define MAX_AXIS 16 +#if SDL_VIDEO_DRIVER_X11_XINPUT2 static int xinput2_initialized = 0; + +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH static int xinput2_multitouch_supported = 0; -/* Opcode returned XQueryExtension +#endif + +/* Opcode returned XQueryExtension * It will be used in event processing * to know that the event came from * this extension */ static int xinput2_opcode; - -#if SDL_VIDEO_DRIVER_X11_XINPUT2 static void parse_valuators(const double *input_values,unsigned char *mask,int mask_len, double *output_values,int output_values_len) { int i = 0,z = 0; @@ -217,6 +220,10 @@ X11_InitXinput2Multitouch(_THIS) { void X11_Xinput2SelectTouch(_THIS, SDL_Window *window) { #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + if (!X11_Xinput2IsMultitouchSupported()) { + return; + } + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; XIEventMask eventmask; unsigned char mask[3] = { 0,0,0 }; @@ -237,12 +244,20 @@ X11_Xinput2SelectTouch(_THIS, SDL_Window *window) { int X11_Xinput2IsInitialized() { +#if SDL_VIDEO_DRIVER_X11_XINPUT2 return xinput2_initialized; +#else + return 0; +#endif } int -X11_Xinput2IsMutitouchSupported() { +X11_Xinput2IsMultitouchSupported() { +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH return xinput2_initialized && xinput2_multitouch_supported; +#else + return 0; +#endif } #endif /* SDL_VIDEO_DRIVER_X11 */ diff --git a/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.h b/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.h index a95ef2940..207c100c2 100644 --- a/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.h +++ b/src/eepp/helper/SDL2/src/video/x11/SDL_x11xinput2.h @@ -34,7 +34,7 @@ extern void X11_InitXinput2(_THIS); extern void X11_InitXinput2Multitouch(_THIS); extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie); extern int X11_Xinput2IsInitialized(void); -extern int X11_Xinput2IsMutitouchSupported(void); +extern int X11_Xinput2IsMultitouchSupported(void); extern void X11_Xinput2SelectTouch(_THIS, SDL_Window *window); #endif /* _SDL_x11xinput2_h */ diff --git a/src/eepp/window/backend/SDL2/cwindowsdl2.cpp b/src/eepp/window/backend/SDL2/cwindowsdl2.cpp index 80372aff1..33a30a3de 100644 --- a/src/eepp/window/backend/SDL2/cwindowsdl2.cpp +++ b/src/eepp/window/backend/SDL2/cwindowsdl2.cpp @@ -20,6 +20,44 @@ #include #include + +#if EE_PLATFORM == EE_PLATFORM_ANDROID +#include +#include + +static std::string SDL_AndroidGetApkPath() { + static std::string apkPath = ""; + + if ( "" == apkPath ) { + jmethodID mid; + jobject context; + jobject fileObject; + const char *path; + + JNIEnv *env = (JNIEnv*)SDL_AndroidGetJNIEnv(); + + jclass ActivityClass = env->GetObjectClass((jobject)SDL_AndroidGetActivity()); + + // context = SDLActivity.getContext(); + mid = env->GetStaticMethodID(ActivityClass,"getContext","()Landroid/content/Context;"); + + context = env->CallStaticObjectMethod(ActivityClass, mid); + + // fileObj = context.getFilesDir(); + mid = env->GetMethodID(env->GetObjectClass(context),"getPackageCodePath", "()Ljava/lang/String;"); + + fileObject = env->CallObjectMethod(context, mid); + + jboolean isCopy; + path = env->GetStringUTFChars((jstring)fileObject, &isCopy); + + apkPath = std::string( path ); + } + + return apkPath; +} +#endif + namespace EE { namespace Window { namespace Backend { namespace SDL2 { cWindowSDL::cWindowSDL( WindowSettings Settings, ContextSettings Context ) : @@ -30,6 +68,10 @@ cWindowSDL::cWindowSDL( WindowSettings Settings, ContextSettings Context ) : , mWMinfo( eeNew( SDL_SysWMinfo, () ) ) #endif +#if EE_PLATFORM == EE_PLATFORM_ANDROID + , + mZip( eeNew( cZip, () ) ) +#endif { Create( Settings, Context ); } @@ -42,6 +84,10 @@ cWindowSDL::~cWindowSDL() { #ifdef EE_USE_WMINFO eeSAFE_DELETE( mWMinfo ); #endif + +#if EE_PLATFORM == EE_PLATFORM_ANDROID + eeSAFE_DELETE( mZip ); +#endif } bool cWindowSDL::Create( WindowSettings Settings, ContextSettings Context ) { @@ -171,6 +217,17 @@ bool cWindowSDL::Create( WindowSettings Settings, ContextSettings Context ) { LogSuccessfulInit( GetVersion() ); + #if EE_PLATFORM == EE_PLATFORM_ANDROID + std::string apkPath( SDL_AndroidGetApkPath() ); + + cLog::instance()->Write( "Opening application APK in: " + apkPath ); + + if ( mZip->Open( apkPath ) ) + cLog::instance()->Write( "APK opened succesfully!" ); + else + cLog::instance()->Write( "Failed to open APK!" ); + #endif + return true; } @@ -546,6 +603,32 @@ bool cWindowSDL::IsScreenKeyboardShown() { return SDL_TRUE == SDL_IsScreenKeyboardShown( mSDLWindow ); } +#if EE_PLATFORM == EE_PLATFORM_ANDROID +void * cWindowSDL::GetJNIEnv() { + return SDL_AndroidGetJNIEnv(); +} + +void * cWindowSDL::GetActivity() { + return SDL_AndroidGetActivity(); +} + +int cWindowSDL::GetExternalStorageState() { + return SDL_AndroidGetExternalStorageState(); +} + +std::string cWindowSDL::GetInternalStoragePath() { + return std::string( SDL_AndroidGetInternalStoragePath() ); +} + +std::string cWindowSDL::GetExternalStoragePath() { + return std::string( SDL_AndroidGetExternalStoragePath() ); +} + +std::string cWindowSDL::GetApkPath() { + return SDL_AndroidGetApkPath(); +} +#endif + }}}} #endif diff --git a/src/eepp/window/backend/SDL2/cwindowsdl2.hpp b/src/eepp/window/backend/SDL2/cwindowsdl2.hpp index 8f243beea..8b2e7bb6a 100644 --- a/src/eepp/window/backend/SDL2/cwindowsdl2.hpp +++ b/src/eepp/window/backend/SDL2/cwindowsdl2.hpp @@ -14,6 +14,8 @@ class SDL_SysWMinfo; #define EE_USE_WMINFO #endif +namespace EE { namespace System { class cZip; } } + namespace EE { namespace Window { namespace Backend { namespace SDL2 { class EE_API cWindowSDL : public cWindow { @@ -71,6 +73,20 @@ class EE_API cWindowSDL : public cWindow { bool HasScreenKeyboardSupport(); bool IsScreenKeyboardShown(); + +#if EE_PLATFORM == EE_PLATFORM_ANDROID + void * GetJNIEnv(); + + void * GetActivity(); + + int GetExternalStorageState(); + + std::string GetInternalStoragePath(); + + std::string GetExternalStoragePath(); + + std::string GetApkPath(); +#endif protected: friend class cClipboardSDL; @@ -81,6 +97,10 @@ class EE_API cWindowSDL : public cWindow { SDL_SysWMinfo * mWMinfo; #endif + #if EE_PLATFORM == EE_PLATFORM_ANDROID + cZip * mZip; + #endif + eeVector2i mWinPos; void CreatePlatform(); diff --git a/src/eepp/window/cwindow.cpp b/src/eepp/window/cwindow.cpp index ae03231fe..c8a9c958e 100644 --- a/src/eepp/window/cwindow.cpp +++ b/src/eepp/window/cwindow.cpp @@ -518,4 +518,30 @@ bool cWindow::IsScreenKeyboardShown() { return false; } +#if EE_PLATFORM == EE_PLATFORM_ANDROID +void * cWindow::GetJNIEnv() { + return NULL; +} + +void * cWindow::GetActivity() { + return NULL; +} + +int cWindow::GetExternalStorageState() { + return 0; +} + +std::string cWindow::GetInternalStoragePath() { + return std::string(""); +} + +std::string cWindow::GetExternalStoragePath() { + return std::string(""); +} + +std::string cWindow::GetApkPath() { + return std::string(""); +} +#endif + }} diff --git a/src/examples/external_shader/external_shader.cpp b/src/examples/external_shader/external_shader.cpp index f45724230..8713bf832 100644 --- a/src/examples/external_shader/external_shader.cpp +++ b/src/examples/external_shader/external_shader.cpp @@ -239,6 +239,12 @@ EE_MAIN_FUNC int main (int argc, char * argv []) /// Draw the lines GLi->DrawArrays( DM_LINES, 0, ParticlesNum ); + /// Stop the simulation if the window is not visible + while ( !win->Visible() ) { + imp->Update(); /// To get the real state of the window you need to update the window input + Sys::Sleep( 100 ); /// Sleep 100 ms + } + win->Display(); }