XSDL: screen follows mouse cursor

This commit is contained in:
Sergii Pylypenko
2014-12-22 23:38:38 +02:00
parent 47d4a2a261
commit 2a21ba82ad
8 changed files with 89 additions and 14 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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];

View File

@@ -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;