diff --git a/changeAppSettings.sh b/changeAppSettings.sh index f490caa86..bc4993e09 100755 --- a/changeAppSettings.sh +++ b/changeAppSettings.sh @@ -223,6 +223,9 @@ echo >> AndroidAppSettings.cfg echo "# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)" >> AndroidAppSettings.cfg echo ShowMouseCursor=$ShowMouseCursor >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg +echo "# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n)" >> AndroidAppSettings.cfg +echo ScreenFollowsMouse=$ScreenFollowsMouse >> AndroidAppSettings.cfg +echo >> AndroidAppSettings.cfg echo "# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n)" >> AndroidAppSettings.cfg echo GenerateSubframeTouchEvents=$GenerateSubframeTouchEvents >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg @@ -531,6 +534,12 @@ else ShowMouseCursor=false fi +if [ "$ScreenFollowsMouse" = "y" ] ; then + ScreenFollowsMouse=true +else + ScreenFollowsMouse=false +fi + if [ "$GenerateSubframeTouchEvents" = "y" ] ; then GenerateSubframeTouchEvents=true else @@ -784,6 +793,7 @@ $SEDI "s/public static boolean AppNeedsTwoButtonMouse = .*;/public static boolea $SEDI "s/public static boolean RightMouseButtonLongPress = .*;/public static boolean RightMouseButtonLongPress = $RightMouseButtonLongPress;/" project/src/Globals.java $SEDI "s/public static boolean ForceRelativeMouseMode = .*;/public static boolean ForceRelativeMouseMode = $ForceRelativeMouseMode;/" project/src/Globals.java $SEDI "s/public static boolean ShowMouseCursor = .*;/public static boolean ShowMouseCursor = $ShowMouseCursor;/" project/src/Globals.java +$SEDI "s/public static boolean ScreenFollowsMouse = .*;/public static boolean ScreenFollowsMouse = $ScreenFollowsMouse;/" project/src/Globals.java $SEDI "s/public static boolean GenerateSubframeTouchEvents = .*;/public static boolean GenerateSubframeTouchEvents = $GenerateSubframeTouchEvents;/" project/src/Globals.java $SEDI "s/public static boolean AppNeedsArrowKeys = .*;/public static boolean AppNeedsArrowKeys = $AppNeedsArrowKeys;/" project/src/Globals.java $SEDI "s/public static boolean FloatingScreenJoystick = .*;/public static boolean FloatingScreenJoystick = $FloatingScreenJoystick;/" project/src/Globals.java diff --git a/project/java/Globals.java b/project/java/Globals.java index 8943b18ad..02c893049 100644 --- a/project/java/Globals.java +++ b/project/java/Globals.java @@ -52,7 +52,8 @@ class Globals public static boolean AppNeedsTwoButtonMouse = false; public static boolean RightMouseButtonLongPress = true; public static boolean ForceRelativeMouseMode = false; // If both on-screen keyboard and mouse are needed, this will only set the default setting, user may override it later - public static boolean ShowMouseCursor = false; + public static boolean ShowMouseCursor = false; // Draw system mouse cursor, if the app does not do it + public static boolean ScreenFollowsMouse = false; // Move app screen make mouse cursor always visible, when soft keyboard is shown public static boolean AppNeedsArrowKeys = true; public static boolean AppNeedsTextInput = true; public static boolean AppUsesJoystick = false; diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index 1d7ff42a3..85ad94fe5 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -83,6 +83,8 @@ import android.util.Log; import android.view.Surface; import android.app.ProgressDialog; import android.app.KeyguardManager; +import android.view.ViewTreeObserver; +import android.graphics.Rect; public class MainActivity extends Activity @@ -350,6 +352,24 @@ public class MainActivity extends Activity } DimSystemStatusBar.get().dim(_videoLayout); DimSystemStatusBar.get().dim(mGLView); + + if( Globals.ScreenFollowsMouse ) + { + Rect r = new Rect(); + _videoLayout.getWindowVisibleDisplayFrame(r); + mGLView.nativeScreenVisibleRect(r.left, r.top, r.right, r.bottom); + _videoLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() + { + public void onGlobalLayout() + { + Rect r = new Rect(); + _videoLayout.getWindowVisibleDisplayFrame(r); + int heightDiff = _videoLayout.getRootView().getHeight() - _videoLayout.getHeight(); // Take system bar into consideration + mGLView.nativeScreenVisibleRect(r.left, r.top + heightDiff, r.width(), r.height()); + Log.v("SDL", "Main window visible region changed: " + r.left + ":" + r.top + ":" + r.width() + ":" + r.height() ); + } + }); + } } @Override diff --git a/project/java/Video.java b/project/java/Video.java index fb1cf0f2e..3a600fb38 100644 --- a/project/java/Video.java +++ b/project/java/Video.java @@ -1031,12 +1031,10 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL { MainActivity mParent; public static native void nativeMotionEvent( int x, int y, int action, int pointerId, int pressure, int radius ); - public static native int nativeKey( int keyCode, int down, int unicode ); - public static native void initJavaCallbacks(); + public static native int nativeKey( int keyCode, int down, int unicode ); public static native void nativeHardwareMouseDetected( int detected ); public static native void nativeMouseButtonsPressed( int buttonId, int pressedState ); public static native void nativeMouseWheel( int scrollX, int scrollY ); public static native void nativeGamepadAnalogJoystickInput( float stick1x, float stick1y, float stick2x, float stick2y, float rtrigger, float ltrigger, int usingHat ); + public static native void nativeScreenVisibleRect( int x, int y, int w, int h ); } - - diff --git a/project/jni/application/xserver/AndroidAppSettings.cfg b/project/jni/application/xserver/AndroidAppSettings.cfg index 96199d220..64fccf5ff 100644 --- a/project/jni/application/xserver/AndroidAppSettings.cfg +++ b/project/jni/application/xserver/AndroidAppSettings.cfg @@ -113,6 +113,9 @@ RightMouseButtonLongPress=n # Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n) ShowMouseCursor=n +# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n) +ScreenFollowsMouse=y + # Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n) GenerateSubframeTouchEvents=n diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c index d2f413317..c0d269a64 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c @@ -978,7 +978,7 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects) //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_FlipHWSurface()"); if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels && ! ( SDL_CurrentVideoSurface->flags & SDL_HWSURFACE ) ) { - SDL_Rect rect; + SDL_Rect rect, dstrect; rect.x = 0; rect.y = 0; rect.w = SDL_CurrentVideoSurface->w; @@ -997,14 +997,38 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects) SDL_CurrentVideoSurface->pitch); } } - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_NONE || SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) + + if( SDL_ANDROID_ScreenVisibleRect.h <= 0 || ) + SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); + else { - SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &rect); + int x, y; + SDL_GetMouseState(&x, &y); + rect.w = SDL_ANDROID_ScreenVisibleRect.w * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_sRealWindowWidth; + rect.h = SDL_ANDROID_ScreenVisibleRect.h * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_sRealWindowHeight; + rect.x = x - rect.w / 2; + if( rect.x < 0 ) + rect.x = 0; + if( rect.x + rect.w > SDL_ANDROID_sFakeWindowWidth ) + rect.x = SDL_ANDROID_sFakeWindowWidth - rect.w; + rect.y = y - rect.h / 2; + if( rect.y < 0 ) + rect.y = 0; + if( rect.y + rect.h > SDL_ANDROID_sFakeWindowHeight ) + rect.y = SDL_ANDROID_sFakeWindowHeight - rect.h; + dstrect.w = rect.w; + dstrect.h = rect.h; + dstrect.x = SDL_ANDROID_ScreenVisibleRect.x * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_sRealWindowWidth; + dstrect.y = SDL_ANDROID_ScreenVisibleRect.y * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_sRealWindowHeight; + //__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Flip: %04d:%04d:%04d:%04d -> %04d:%04d:%04d:%04d vis %04d:%04d:%04d:%04d", rect.x, rect.y, rect.w, rect.h, dstrect.x, dstrect.y, dstrect.w, dstrect.h, SDL_ANDROID_ScreenVisibleRect.x, SDL_ANDROID_ScreenVisibleRect.y, SDL_ANDROID_ScreenVisibleRect.w, SDL_ANDROID_ScreenVisibleRect.h); + SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); } + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER && SDL_ANDROID_ShowScreenUnderFingerRect.w > 0 ) { - SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &SDL_ANDROID_ShowScreenUnderFingerRectSrc, &SDL_ANDROID_ShowScreenUnderFingerRect); - SDL_Rect frame = SDL_ANDROID_ShowScreenUnderFingerRect; + rect = SDL_ANDROID_ShowScreenUnderFingerRectSrc; + dstrect = SDL_ANDROID_ShowScreenUnderFingerRect; + SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); int buttons = SDL_GetMouseState(NULL, NULL); // For some reason this code fails - it just outputs nothing to screen /* @@ -1021,10 +1045,10 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects) glOrthof( 0.0f, SDL_ANDROID_sFakeWindowWidth, SDL_ANDROID_sFakeWindowHeight, 0.0f, 0.0f, 1.0f ); glEnableClientState(GL_VERTEX_ARRAY); glColor4f(0.0f, buttons & SDL_BUTTON_RMASK ? 1.0f : 0.0f, buttons & SDL_BUTTON_LMASK ? 1.0f : 0.0f, 1.0f); - GLshort vertices[] = { frame.x, frame.y, - frame.x + frame.w, frame.y, - frame.x + frame.w, frame.y + frame.h, - frame.x, frame.y + frame.h }; + GLshort vertices[] = { dstrect.x, dstrect.y, + dstrect.x + dstrect.w, dstrect.y, + dstrect.x + dstrect.w, dstrect.y + dstrect.h, + dstrect.x, dstrect.y + dstrect.h }; glVertexPointer(2, GL_SHORT, 0, vertices); glDrawArrays(GL_LINE_LOOP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c index aa37d09c6..24eb587d9 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c @@ -38,6 +38,7 @@ If you compile this code with SDL 1.3 or newer, or use in some other way, the li #include "SDL_config.h" #include "SDL_version.h" +#include "SDL.h" #include "SDL_video.h" #include "SDL_mouse.h" #include "SDL_mutex.h" @@ -98,6 +99,7 @@ int SDL_ANDROID_UseGles2 = 0; int SDL_ANDROID_ShowMouseCursor = 0; SDL_Rect SDL_ANDROID_VideoDebugRect; SDL_Color SDL_ANDROID_VideoDebugRectColor; +SDL_Rect SDL_ANDROID_ScreenVisibleRect = {0, 0, 0, 0}; static void appPutToBackgroundCallbackDefault(void) { @@ -435,6 +437,22 @@ void SDLCALL SDL_ANDROID_GetClipboardText(char * buf, int len) (*JavaEnv)->PopLocalFrame( JavaEnv, NULL ); } +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeScreenVisibleRect) (JNIEnv* env, jobject thiz, jint x, jint y, jint w, jint h ) +{ + SDL_ANDROID_ScreenVisibleRect.x = x; + SDL_ANDROID_ScreenVisibleRect.y = y; + SDL_ANDROID_ScreenVisibleRect.w = w; + SDL_ANDROID_ScreenVisibleRect.h = h; + + if( SDL_WasInit(SDL_INIT_VIDEO) ) + { + // Move mouse by 1 pixel to force screen update + SDL_GetMouseState( &x, &y ); + SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y); + } +} + int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position) { jint arr[5]; diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h index f46c66452..8e8f99dd3 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h @@ -83,6 +83,7 @@ extern void SDL_ANDROID_DrawMouseCursor(int x, int y, int size, float alpha); extern void SDL_ANDROID_DrawMouseCursorIfNeeded(); extern void SDL_ANDROID_CallJavaTogglePlainAndroidSoftKeyboardInput(); extern void SDL_ANDROID_CallJavaStartAccelerometerGyroscope(int start); +extern SDL_Rect SDL_ANDROID_ScreenVisibleRect; extern SDL_Rect SDL_ANDROID_VideoDebugRect; extern SDL_Color SDL_ANDROID_VideoDebugRectColor;