mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 11:03:01 +00:00
Add support for the NVIDIA relative mouse extensions for Shield devices
This commit is contained in:
parent
a455e75e37
commit
fb15ff99ca
@ -4,6 +4,7 @@ package com.limelight;
|
|||||||
import com.limelight.binding.PlatformBinding;
|
import com.limelight.binding.PlatformBinding;
|
||||||
import com.limelight.binding.input.ControllerHandler;
|
import com.limelight.binding.input.ControllerHandler;
|
||||||
import com.limelight.binding.input.KeyboardTranslator;
|
import com.limelight.binding.input.KeyboardTranslator;
|
||||||
|
import com.limelight.binding.input.NvMouseHelper;
|
||||||
import com.limelight.binding.input.TouchContext;
|
import com.limelight.binding.input.TouchContext;
|
||||||
import com.limelight.binding.input.driver.UsbDriverService;
|
import com.limelight.binding.input.driver.UsbDriverService;
|
||||||
import com.limelight.binding.input.evdev.EvdevHandler;
|
import com.limelight.binding.input.evdev.EvdevHandler;
|
||||||
@ -422,11 +423,15 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
private final Runnable toggleGrab = new Runnable() {
|
private final Runnable toggleGrab = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (evdevHandler != null) {
|
if (grabbedInput) {
|
||||||
if (grabbedInput) {
|
NvMouseHelper.setCursorVisibility(Game.this, true);
|
||||||
|
if (evdevHandler != null) {
|
||||||
evdevHandler.ungrabAll();
|
evdevHandler.ungrabAll();
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
else {
|
||||||
|
NvMouseHelper.setCursorVisibility(Game.this, false);
|
||||||
|
if (evdevHandler != null) {
|
||||||
evdevHandler.regrabAll();
|
evdevHandler.regrabAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,13 +660,26 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First process the history
|
// Get relative axis values if we can
|
||||||
for (int i = 0; i < event.getHistorySize(); i++) {
|
if (NvMouseHelper.eventHasRelativeMouseAxes(event)) {
|
||||||
updateMousePosition((int)event.getHistoricalX(i), (int)event.getHistoricalY(i));
|
// Send the deltas straight from the motion event
|
||||||
}
|
conn.sendMouseMove((short)NvMouseHelper.getRelativeAxisX(event),
|
||||||
|
(short)NvMouseHelper.getRelativeAxisY(event));
|
||||||
|
|
||||||
// Now process the current values
|
// We have to also update the position Android thinks the cursor is at
|
||||||
updateMousePosition((int)event.getX(), (int)event.getY());
|
// in order to avoid jumping when we stop moving or click.
|
||||||
|
lastMouseX = (int)event.getX();
|
||||||
|
lastMouseY = (int)event.getY();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// First process the history
|
||||||
|
for (int i = 0; i < event.getHistorySize(); i++) {
|
||||||
|
updateMousePosition((int)event.getHistoricalX(i), (int)event.getHistoricalY(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now process the current values
|
||||||
|
updateMousePosition((int)event.getX(), (int)event.getY());
|
||||||
|
}
|
||||||
|
|
||||||
lastButtonState = event.getButtonState();
|
lastButtonState = event.getButtonState();
|
||||||
}
|
}
|
||||||
@ -828,6 +846,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
evdevHandler.stop();
|
evdevHandler.stop();
|
||||||
evdevHandler = null;
|
evdevHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable cursor visibility again
|
||||||
|
NvMouseHelper.setCursorVisibility(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -867,6 +888,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
connecting = false;
|
connecting = false;
|
||||||
connected = true;
|
connected = true;
|
||||||
|
|
||||||
|
// Hide the mouse cursor now. Doing it before
|
||||||
|
// dismissing the spinner seems to be undone
|
||||||
|
// when the spinner gets displayed.
|
||||||
|
NvMouseHelper.setCursorVisibility(this, false);
|
||||||
|
|
||||||
hideSystemUi(1000);
|
hideSystemUi(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.limelight.binding.input;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.hardware.input.InputManager;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.limelight.LimeLog;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
// NVIDIA extended the Android input APIs with support for using an attached mouse in relative
|
||||||
|
// mode without having to grab the input device (which requires root). The data comes in the form
|
||||||
|
// of new AXIS_RELATIVE_X and AXIS_RELATIVE_Y constants in the mouse's MotionEvent objects and
|
||||||
|
// a new function, InputManager.setCursorVisibility(), that allows the cursor to be hidden.
|
||||||
|
//
|
||||||
|
// http://docs.nvidia.com/gameworks/index.html#technologies/mobile/game_controller_handling_mouse.htm
|
||||||
|
|
||||||
|
public class NvMouseHelper {
|
||||||
|
private static boolean nvExtensionSupported;
|
||||||
|
private static Method methodSetCursorVisibility;
|
||||||
|
private static int AXIS_RELATIVE_X;
|
||||||
|
private static int AXIS_RELATIVE_Y;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
methodSetCursorVisibility = InputManager.class.getMethod("setCursorVisibility", boolean.class);
|
||||||
|
|
||||||
|
Field fieldRelX = MotionEvent.class.getField("AXIS_RELATIVE_X");
|
||||||
|
Field fieldRelY = MotionEvent.class.getField("AXIS_RELATIVE_Y");
|
||||||
|
|
||||||
|
AXIS_RELATIVE_X = (Integer) fieldRelX.get(null);
|
||||||
|
AXIS_RELATIVE_Y = (Integer) fieldRelY.get(null);
|
||||||
|
|
||||||
|
nvExtensionSupported = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LimeLog.info("NvMouseHelper not supported");
|
||||||
|
nvExtensionSupported = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean setCursorVisibility(Context context, boolean visible) {
|
||||||
|
if (!nvExtensionSupported) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
methodSetCursorVisibility.invoke(context.getSystemService(Context.INPUT_SERVICE), visible);
|
||||||
|
return true;
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean eventHasRelativeMouseAxes(MotionEvent event) {
|
||||||
|
if (!nvExtensionSupported) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return event.getAxisValue(AXIS_RELATIVE_X) != 0 ||
|
||||||
|
event.getAxisValue(AXIS_RELATIVE_Y) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getRelativeAxisX(MotionEvent event) {
|
||||||
|
return event.getAxisValue(AXIS_RELATIVE_X);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getRelativeAxisY(MotionEvent event) {
|
||||||
|
return event.getAxisValue(AXIS_RELATIVE_Y);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user