diff options
Diffstat (limited to 'Source/3rdParty/SDL2/src/core')
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/SDL_android.c | 426 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/SDL_android.h | 29 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_dbus.c | 18 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_dbus.h | 9 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_evdev.c | 1 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.c | 171 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.h | 5 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_udev.c | 80 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/linux/SDL_udev.h | 32 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/windows/SDL_windows.c | 3 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp | 2 |
11 files changed, 616 insertions, 160 deletions
diff --git a/Source/3rdParty/SDL2/src/core/android/SDL_android.c b/Source/3rdParty/SDL2/src/core/android/SDL_android.c index c40c676..a56575e 100644 --- a/Source/3rdParty/SDL2/src/core/android/SDL_android.c +++ b/Source/3rdParty/SDL2/src/core/android/SDL_android.c @@ -61,6 +61,10 @@ #define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function) #define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function) +/* Audio encoding definitions */ +#define ENCODING_PCM_8BIT 3 +#define ENCODING_PCM_16BIT 2 +#define ENCODING_PCM_FLOAT 4 /* Java class SDLActivity */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)( @@ -76,7 +80,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEnv* env, jclass jcls, - jint width, jint height, jint format, jfloat rate); + jint surfaceWidth, jint surfaceHeight, + jint deviceWidth, jint deviceHeight, jint format, jfloat rate); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( JNIEnv* env, jclass jcls); @@ -102,7 +107,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y); + jint button, jint action, jfloat x, jfloat y, jboolean relative); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( JNIEnv* env, jclass jcls, @@ -134,11 +139,19 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)( JNIEnv* env, jclass cls); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( + JNIEnv* env, jclass cls, + jint orientation); + /* Java class SDLInputConnection */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( + JNIEnv* env, jclass cls, + jchar chUnicode); + JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); @@ -169,8 +182,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, - jint nbuttons, jint naxes, jint nhats, jint nballs); + jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id, + jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs); JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( JNIEnv* env, jclass jcls, @@ -190,6 +203,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( /* #define DEBUG_JNI */ static void Android_JNI_ThreadDestroyed(void*); +static void checkJNIReady(void); /******************************************************************************* This file links the Java side of Android with libsdl @@ -212,7 +226,11 @@ static jmethodID midSetActivityTitle; static jmethodID midSetWindowStyle; static jmethodID midSetOrientation; static jmethodID midGetContext; +static jmethodID midIsTablet; static jmethodID midIsAndroidTV; +static jmethodID midIsChromebook; +static jmethodID midIsDeXMode; +static jmethodID midManualBackButton; static jmethodID midInputGetInputDeviceIds; static jmethodID midSendMessage; static jmethodID midShowTextInput; @@ -223,18 +241,25 @@ static jmethodID midClipboardHasText; static jmethodID midOpenAPKExpansionInputStream; static jmethodID midGetManifestEnvironmentVariables; static jmethodID midGetDisplayDPI; +static jmethodID midCreateCustomCursor; +static jmethodID midSetCustomCursor; +static jmethodID midSetSystemCursor; +static jmethodID midSupportsRelativeMouse; +static jmethodID midSetRelativeMouseEnabled; /* audio manager */ static jclass mAudioManagerClass; /* method signatures */ static jmethodID midAudioOpen; -static jmethodID midAudioWriteShortBuffer; static jmethodID midAudioWriteByteBuffer; +static jmethodID midAudioWriteShortBuffer; +static jmethodID midAudioWriteFloatBuffer; static jmethodID midAudioClose; static jmethodID midCaptureOpen; -static jmethodID midCaptureReadShortBuffer; static jmethodID midCaptureReadByteBuffer; +static jmethodID midCaptureReadShortBuffer; +static jmethodID midCaptureReadFloatBuffer; static jmethodID midCaptureClose; /* controller manager */ @@ -244,6 +269,7 @@ static jclass mControllerManagerClass; static jmethodID midPollInputDevices; static jmethodID midPollHapticDevices; static jmethodID midHapticRun; +static jmethodID midHapticStop; /* static fields */ static jfieldID fidSeparateMouseAndTouch; @@ -309,8 +335,16 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c "setOrientation","(IIZLjava/lang/String;)V"); midGetContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getContext","()Landroid/content/Context;"); + midIsTablet = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "isTablet", "()Z"); midIsAndroidTV = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "isAndroidTV","()Z"); + midIsChromebook = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "isChromebook", "()Z"); + midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "isDeXMode", "()Z"); + midManualBackButton = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "manualBackButton", "()V"); midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "inputGetInputDeviceIds", "(I)[I"); midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, @@ -332,13 +366,21 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c "getManifestEnvironmentVariables", "()Z"); midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); - midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); + midCreateCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "createCustomCursor", "([IIIII)I"); + midSetCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setCustomCursor", "(I)Z"); + midSetSystemCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setSystemCursor", "(I)Z"); + + midSupportsRelativeMouse = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "supportsRelativeMouse", "()Z"); + midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setRelativeMouseEnabled", "(Z)Z"); + if (!midGetNativeSurface || - !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsAndroidTV || !midInputGetInputDeviceIds || + !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInputGetInputDeviceIds || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || - !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables|| !midGetDisplayDPI) { + !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI || + !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled || + !midIsChromebook || !midIsDeXMode || !midManualBackButton) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); } @@ -361,24 +403,28 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jc mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioOpen", "(IZZI)I"); - midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioWriteShortBuffer", "([S)V"); + "audioOpen", "(IIII)[I"); midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "audioWriteByteBuffer", "([B)V"); + midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioWriteShortBuffer", "([S)V"); + midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioWriteFloatBuffer", "([F)V"); midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "audioClose", "()V"); midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureOpen", "(IZZI)I"); - midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureReadShortBuffer", "([SZ)I"); + "captureOpen", "(IIII)[I"); midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "captureReadByteBuffer", "([BZ)I"); + midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureReadShortBuffer", "([SZ)I"); + midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureReadFloatBuffer", "([FZ)I"); midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "captureClose", "()V"); - if (!midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose || - !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose) { + if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose || + !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); } @@ -399,9 +445,11 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEn midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, "pollHapticDevices", "()V"); midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, - "hapticRun", "(II)V"); + "hapticRun", "(IFI)V"); + midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, + "hapticStop", "(I)V"); - if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun) { + if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?"); } @@ -503,9 +551,18 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( /* Resize */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEnv* env, jclass jcls, - jint width, jint height, jint format, jfloat rate) + jint surfaceWidth, jint surfaceHeight, + jint deviceWidth, jint deviceHeight, jint format, jfloat rate) { - Android_SetScreenResolution(width, height, format, rate); + Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate); +} + +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( + JNIEnv *env, jclass jcls, + jint orientation) +{ + SDL_VideoDisplay *display = SDL_GetDisplay(0); + SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation); } /* Paddown */ @@ -543,14 +600,15 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, - jint nbuttons, jint naxes, jint nhats, jint nballs) + jint device_id, jstring device_name, jstring device_desc, + jint vendor_id, jint product_id, jboolean is_accelerometer, + jint button_mask, jint naxes, jint nhats, jint nballs) { int retval; const char *name = (*env)->GetStringUTFChars(env, device_name, NULL); const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL); - retval = Android_AddJoystick(device_id, name, desc, (SDL_bool) is_accelerometer, nbuttons, naxes, nhats, nballs); + retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ? SDL_TRUE : SDL_FALSE, button_mask, naxes, nhats, nballs); (*env)->ReleaseStringUTFChars(env, device_name, name); (*env)->ReleaseStringUTFChars(env, device_desc, desc); @@ -675,9 +733,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( /* Mouse */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y) + jint button, jint action, jfloat x, jfloat y, jboolean relative) { - Android_OnMouse(button, action, x, y); + Android_OnMouse(button, action, x, y, relative); } /* Accelerometer */ @@ -995,17 +1053,19 @@ int Android_JNI_SetupThread(void) /* * Audio support */ -static jboolean audioBuffer16Bit = JNI_FALSE; +static int audioBufferFormat = 0; static jobject audioBuffer = NULL; static void* audioBufferPinned = NULL; -static jboolean captureBuffer16Bit = JNI_FALSE; +static int captureBufferFormat = 0; static jobject captureBuffer = NULL; -int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) +int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec) { - jboolean audioBufferStereo; - int audioBufferFrames; + int audioformat; + int numBufferFrames; jobject jbufobj = NULL; + jobject result; + int *resultElements; jboolean isCopy; JNIEnv *env = Android_JNI_GetEnv(); @@ -1015,74 +1075,123 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int } Android_JNI_SetupThread(); - audioBufferStereo = channelCount > 1; + switch (spec->format) { + case AUDIO_U8: + audioformat = ENCODING_PCM_8BIT; + break; + case AUDIO_S16: + audioformat = ENCODING_PCM_16BIT; + break; + case AUDIO_F32: + audioformat = ENCODING_PCM_FLOAT; + break; + default: + return SDL_SetError("Unsupported audio format: 0x%x", spec->format); + } if (iscapture) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); - captureBuffer16Bit = is16Bit; - if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { - /* Error during audio initialization */ - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!"); - return 0; - } + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples); } else { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); - audioBuffer16Bit = is16Bit; - if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { - /* Error during audio initialization */ - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!"); - return 0; - } + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples); + } + if (result == NULL) { + /* Error during audio initialization, error printed from Java */ + return SDL_SetError("Java-side initialization failed"); } + if ((*env)->GetArrayLength(env, (jintArray)result) != 4) { + return SDL_SetError("Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result)); + } + isCopy = JNI_FALSE; + resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy); + spec->freq = resultElements[0]; + audioformat = resultElements[1]; + switch (audioformat) { + case ENCODING_PCM_8BIT: + spec->format = AUDIO_U8; + break; + case ENCODING_PCM_16BIT: + spec->format = AUDIO_S16; + break; + case ENCODING_PCM_FLOAT: + spec->format = AUDIO_F32; + break; + default: + return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); + } + spec->channels = resultElements[2]; + spec->samples = resultElements[3]; + (*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT); + (*env)->DeleteLocalRef(env, result); + /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */ - - if (is16Bit) { - jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); + switch (audioformat) { + case ENCODING_PCM_8BIT: + { + jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); + } } - } - else { - jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); + break; + case ENCODING_PCM_16BIT: + { + jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); + } } + break; + case ENCODING_PCM_FLOAT: + { + jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); + } + } + break; + default: + return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); } if (jbufobj == NULL) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!"); - return 0; + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer"); + return SDL_OutOfMemory(); } if (iscapture) { + captureBufferFormat = audioformat; captureBuffer = jbufobj; } else { + audioBufferFormat = audioformat; audioBuffer = jbufobj; } + numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj); - isCopy = JNI_FALSE; + if (!iscapture) { + isCopy = JNI_FALSE; - if (is16Bit) { - if (!iscapture) { - audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); - } - audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer); - } else { - if (!iscapture) { + switch (audioformat) { + case ENCODING_PCM_8BIT: audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy); + break; + case ENCODING_PCM_16BIT: + audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); + break; + case ENCODING_PCM_FLOAT: + audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy); + break; + default: + return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); } - audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer); - } - - if (audioBufferStereo) { - audioBufferFrames /= 2; } - - return audioBufferFrames; + return 0; } int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi) @@ -1126,12 +1235,22 @@ void Android_JNI_WriteAudioBuffer(void) { JNIEnv *mAudioEnv = Android_JNI_GetEnv(); - if (audioBuffer16Bit) { - (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); - } else { + switch (audioBufferFormat) { + case ENCODING_PCM_8BIT: (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT); (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); + break; + case ENCODING_PCM_16BIT: + (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); + (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); + break; + case ENCODING_PCM_FLOAT: + (*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT); + (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer); + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled audio buffer format"); + break; } /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ @@ -1143,44 +1262,84 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) jboolean isCopy = JNI_FALSE; jint br; - if (captureBuffer16Bit) { - SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2)); + switch (captureBufferFormat) { + case ENCODING_PCM_8BIT: + SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); + br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); + if (br > 0) { + jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); + SDL_memcpy(buffer, ptr, br); + (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); + } + break; + case ENCODING_PCM_16BIT: + SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16))); br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE); if (br > 0) { jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy); - br *= 2; + br *= sizeof(Sint16); SDL_memcpy(buffer, ptr, br); (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT); } - } else { - SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); - br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); + break; + case ENCODING_PCM_FLOAT: + SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float))); + br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE); if (br > 0) { - jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); + jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy); + br *= sizeof(float); SDL_memcpy(buffer, ptr, br); - (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); + (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT); } + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled capture buffer format"); + break; } - - return (int) br; + return br; } void Android_JNI_FlushCapturedAudio(void) { JNIEnv *env = Android_JNI_GetEnv(); #if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ - if (captureBuffer16Bit) { - const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } - } else { - const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + switch (captureBufferFormat) { + case ENCODING_PCM_8BIT: + { + const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + break; + case ENCODING_PCM_16BIT: + { + const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + break; + case ENCODING_PCM_FLOAT: + { + const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format"); + break; } #else - if (captureBuffer16Bit) { - (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); - } else { + switch (captureBufferFormat) { + case ENCODING_PCM_8BIT: (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); + break; + case ENCODING_PCM_16BIT: + (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); + break; + case ENCODING_PCM_FLOAT: + (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE); + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format"); + break; } #endif } @@ -1846,12 +2005,17 @@ void Android_JNI_PollHapticDevices(void) (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices); } -void Android_JNI_HapticRun(int device_id, int length) +void Android_JNI_HapticRun(int device_id, float intensity, int length) { JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, length); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length); } +void Android_JNI_HapticStop(int device_id) +{ + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id); +} /* See SDLActivity.java for constants. */ #define COMMAND_SET_KEEP_SCREEN_ON 5 @@ -2006,12 +2170,36 @@ void *SDL_AndroidGetActivity(void) return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); } +SDL_bool SDL_IsAndroidTablet(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet); +} + SDL_bool SDL_IsAndroidTV(void) { JNIEnv *env = Android_JNI_GetEnv(); return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV); } +SDL_bool SDL_IsChromebook(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook); +} + +SDL_bool SDL_IsDeXMode(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode); +} + +void SDL_AndroidBackButton(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton); +} + const char * SDL_AndroidGetInternalStoragePath(void) { static char *s_AndroidInternalFilesPath = NULL; @@ -2166,6 +2354,48 @@ void Android_JNI_GetManifestEnvironmentVariables(void) } } +int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + int custom_cursor = 0; + jintArray pixels; + pixels = (*mEnv)->NewIntArray(mEnv, surface->w * surface->h); + if (pixels) { + (*mEnv)->SetIntArrayRegion(mEnv, pixels, 0, surface->w * surface->h, (int *)surface->pixels); + custom_cursor = (*mEnv)->CallStaticIntMethod(mEnv, mActivityClass, midCreateCustomCursor, pixels, surface->w, surface->h, hot_x, hot_y); + (*mEnv)->DeleteLocalRef(mEnv, pixels); + } else { + SDL_OutOfMemory(); + } + return custom_cursor; +} + + +SDL_bool Android_JNI_SetCustomCursor(int cursorID) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetCustomCursor, cursorID); +} + +SDL_bool Android_JNI_SetSystemCursor(int cursorID) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetSystemCursor, cursorID); +} + +SDL_bool Android_JNI_SupportsRelativeMouse() +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSupportsRelativeMouse); +} + +SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1)); +} + + #endif /* __ANDROID__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/core/android/SDL_android.h b/Source/3rdParty/SDL2/src/core/android/SDL_android.h index c800dc6..b2ff32e 100644 --- a/Source/3rdParty/SDL2/src/core/android/SDL_android.h +++ b/Source/3rdParty/SDL2/src/core/android/SDL_android.h @@ -19,6 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" +#include "SDL_system.h" /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus @@ -30,6 +31,7 @@ extern "C" { #include <EGL/eglplatform.h> #include <android/native_window_jni.h> +#include "SDL_audio.h" #include "SDL_rect.h" /* Interface from the SDL library into the Android Java activity */ @@ -46,13 +48,17 @@ extern ANativeWindow* Android_JNI_GetNativeWindow(void); extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi); /* Audio support */ -extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); +extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec); extern void* Android_JNI_GetAudioBuffer(void); extern void Android_JNI_WriteAudioBuffer(void); extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); extern void Android_JNI_FlushCapturedAudio(void); extern void Android_JNI_CloseAudioDevice(const int iscapture); +/* Detecting device type */ +extern SDL_bool Android_IsDeXMode(); +extern SDL_bool Android_IsChromebook(); + #include "SDL_rwops.h" int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode); @@ -78,14 +84,16 @@ void Android_JNI_PollInputDevices(void); /* Haptic support */ void Android_JNI_PollHapticDevices(void); -void Android_JNI_HapticRun(int device_id, int length); +void Android_JNI_HapticRun(int device_id, float intensity, int length); +void Android_JNI_HapticStop(int device_id); /* Video */ void Android_JNI_SuspendScreenSaver(SDL_bool suspend); /* Touch support */ -int Android_JNI_GetTouchDeviceIds(int **ids); +int Android_JNI_InitTouch(void); void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value); +int Android_JNI_GetTouchDeviceIds(int **ids); /* Threads */ #include <jni.h> @@ -102,6 +110,21 @@ JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls); #include "SDL_messagebox.h" int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); +/* Cursor support */ +int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y); +SDL_bool Android_JNI_SetCustomCursor(int cursorID); +SDL_bool Android_JNI_SetSystemCursor(int cursorID); + +/* Relative mouse support */ +SDL_bool Android_JNI_SupportsRelativeMouse(void); +SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled); + + +SDL_bool SDL_IsAndroidTablet(void); +SDL_bool SDL_IsAndroidTV(void); +SDL_bool SDL_IsChromebook(void); +SDL_bool SDL_IsDeXMode(void); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.c b/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.c index ff4f0fe..e0d9972 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.c +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.c @@ -173,17 +173,29 @@ SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, const char * if (conn) { DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method); if (msg) { - int firstarg = va_arg(ap, int); + int firstarg; + va_list ap_reply; + va_copy(ap_reply, ap); /* copy the arg list so we don't compete with D-Bus for it */ + firstarg = va_arg(ap, int); if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) { DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); if (reply) { - firstarg = va_arg(ap, int); - if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap)) { + /* skip any input args, get to output args. */ + while ((firstarg = va_arg(ap_reply, int)) != DBUS_TYPE_INVALID) { + /* we assume D-Bus already validated all this. */ + { void *dumpptr = va_arg(ap_reply, void*); (void) dumpptr; } + if (firstarg == DBUS_TYPE_ARRAY) { + { const int dumpint = va_arg(ap_reply, int); (void) dumpint; } + } + } + firstarg = va_arg(ap_reply, int); + if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap_reply)) { retval = SDL_TRUE; } dbus.message_unref(reply); } } + va_end(ap_reply); dbus.message_unref(msg); } } diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.h b/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.h index 062543d..aa787f2 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.h +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_dbus.h @@ -39,9 +39,8 @@ typedef struct SDL_DBusContext { void (*bus_add_match)(DBusConnection *, const char *, DBusError *); DBusConnection * (*connection_open_private)(const char *, DBusError *); void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t); - dbus_bool_t (*connection_get_is_connected)(DBusConnection *); - dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, - void *, DBusFreeFunction); + dbus_bool_t (*connection_get_is_connected)(DBusConnection *); + dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction); dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *, const DBusObjectPathVTable *, void *, DBusError *); dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *); @@ -51,7 +50,7 @@ typedef struct SDL_DBusContext { void (*connection_flush)(DBusConnection *); dbus_bool_t (*connection_read_write)(DBusConnection *, int); DBusDispatchStatus (*connection_dispatch)(DBusConnection *); - dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); + dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *); dbus_bool_t (*message_append_args)(DBusMessage *, int, ...); dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list); @@ -61,7 +60,7 @@ typedef struct SDL_DBusContext { dbus_bool_t (*message_iter_next)(DBusMessageIter *); void (*message_iter_get_basic)(DBusMessageIter *, void *); int (*message_iter_get_arg_type)(DBusMessageIter *); - void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); + void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); void (*message_unref)(DBusMessage *); void (*error_init)(DBusError *); dbus_bool_t (*error_is_set)(const DBusError *); diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_evdev.c b/Source/3rdParty/SDL2/src/core/linux/SDL_evdev.c index a506926..5443c21 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_evdev.c +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_evdev.c @@ -101,6 +101,7 @@ typedef struct SDL_EVDEV_PrivateData SDL_EVDEV_keyboard_state *kbd; } SDL_EVDEV_PrivateData; +#undef _THIS #define _THIS SDL_EVDEV_PrivateData *_this static _THIS = NULL; diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.c b/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.c index 250e644..00a3a54 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.c +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.c @@ -21,6 +21,7 @@ #include "../../SDL_internal.h" #include "SDL_evdev_kbd.h" +#include "SDL_hints.h" #ifdef SDL_INPUT_LINUXKD @@ -34,6 +35,8 @@ #include <linux/vt.h> #include <linux/tiocl.h> /* for TIOCL_GETSHIFTSTATE */ +#include <signal.h> + #include "../../events/SDL_events_c.h" #include "SDL_evdev_kbd_default_accents.h" #include "SDL_evdev_kbd_default_keymap.h" @@ -191,6 +194,151 @@ static int SDL_EVDEV_kbd_load_keymaps(SDL_EVDEV_keyboard_state *kbd) return 0; } +static SDL_EVDEV_keyboard_state * kbd_cleanup_state = NULL; +static int kbd_cleanup_sigactions_installed = 0; +static int kbd_cleanup_atexit_installed = 0; + +static struct sigaction old_sigaction[NSIG]; + +static int fatal_signals[] = +{ + /* Handlers for SIGTERM and SIGINT are installed in SDL_QuitInit. */ + SIGHUP, SIGQUIT, SIGILL, SIGABRT, + SIGFPE, SIGSEGV, SIGPIPE, SIGBUS, + SIGSYS +}; + +static void kbd_cleanup(void) +{ + SDL_EVDEV_keyboard_state* kbd = kbd_cleanup_state; + if (kbd == NULL) { + return; + } + kbd_cleanup_state = NULL; + + fprintf(stderr, "(SDL restoring keyboard) "); + ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode); +} + +void +SDL_EVDEV_kbd_reraise_signal(int sig) +{ + raise(sig); +} + +siginfo_t* SDL_EVDEV_kdb_cleanup_siginfo = NULL; +void* SDL_EVDEV_kdb_cleanup_ucontext = NULL; + +static void kbd_cleanup_signal_action(int signum, siginfo_t* info, void* ucontext) +{ + struct sigaction* old_action_p = &(old_sigaction[signum]); + sigset_t sigset; + + /* Restore original signal handler before going any further. */ + sigaction(signum, old_action_p, NULL); + + /* Unmask current signal. */ + sigemptyset(&sigset); + sigaddset(&sigset, signum); + sigprocmask(SIG_UNBLOCK, &sigset, NULL); + + /* Save original signal info and context for archeologists. */ + SDL_EVDEV_kdb_cleanup_siginfo = info; + SDL_EVDEV_kdb_cleanup_ucontext = ucontext; + + /* Restore keyboard. */ + kbd_cleanup(); + + /* Reraise signal. */ + SDL_EVDEV_kbd_reraise_signal(signum); +} + +static void kbd_unregister_emerg_cleanup() +{ + int tabidx, signum; + + kbd_cleanup_state = NULL; + + if (!kbd_cleanup_sigactions_installed) { + return; + } + kbd_cleanup_sigactions_installed = 0; + + for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) { + struct sigaction* old_action_p; + struct sigaction cur_action; + signum = fatal_signals[tabidx]; + old_action_p = &(old_sigaction[signum]); + + /* Examine current signal action */ + if (sigaction(signum, NULL, &cur_action)) + continue; + + /* Check if action installed and not modifed */ + if (!(cur_action.sa_flags & SA_SIGINFO) + || cur_action.sa_sigaction != &kbd_cleanup_signal_action) + continue; + + /* Restore original action */ + sigaction(signum, old_action_p, NULL); + } +} + +static void kbd_cleanup_atexit(void) +{ + /* Restore keyboard. */ + kbd_cleanup(); + + /* Try to restore signal handlers in case shared library is being unloaded */ + kbd_unregister_emerg_cleanup(); +} + +static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state * kbd) +{ + int tabidx, signum; + + if (kbd_cleanup_state != NULL) { + return; + } + kbd_cleanup_state = kbd; + + if (!kbd_cleanup_atexit_installed) { + /* Since glibc 2.2.3, atexit() (and on_exit(3)) can be used within a shared library to establish + * functions that are called when the shared library is unloaded. + * -- man atexit(3) + */ + atexit(kbd_cleanup_atexit); + kbd_cleanup_atexit_installed = 1; + } + + if (kbd_cleanup_sigactions_installed) { + return; + } + kbd_cleanup_sigactions_installed = 1; + + for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) { + struct sigaction* old_action_p; + struct sigaction new_action; + signum = fatal_signals[tabidx]; + old_action_p = &(old_sigaction[signum]); + if (sigaction(signum, NULL, old_action_p)) + continue; + + /* Skip SIGHUP and SIGPIPE if handler is already installed + * - assume the handler will do the cleanup + */ + if ((signum == SIGHUP || signum == SIGPIPE) + && (old_action_p->sa_handler != SIG_DFL + || (void (*)(int))old_action_p->sa_sigaction != SIG_DFL)) + continue; + + new_action = *old_action_p; + new_action.sa_flags |= SA_SIGINFO; + new_action.sa_sigaction = &kbd_cleanup_signal_action; + sigaction(signum, &new_action, NULL); + } +} + SDL_EVDEV_keyboard_state * SDL_EVDEV_kbd_init(void) { @@ -238,10 +386,20 @@ SDL_EVDEV_kbd_init(void) kbd->key_maps = default_key_maps; } - /* Mute the keyboard so keystrokes only generate evdev events - * and do not leak through to the console - */ - ioctl(kbd->console_fd, KDSKBMODE, K_OFF); + /* Allow inhibiting keyboard mute with env. variable for debugging etc. */ + if (getenv("SDL_INPUT_LINUX_KEEP_KBD") == NULL) { + /* Mute the keyboard so keystrokes only generate evdev events + * and do not leak through to the console + */ + ioctl(kbd->console_fd, KDSKBMODE, K_OFF); + + /* Make sure to restore keyboard if application fails to call + * SDL_Quit before exit or fatal signal is raised. + */ + if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) { + kbd_register_emerg_cleanup(kbd); + } + } } #ifdef DUMP_ACCENTS @@ -260,6 +418,8 @@ SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd) return; } + kbd_unregister_emerg_cleanup(); + if (kbd->console_fd >= 0) { /* Restore the original keyboard mode */ ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode); @@ -609,7 +769,10 @@ SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode, int d shift_final = (kbd->shift_state | kbd->slockstate) ^ kbd->lockstate; key_map = kbd->key_maps[shift_final]; if (!key_map) { + /* Unsupported shift state (e.g. ctrl = 4, alt = 8), just reset to the default state */ + kbd->shift_state = 0; kbd->slockstate = 0; + kbd->lockstate = 0; return; } diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.h b/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.h index 831ba3a..5e51cdd 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.h +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_evdev_kbd.h @@ -19,6 +19,9 @@ 3. This notice may not be removed or altered from any source distribution. */ +#ifndef SDL_evdev_kbd_h_ +#define SDL_evdev_kbd_h_ + struct SDL_EVDEV_keyboard_state; typedef struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state; @@ -26,4 +29,6 @@ extern SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void); extern void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down); extern void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state); +#endif /* SDL_evdev_kbd_h_ */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_udev.c b/Source/3rdParty/SDL2/src/core/linux/SDL_udev.c index dfbeb79..751e2ca 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_udev.c +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_udev.c @@ -63,7 +63,7 @@ SDL_UDEV_load_syms(void) { /* cast funcs to char* first, to please GCC's strict aliasing rules. */ #define SDL_UDEV_SYM(x) \ - if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1 + if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1 SDL_UDEV_SYM(udev_device_get_action); SDL_UDEV_SYM(udev_device_get_devnode); @@ -100,7 +100,7 @@ static SDL_bool SDL_UDEV_hotplug_update_available(void) { if (_this->udev_mon != NULL) { - const int fd = _this->udev_monitor_get_fd(_this->udev_mon); + const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon); if (SDL_IOReady(fd, SDL_FALSE, 0)) { return SDL_TRUE; } @@ -130,21 +130,21 @@ SDL_UDEV_Init(void) * Listen for input devices (mouse, keyboard, joystick, etc) and sound devices */ - _this->udev = _this->udev_new(); + _this->udev = _this->syms.udev_new(); if (_this->udev == NULL) { SDL_UDEV_Quit(); return SDL_SetError("udev_new() failed"); } - _this->udev_mon = _this->udev_monitor_new_from_netlink(_this->udev, "udev"); + _this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev"); if (_this->udev_mon == NULL) { SDL_UDEV_Quit(); return SDL_SetError("udev_monitor_new_from_netlink() failed"); } - _this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL); - _this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL); - _this->udev_monitor_enable_receiving(_this->udev_mon); + _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL); + _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL); + _this->syms.udev_monitor_enable_receiving(_this->udev_mon); /* Do an initial scan of existing devices */ SDL_UDEV_Scan(); @@ -170,11 +170,11 @@ SDL_UDEV_Quit(void) if (_this->ref_count < 1) { if (_this->udev_mon != NULL) { - _this->udev_monitor_unref(_this->udev_mon); + _this->syms.udev_monitor_unref(_this->udev_mon); _this->udev_mon = NULL; } if (_this->udev != NULL) { - _this->udev_unref(_this->udev); + _this->syms.udev_unref(_this->udev); _this->udev = NULL; } @@ -202,28 +202,28 @@ SDL_UDEV_Scan(void) return; } - enumerate = _this->udev_enumerate_new(_this->udev); + enumerate = _this->syms.udev_enumerate_new(_this->udev); if (enumerate == NULL) { SDL_UDEV_Quit(); SDL_SetError("udev_enumerate_new() failed"); return; } - _this->udev_enumerate_add_match_subsystem(enumerate, "input"); - _this->udev_enumerate_add_match_subsystem(enumerate, "sound"); + _this->syms.udev_enumerate_add_match_subsystem(enumerate, "input"); + _this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound"); - _this->udev_enumerate_scan_devices(enumerate); - devs = _this->udev_enumerate_get_list_entry(enumerate); - for (item = devs; item; item = _this->udev_list_entry_get_next(item)) { - const char *path = _this->udev_list_entry_get_name(item); - struct udev_device *dev = _this->udev_device_new_from_syspath(_this->udev, path); + _this->syms.udev_enumerate_scan_devices(enumerate); + devs = _this->syms.udev_enumerate_get_list_entry(enumerate); + for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) { + const char *path = _this->syms.udev_list_entry_get_name(item); + struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path); if (dev != NULL) { device_event(SDL_UDEV_DEVICEADDED, dev); - _this->udev_device_unref(dev); + _this->syms.udev_device_unref(dev); } } - _this->udev_enumerate_unref(enumerate); + _this->syms.udev_enumerate_unref(enumerate); } @@ -305,7 +305,7 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch unsigned long v; SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask)); - value = _this->udev_device_get_sysattr_value(pdev, attr); + value = _this->syms.udev_device_get_sysattr_value(pdev, attr); if (!value) { return; } @@ -340,8 +340,8 @@ guess_device_class(struct udev_device *dev) /* walk up the parental chain until we find the real input device; the * argument is very likely a subdevice of this, like eventN */ pdev = dev; - while (pdev && !_this->udev_device_get_sysattr_value(pdev, "capabilities/ev")) { - pdev = _this->udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL); + while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) { + pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL); } if (!pdev) { return 0; @@ -405,28 +405,28 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) const char *path; SDL_UDEV_CallbackList *item; - path = _this->udev_device_get_devnode(dev); + path = _this->syms.udev_device_get_devnode(dev); if (path == NULL) { return; } - subsystem = _this->udev_device_get_subsystem(dev); + subsystem = _this->syms.udev_device_get_subsystem(dev); if (SDL_strcmp(subsystem, "sound") == 0) { devclass = SDL_UDEV_DEVICE_SOUND; } else if (SDL_strcmp(subsystem, "input") == 0) { /* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */ - val = _this->udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); if (val != NULL && SDL_strcmp(val, "1") == 0 ) { devclass |= SDL_UDEV_DEVICE_JOYSTICK; } - val = _this->udev_device_get_property_value(dev, "ID_INPUT_MOUSE"); + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE"); if (val != NULL && SDL_strcmp(val, "1") == 0 ) { devclass |= SDL_UDEV_DEVICE_MOUSE; } - val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"); + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"); if (val != NULL && SDL_strcmp(val, "1") == 0 ) { devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; } @@ -437,14 +437,14 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183 */ - val = _this->udev_device_get_property_value(dev, "ID_INPUT_KEY"); + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY"); if (val != NULL && SDL_strcmp(val, "1") == 0 ) { devclass |= SDL_UDEV_DEVICE_KEYBOARD; } if (devclass == 0) { /* Fall back to old style input classes */ - val = _this->udev_device_get_property_value(dev, "ID_CLASS"); + val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS"); if (val != NULL) { if (SDL_strcmp(val, "joystick") == 0) { devclass = SDL_UDEV_DEVICE_JOYSTICK; @@ -481,11 +481,11 @@ SDL_UDEV_Poll(void) } while (SDL_UDEV_hotplug_update_available()) { - dev = _this->udev_monitor_receive_device(_this->udev_mon); + dev = _this->syms.udev_monitor_receive_device(_this->udev_mon); if (dev == NULL) { break; } - action = _this->udev_device_get_action(dev); + action = _this->syms.udev_device_get_action(dev); if (SDL_strcmp(action, "add") == 0) { /* Wait for the device to finish initialization */ @@ -496,7 +496,7 @@ SDL_UDEV_Poll(void) device_event(SDL_UDEV_DEVICEREMOVED, dev); } - _this->udev_device_unref(dev); + _this->syms.udev_device_unref(dev); } } @@ -547,6 +547,22 @@ SDL_UDEV_DelCallback(SDL_UDEV_Callback cb) } +const SDL_UDEV_Symbols * +SDL_UDEV_GetUdevSyms(void) +{ + if (SDL_UDEV_Init() < 0) { + SDL_SetError("Could not initialize UDEV"); + return NULL; + } + + return &_this->syms; +} + +void +SDL_UDEV_ReleaseUdevSyms(void) +{ + SDL_UDEV_Quit(); +} #endif /* SDL_USE_LIBUDEV */ diff --git a/Source/3rdParty/SDL2/src/core/linux/SDL_udev.h b/Source/3rdParty/SDL2/src/core/linux/SDL_udev.h index edf5187..8be7434 100644 --- a/Source/3rdParty/SDL2/src/core/linux/SDL_udev.h +++ b/Source/3rdParty/SDL2/src/core/linux/SDL_udev.h @@ -64,22 +64,13 @@ typedef struct SDL_UDEV_CallbackList { struct SDL_UDEV_CallbackList *next; } SDL_UDEV_CallbackList; -typedef struct SDL_UDEV_PrivateData -{ - const char *udev_library; - void *udev_handle; - struct udev *udev; - struct udev_monitor *udev_mon; - int ref_count; - SDL_UDEV_CallbackList *first, *last; - - /* Function pointers */ +typedef struct SDL_UDEV_Symbols { const char *(*udev_device_get_action)(struct udev_device *); const char *(*udev_device_get_devnode)(struct udev_device *); const char *(*udev_device_get_subsystem)(struct udev_device *); - struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype); + struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype); const char *(*udev_device_get_property_value)(struct udev_device *, const char *); - const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr); + const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr); struct udev_device *(*udev_device_new_from_syspath)(struct udev *, const char *); void (*udev_device_unref)(struct udev_device *); int (*udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *); @@ -100,6 +91,19 @@ typedef struct SDL_UDEV_PrivateData void (*udev_unref)(struct udev *); struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum); dev_t (*udev_device_get_devnum) (struct udev_device *udev_device); +} SDL_UDEV_Symbols; + +typedef struct SDL_UDEV_PrivateData +{ + const char *udev_library; + void *udev_handle; + struct udev *udev; + struct udev_monitor *udev_mon; + int ref_count; + SDL_UDEV_CallbackList *first, *last; + + /* Function pointers */ + SDL_UDEV_Symbols syms; } SDL_UDEV_PrivateData; extern int SDL_UDEV_Init(void); @@ -110,8 +114,8 @@ extern void SDL_UDEV_Poll(void); extern void SDL_UDEV_Scan(void); extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb); extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb); - - +extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void); +extern void SDL_UDEV_ReleaseUdevSyms(void); #endif /* HAVE_LIBUDEV_H */ diff --git a/Source/3rdParty/SDL2/src/core/windows/SDL_windows.c b/Source/3rdParty/SDL2/src/core/windows/SDL_windows.c index 6624043..4da7d07 100644 --- a/Source/3rdParty/SDL2/src/core/windows/SDL_windows.c +++ b/Source/3rdParty/SDL2/src/core/windows/SDL_windows.c @@ -31,6 +31,9 @@ #ifndef _WIN32_WINNT_VISTA #define _WIN32_WINNT_VISTA 0x0600 #endif +#ifndef _WIN32_WINNT_WIN7 +#define _WIN32_WINNT_WIN7 0x0601 +#endif /* Sets an error message based on an HRESULT */ diff --git a/Source/3rdParty/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp b/Source/3rdParty/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp index 9789d03..7e2aac8 100644 --- a/Source/3rdParty/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp +++ b/Source/3rdParty/SDL2/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -44,7 +44,7 @@ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; #if WINAPI_FAMILY == WINAPI_FAMILY_APP extern "C" ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; -static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; +static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; #endif |