diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index 85ad94fe5..5570739d6 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -353,23 +353,21 @@ 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() { - 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() { - 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() ); - } - }); - } + Rect r = new Rect(); + _videoLayout.getWindowVisibleDisplayFrame(r); + int heightDiff = _videoLayout.getRootView().getHeight() - _videoLayout.getHeight(); // Take system bar into consideration + int widthDiff = _videoLayout.getRootView().getWidth() - _videoLayout.getWidth(); // Nexus 5 has system bar at the right side + mGLView.nativeScreenVisibleRect(r.left + widthDiff, 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/Settings.java b/project/java/Settings.java index 12af4bb89..475b4c7a2 100644 --- a/project/java/Settings.java +++ b/project/java/Settings.java @@ -527,7 +527,8 @@ class Settings Globals.RightMouseButtonLongPress ? 1 : 0, Globals.MoveMouseWithGyroscope ? 1 : 0, Globals.MoveMouseWithGyroscopeSpeed, - Globals.CompatibilityHacksForceScreenUpdateMouseClick ? 1 : 0 ); + Globals.CompatibilityHacksForceScreenUpdateMouseClick ? 1 : 0, + Globals.ScreenFollowsMouse ? 1 : 0 ); } static void Apply(MainActivity p) @@ -863,7 +864,7 @@ class Settings int relativeMovementAccel, int showMouseCursor, int HoverJitterFilter, int RightMouseButtonLongPress, int MoveMouseWithGyroscope, int MoveMouseWithGyroscopeSpeed, - int ForceScreenUpdateMouseClick); + int ForceScreenUpdateMouseClick, int ScreenFollowsMouse); private static native void nativeSetJoystickUsed(int amount); private static native void nativeSetAccelerometerUsed(); private static native void nativeSetMultitouchUsed(); diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c index c217e2602..e382fd30b 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c @@ -35,6 +35,7 @@ If you compile this code with SDL 1.3 or newer, or use in some other way, the li #include #include +#include "SDL.h" #include "SDL_config.h" #include "SDL_version.h" @@ -130,6 +131,8 @@ static unsigned int relativeMovementTime = 0; int SDL_ANDROID_currentMouseX = 0; int SDL_ANDROID_currentMouseY = 0; int SDL_ANDROID_currentMouseButtons = 0; +int screenFollowsMouse = 0; +int SDL_ANDROID_SystemBarAndKeyboardShown; static int hardwareMouseDetected = 0; enum { MOUSE_HW_BUTTON_LEFT = 1, MOUSE_HW_BUTTON_RIGHT = 2, MOUSE_HW_BUTTON_MIDDLE = 4, MOUSE_HW_BUTTON_BACK = 8, MOUSE_HW_BUTTON_FORWARD = 16, MOUSE_HW_BUTTON_MAX = MOUSE_HW_BUTTON_FORWARD }; @@ -1094,7 +1097,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel, jint ShowMouseCursor, jint HoverJitterFilter, jint RightMouseButtonLongPress, jint MoveMouseWithGyroscope, jint MoveMouseWithGyroscopeSpeed, - jint ForceScreenUpdateMouseClick) + jint ForceScreenUpdateMouseClick, jint ScreenFollowsMouse) { SDL_ANDROID_isMouseUsed = 1; rightClickMethod = RightClickMethod; @@ -1120,6 +1123,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, moveMouseWithGyroscopeSpeed = 0.0625f * MoveMouseWithGyroscopeSpeed * MoveMouseWithGyroscopeSpeed + 0.125f * MoveMouseWithGyroscopeSpeed + 0.5f; // Scale value from 0.5 to 2, with 1 at the middle moveMouseWithGyroscopeSpeed *= 5.0f; forceScreenUpdateMouseClick = ForceScreenUpdateMouseClick; + screenFollowsMouse = ScreenFollowsMouse; //__android_log_print(ANDROID_LOG_INFO, "libSDL", "moveMouseWithGyroscopeSpeed %d = %f", MoveMouseWithGyroscopeSpeed, moveMouseWithGyroscopeSpeed); if( !mouseClickTimeoutInitialized && ( leftClickMethod == LEFT_CLICK_WITH_TAP || @@ -1137,49 +1141,78 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, } } -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected) +typedef struct { - if( !SDL_ANDROID_isMouseUsed ) - return; - - static struct { int leftClickMethod; int ShowScreenUnderFinger; int leftClickTimeout; int relativeMovement; int ShowMouseCursor; - } cfg = { 0 }; +} MouseSettings_t; - if( hardwareMouseDetected != detected ) +static void saveMouseSettings(MouseSettings_t *cfg) +{ + cfg->leftClickMethod = leftClickMethod; + cfg->ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger; + cfg->leftClickTimeout = leftClickTimeout; + cfg->relativeMovement = relativeMovement; + cfg->ShowMouseCursor = SDL_ANDROID_ShowMouseCursor; +} + +static void restoreMouseSettings(MouseSettings_t *cfg) +{ + leftClickMethod = cfg->leftClickMethod; + SDL_ANDROID_ShowScreenUnderFinger = cfg->ShowScreenUnderFinger; + leftClickTimeout = cfg->leftClickTimeout; + relativeMovement = cfg->relativeMovement; + SDL_ANDROID_ShowMouseCursor = cfg->ShowMouseCursor; +} + +static void processHardwareMouseDetected (int detected, int ScreenSizeCallback) +{ + static MouseSettings_t cfg; + static int initialized = 0; + + if( !SDL_ANDROID_isMouseUsed ) + return; + + if( !initialized ) { - hardwareMouseDetected = detected; - if(detected) + initialized = 1; + saveMouseSettings(&cfg); + } + + if( hardwareMouseDetected != detected || ScreenSizeCallback ) + { + if( !ScreenSizeCallback ) { - cfg.leftClickMethod = leftClickMethod; - cfg.ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger; - cfg.leftClickTimeout = leftClickTimeout; - cfg.relativeMovement = relativeMovement; - cfg.ShowMouseCursor = SDL_ANDROID_ShowMouseCursor; - + hardwareMouseDetected = detected; + if( SDL_ANDROID_SystemBarAndKeyboardShown ) + return; // Do not enable hardware mouse mode when the keyboard is shown + } + + if( detected ) + { + saveMouseSettings(&cfg); + leftClickMethod = LEFT_CLICK_NORMAL; - SDL_ANDROID_ShowScreenUnderFinger = 0; + SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE; leftClickTimeout = 0; relativeMovement = 0; SDL_ANDROID_ShowMouseCursor = 0; } else - { - leftClickMethod = cfg.leftClickMethod; - SDL_ANDROID_ShowScreenUnderFinger = cfg.ShowScreenUnderFinger; - leftClickTimeout = cfg.leftClickTimeout; - relativeMovement = cfg.relativeMovement; - SDL_ANDROID_ShowMouseCursor = cfg.ShowMouseCursor; - } + restoreMouseSettings(&cfg); } SDL_ANDROID_SetHoverDeadzone(); } +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected) +{ + processHardwareMouseDetected(detected, 0); +} + void SDL_ANDROID_SetHoverDeadzone() { hoverDeadzone = (hardwareMouseDetected == MOUSE_HW_INPUT_STYLUS) ? @@ -1551,7 +1584,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenCalibration) (JNIEnv* env, jobject SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1; } -JNIEXPORT void JNICALL +JNIEXPORT void JNICALL JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz ) { SDL_android_init_keymap(SDL_android_keymap); @@ -1607,3 +1640,48 @@ void *mouseClickTimeoutThread (void * unused) } return 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); + } + else + return; + + if( screenFollowsMouse ) + { + static MouseSettings_t cfg; + //int systemBarActive = SDL_ANDROID_ScreenVisibleRect.h < SDL_ANDROID_sRealWindowHeight; + int keyboardActive = SDL_ANDROID_ScreenVisibleRect.h < SDL_ANDROID_sRealWindowHeight * 9 / 10; + + if( keyboardActive && !SDL_ANDROID_SystemBarAndKeyboardShown ) + { + SDL_ANDROID_SystemBarAndKeyboardShown = 1; + processHardwareMouseDetected(0, 1); // Disable direct mouse input mode, set relative mouse mode + + saveMouseSettings(&cfg); + + leftClickMethod = LEFT_CLICK_WITH_TAP_OR_TIMEOUT; + SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE; + leftClickTimeout = getClickTimeout(3); + relativeMovement = 1; + } + else if( !keyboardActive && SDL_ANDROID_SystemBarAndKeyboardShown ) + { + SDL_ANDROID_SystemBarAndKeyboardShown = 0; + restoreMouseSettings(&cfg); + if( hardwareMouseDetected ) // Restore direct mouse input mode if needed + processHardwareMouseDetected(1, 1); + } + } +} diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h index 9bdef17d0..fae21fcb7 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h @@ -269,5 +269,6 @@ extern int SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY; extern int SDL_ANDROID_moveMouseWithKbSpeedX, SDL_ANDROID_moveMouseWithKbSpeedY; extern int SDL_ANDROID_moveMouseWithKbAccelX, SDL_ANDROID_moveMouseWithKbAccelY; extern int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded; +extern int SDL_ANDROID_SystemBarAndKeyboardShown; #endif 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 51cf71e44..446130224 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, dstrect; + SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = SDL_CurrentVideoSurface->w; @@ -998,12 +998,13 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects) } } - if( SDL_ANDROID_ScreenVisibleRect.h <= 0 ) - SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); + if( !SDL_ANDROID_SystemBarAndKeyboardShown ) + SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &rect); else { int x, y; - SDL_GetMouseState(&x, &y); + SDL_Rect dstrect; + SDL_GetMouseState(&x, &y); // Follow mouse pointer location 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; @@ -1024,21 +1025,12 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects) SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); } - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER && SDL_ANDROID_ShowScreenUnderFingerRect.w > 0 ) + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) { + SDL_Rect dstrect = 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 - /* - SDL_SetRenderDrawColor(0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderFillRect(&SDL_ANDROID_ShowScreenUnderFingerRect); - SDL_SetRenderDrawColor(255, 255, 255, SDL_ALPHA_OPAQUE); - SDL_RenderDrawRect(&SDL_ANDROID_ShowScreenUnderFingerRectSrc); - SDL_SetRenderDrawColor(0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderDrawRect(&frame); - */ // Do it old-fashioned way with direct GL calls glPushMatrix(); glLoadIdentity(); @@ -1053,7 +1045,6 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects) glDrawArrays(GL_LINE_LOOP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); - //glFlush(); } #ifdef VIDEO_DEBUG if( SDL_ANDROID_VideoDebugRect.w > 0 ) 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 24eb587d9..ea482089d 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,7 +38,6 @@ 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" @@ -437,22 +436,6 @@ 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/todo.txt b/todo.txt index f25bea407..a40988a75 100644 --- a/todo.txt +++ b/todo.txt @@ -31,8 +31,6 @@ TODO, which will get actually done - XSDL: support Android intent x11://localhost:6000 - http://www.openintents.org/node/905 -- XSDL: screen follows mouse when on-screen keyboard is shown. - - XSDL: copy text from Android clipboard when it changes. - USB Keyboard: configurable mouse speed, show keyboard LEDs, redefine unknown keys, fix Lollipop SELinux bug.