From 221b349400f0a6f16e9e7e44ebd847c8b75336b0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 13 Jan 2011 15:10:17 -0800 Subject: [PATCH] The window is changed to reflect the actual screen dimensions, for now. Implemented SDL_SetWindowTitle(), which turned out to be fairly complex --- .../src/org/libsdl/app/SDLActivity.java | 29 +++++++- src/SDL_android.cpp | 72 +++++++++++-------- src/SDL_android.h | 1 + src/main/android/SDL_android_main.cpp | 6 +- src/video/android/SDL_androidvideo.c | 24 ++++--- src/video/android/SDL_androidvideo.h | 6 ++ src/video/android/SDL_androidwindow.c | 52 ++++++++++++++ src/video/android/SDL_androidwindow.h | 33 +++++++++ 8 files changed, 180 insertions(+), 43 deletions(-) create mode 100644 src/video/android/SDL_androidwindow.c create mode 100644 src/video/android/SDL_androidwindow.h diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index e198156f3..bb9cb22d6 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -67,6 +67,25 @@ protected void onResume() { super.onResume(); } + // Messages from the SDLMain thread + static int COMMAND_CHANGE_TITLE = 1; + + // Handler for the messages + Handler commandHandler = new Handler() { + public void handleMessage(Message msg) { + if (msg.arg1 == COMMAND_CHANGE_TITLE) { + setTitle((String)msg.obj); + } + } + }; + + // Send a message from the SDLMain thread + void sendCommand(int command, Object data) { + Message msg = commandHandler.obtainMessage(); + msg.arg1 = command; + msg.obj = data; + commandHandler.sendMessage(msg); + } // C functions we call public static native void nativeInit(); @@ -81,7 +100,8 @@ public static native void onNativeTouch(int action, float x, // Java functions called from C - private static void createGLContext() { + + public static void createGLContext() { mSurface.initEGL(); } @@ -89,6 +109,11 @@ public static void flipBuffers() { mSurface.flipEGL(); } + public static void setActivityTitle(String title) { + // Called from SDLMain() thread and can't directly affect the view + mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); + } + // Audio private static Object buf; @@ -177,7 +202,7 @@ public static void audioQuit() { } mAudioThread = null; - Log.v("SDL", "Finished waiting for audio thread"); + //Log.v("SDL", "Finished waiting for audio thread"); } if (mAudioTrack != null) { diff --git a/src/SDL_android.cpp b/src/SDL_android.cpp index 42928c6f8..32d6adfab 100644 --- a/src/SDL_android.cpp +++ b/src/SDL_android.cpp @@ -42,12 +42,11 @@ extern void Android_RunAudioThread(); /******************************************************************************* Globals *******************************************************************************/ -static JavaVM* mVM = NULL; static JNIEnv* mEnv = NULL; static JNIEnv* mAudioEnv = NULL; // Main activity -static jclass mActivityInstance; +static jclass mActivityClass; // method signatures static jmethodID midCreateGLContext; @@ -68,26 +67,29 @@ float fLastAccelerometer[3]; // Library init extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) { - mVM = vm; - return JNI_VERSION_1_4; } // Called before SDL_main() to initialize JNI bindings -extern "C" void SDL_Android_Init(JNIEnv* env) +extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls) { - mEnv = env; - __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()"); - jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity"); - mActivityInstance = cls; - midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V"); - midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V"); - midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;"); - midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V"); - midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V"); - midAudioQuit = mEnv->GetStaticMethodID(cls, "audioQuit", "()V"); + mEnv = env; + mActivityClass = cls; + + midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass, + "createGLContext","()V"); + midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass, + "flipBuffers","()V"); + midAudioInit = mEnv->GetStaticMethodID(mActivityClass, + "audioInit", "(IZZI)Ljava/lang/Object;"); + midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass, + "audioWriteShortBuffer", "([S)V"); + midAudioWriteByteBuffer = mEnv->GetStaticMethodID(mActivityClass, + "audioWriteByteBuffer", "([B)V"); + midAudioQuit = mEnv->GetStaticMethodID(mActivityClass, + "audioQuit", "()V"); if(!midCreateGLContext || !midFlipBuffers || !midAudioInit || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit) { @@ -97,7 +99,7 @@ extern "C" void SDL_Android_Init(JNIEnv* env) // Resize extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize( - JNIEnv* env, jobject obj, + JNIEnv* env, jclass jcls, jint width, jint height, jint format) { Android_SetScreenResolution(width, height, format); @@ -105,21 +107,21 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize( // Keydown extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown( - JNIEnv* env, jobject obj, jint keycode) + JNIEnv* env, jclass jcls, jint keycode) { Android_OnKeyDown(keycode); } // Keyup extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp( - JNIEnv* env, jobject obj, jint keycode) + JNIEnv* env, jclass jcls, jint keycode) { Android_OnKeyUp(keycode); } // Touch extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch( - JNIEnv* env, jobject obj, + JNIEnv* env, jclass jcls, jint action, jfloat x, jfloat y, jfloat p) { #ifdef DEBUG @@ -133,7 +135,7 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch( // Accelerometer extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel( - JNIEnv* env, jobject obj, + JNIEnv* env, jclass jcls, jfloat x, jfloat y, jfloat z) { fLastAccelerometer[0] = x; @@ -143,16 +145,18 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel( // Quit extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( - JNIEnv* env, jobject obj) + JNIEnv* env, jclass cls) { // Inject a SDL_QUIT event SDL_SendQuit(); } extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread( - JNIEnv* env) + JNIEnv* env, jclass cls) { - mVM->AttachCurrentThread(&mAudioEnv, NULL); + /* This is the audio thread, with a different environment */ + mAudioEnv = env; + Android_RunAudioThread(); } @@ -162,12 +166,22 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread( *******************************************************************************/ extern "C" void Android_JNI_CreateContext() { - mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext); + mEnv->CallStaticVoidMethod(mActivityClass, midCreateGLContext); } extern "C" void Android_JNI_SwapWindow() { - mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers); + mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); +} + +extern "C" void Android_JNI_SetActivityTitle(const char *title) +{ + jmethodID mid; + + mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)V"); + if (mid) { + mEnv->CallStaticVoidMethod(mActivityClass, mid, mEnv->NewStringUTF(title)); + } } // @@ -186,7 +200,7 @@ extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int chan audioBuffer16Bit = is16Bit; audioBufferStereo = channelCount > 1; - audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames); + audioBuffer = mEnv->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames); if (audioBuffer == NULL) { __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!"); @@ -218,10 +232,10 @@ extern "C" void Android_JNI_WriteAudioBuffer() { if (audioBuffer16Bit) { mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); - mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer); + mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); } else { mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT); - mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); + mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); } /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ @@ -229,7 +243,7 @@ extern "C" void Android_JNI_WriteAudioBuffer() extern "C" void Android_JNI_CloseAudioDevice() { - mEnv->CallStaticVoidMethod(mActivityInstance, midAudioQuit); + mEnv->CallStaticVoidMethod(mActivityClass, midAudioQuit); if (audioBuffer) { mEnv->DeleteGlobalRef(audioBuffer); diff --git a/src/SDL_android.h b/src/SDL_android.h index ea3a487d7..f5704612e 100644 --- a/src/SDL_android.h +++ b/src/SDL_android.h @@ -31,6 +31,7 @@ extern "C" { /* Interface from the SDL library into the Android Java activity */ void Android_JNI_CreateContext(); void Android_JNI_SwapWindow(); +void Android_JNI_SetActivityTitle(const char *title); // Audio support int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); diff --git a/src/main/android/SDL_android_main.cpp b/src/main/android/SDL_android_main.cpp index c675b1102..b5829c6ee 100644 --- a/src/main/android/SDL_android_main.cpp +++ b/src/main/android/SDL_android_main.cpp @@ -8,7 +8,7 @@ #include // Called before SDL_main() to initialize JNI bindings in SDL library -extern "C" void SDL_Android_Init(JNIEnv* env); +extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls); // Library init extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) @@ -17,10 +17,10 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) } // Start up the SDL app -extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit( JNIEnv* env, jobject obj ) +extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) { /* This interface could expand with ABI negotiation, calbacks, etc. */ - SDL_Android_Init(env); + SDL_Android_Init(env, cls); /* Run the application code! */ char *argv[2]; diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index 8b02094b9..a744e70e9 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/src/video/android/SDL_androidvideo.c @@ -33,6 +33,7 @@ #include "SDL_androidvideo.h" #include "SDL_androidevents.h" #include "SDL_androidkeyboard.h" +#include "SDL_androidwindow.h" #define ANDROID_VID_DRIVER_NAME "Android" @@ -58,9 +59,9 @@ extern void Android_GL_DeleteContext(_THIS, SDL_GLContext context); // These are filled in with real values in Android_SetScreenResolution on // init (before SDL_main()) -static Uint32 iScreenFormat = SDL_PIXELFORMAT_UNKNOWN; -static int iScreenWidth = 0; -static int iScreenHeight = 0; +int Android_ScreenWidth = 0; +int Android_ScreenHeight = 0; +Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN; static int @@ -96,6 +97,10 @@ Android_CreateDevice(int devindex) device->VideoQuit = Android_VideoQuit; device->PumpEvents = Android_PumpEvents; + device->CreateWindow = Android_CreateWindow; + device->SetWindowTitle = Android_SetWindowTitle; + device->DestroyWindow = Android_DestroyWindow; + device->free = Android_DeleteDevice; /* GL pointers */ @@ -123,9 +128,9 @@ Android_VideoInit(_THIS) { SDL_DisplayMode mode; - mode.format = iScreenFormat; - mode.w = iScreenWidth; - mode.h = iScreenHeight; + mode.format = Android_ScreenFormat; + mode.w = Android_ScreenWidth; + mode.h = Android_ScreenHeight; mode.refresh_rate = 0; mode.driverdata = NULL; if (SDL_AddBasicVideoDisplay(&mode) < 0) { @@ -146,12 +151,13 @@ Android_VideoQuit(_THIS) { } +/* This function gets called before VideoInit() */ void Android_SetScreenResolution(int width, int height, Uint32 format) { - iScreenWidth = width; - iScreenHeight = height; - iScreenFormat = format; + Android_ScreenWidth = width; + Android_ScreenHeight = height; + Android_ScreenFormat = format; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/android/SDL_androidvideo.h b/src/video/android/SDL_androidvideo.h index 8d07ec50c..3fc7d2a6b 100644 --- a/src/video/android/SDL_androidvideo.h +++ b/src/video/android/SDL_androidvideo.h @@ -29,6 +29,12 @@ /* Called by the JNI layer when the screen changes size or format */ extern void Android_SetScreenResolution(int width, int height, Uint32 format); +/* Private display data */ + +extern int Android_ScreenWidth; +extern int Android_ScreenHeight; +extern Uint32 Android_ScreenFormat; + #endif /* _SDL_androidvideo_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c new file mode 100644 index 000000000..1cd929b2a --- /dev/null +++ b/src/video/android/SDL_androidwindow.c @@ -0,0 +1,52 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "../SDL_sysvideo.h" + +#include "SDL_androidvideo.h" +#include "SDL_androidwindow.h" + +int +Android_CreateWindow(_THIS, SDL_Window * window) +{ + /* Adjust the window data to match the screen */ + window->x = 0; + window->y = 0; + window->w = Android_ScreenWidth; + window->h = Android_ScreenHeight; + + return 0; +} + +void +Android_SetWindowTitle(_THIS, SDL_Window * window) +{ + Android_JNI_SetActivityTitle(window->title); +} + +void +Android_DestroyWindow(_THIS, SDL_Window * window) +{ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/android/SDL_androidwindow.h b/src/video/android/SDL_androidwindow.h new file mode 100644 index 000000000..a35d14b4e --- /dev/null +++ b/src/video/android/SDL_androidwindow.h @@ -0,0 +1,33 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_androidwindow_h +#define _SDL_androidwindow_h + +extern int Android_CreateWindow(_THIS, SDL_Window * window); +extern void Android_SetWindowTitle(_THIS, SDL_Window * window); +extern void Android_DestroyWindow(_THIS, SDL_Window * window); + +#endif /* _SDL_androidwindow_h */ + +/* vi: set ts=4 sw=4 expandtab: */