mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-08-02 21:58:42 +00:00
server添加多点触摸接口
This commit is contained in:
parent
4e386e879e
commit
310518f8ee
3 changed files with 179 additions and 22 deletions
|
@ -10,6 +10,7 @@ public final class ControlEvent {
|
||||||
public static final int TYPE_MOUSE = 2;
|
public static final int TYPE_MOUSE = 2;
|
||||||
public static final int TYPE_SCROLL = 3;
|
public static final int TYPE_SCROLL = 3;
|
||||||
public static final int TYPE_COMMAND = 4;
|
public static final int TYPE_COMMAND = 4;
|
||||||
|
public static final int TYPE_TOUCH = 5;
|
||||||
|
|
||||||
public static final int COMMAND_BACK_OR_SCREEN_ON = 0;
|
public static final int COMMAND_BACK_OR_SCREEN_ON = 0;
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ public final class ControlEvent {
|
||||||
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_* or COMMAND_*
|
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_* or COMMAND_*
|
||||||
private int keycode; // KeyEvent.KEYCODE_*
|
private int keycode; // KeyEvent.KEYCODE_*
|
||||||
private int buttons; // MotionEvent.BUTTON_*
|
private int buttons; // MotionEvent.BUTTON_*
|
||||||
|
private int id;
|
||||||
private Position position;
|
private Position position;
|
||||||
private int hScroll;
|
private int hScroll;
|
||||||
private int vScroll;
|
private int vScroll;
|
||||||
|
@ -51,6 +53,15 @@ public final class ControlEvent {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ControlEvent createMotionTouchEvent(int id, int action, Position position) {
|
||||||
|
ControlEvent event = new ControlEvent();
|
||||||
|
event.type = TYPE_TOUCH;
|
||||||
|
event.action = action;
|
||||||
|
event.id = id;
|
||||||
|
event.position = position;
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
public static ControlEvent createScrollControlEvent(Position position, int hScroll, int vScroll) {
|
public static ControlEvent createScrollControlEvent(Position position, int hScroll, int vScroll) {
|
||||||
ControlEvent event = new ControlEvent();
|
ControlEvent event = new ControlEvent();
|
||||||
event.type = TYPE_SCROLL;
|
event.type = TYPE_SCROLL;
|
||||||
|
@ -91,6 +102,10 @@ public final class ControlEvent {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public Position getPosition() {
|
public Position getPosition() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ public class ControlEventReader {
|
||||||
|
|
||||||
private static final int KEYCODE_PAYLOAD_LENGTH = 9;
|
private static final int KEYCODE_PAYLOAD_LENGTH = 9;
|
||||||
private static final int MOUSE_PAYLOAD_LENGTH = 13;
|
private static final int MOUSE_PAYLOAD_LENGTH = 13;
|
||||||
|
private static final int TOUCH_PAYLOAD_LENGTH = 10;
|
||||||
private static final int SCROLL_PAYLOAD_LENGTH = 16;
|
private static final int SCROLL_PAYLOAD_LENGTH = 16;
|
||||||
private static final int COMMAND_PAYLOAD_LENGTH = 1;
|
private static final int COMMAND_PAYLOAD_LENGTH = 1;
|
||||||
|
|
||||||
|
@ -48,7 +49,6 @@ public class ControlEventReader {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int savedPosition = buffer.position();
|
int savedPosition = buffer.position();
|
||||||
|
|
||||||
int type = buffer.get();
|
int type = buffer.get();
|
||||||
ControlEvent controlEvent;
|
ControlEvent controlEvent;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -61,6 +61,9 @@ public class ControlEventReader {
|
||||||
case ControlEvent.TYPE_MOUSE:
|
case ControlEvent.TYPE_MOUSE:
|
||||||
controlEvent = parseMouseControlEvent();
|
controlEvent = parseMouseControlEvent();
|
||||||
break;
|
break;
|
||||||
|
case ControlEvent.TYPE_TOUCH:
|
||||||
|
controlEvent = parseMouseTouchEvent();
|
||||||
|
break;
|
||||||
case ControlEvent.TYPE_SCROLL:
|
case ControlEvent.TYPE_SCROLL:
|
||||||
controlEvent = parseScrollControlEvent();
|
controlEvent = parseScrollControlEvent();
|
||||||
break;
|
break;
|
||||||
|
@ -113,6 +116,16 @@ public class ControlEventReader {
|
||||||
return ControlEvent.createMotionControlEvent(action, buttons, position);
|
return ControlEvent.createMotionControlEvent(action, buttons, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ControlEvent parseMouseTouchEvent() {
|
||||||
|
if (buffer.remaining() < TOUCH_PAYLOAD_LENGTH) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int id = toUnsigned(buffer.get());
|
||||||
|
int action = toUnsigned(buffer.get());
|
||||||
|
Position position = readPosition(buffer);
|
||||||
|
return ControlEvent.createMotionTouchEvent(id, action, position);
|
||||||
|
}
|
||||||
|
|
||||||
private ControlEvent parseScrollControlEvent() {
|
private ControlEvent parseScrollControlEvent() {
|
||||||
if (buffer.remaining() < SCROLL_PAYLOAD_LENGTH) {
|
if (buffer.remaining() < SCROLL_PAYLOAD_LENGTH) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
public class EventController {
|
public class EventController {
|
||||||
|
@ -21,37 +22,80 @@ public class EventController {
|
||||||
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||||
|
|
||||||
private long lastMouseDown;
|
private long lastMouseDown;
|
||||||
private final MotionEvent.PointerProperties[] pointerProperties = {new MotionEvent.PointerProperties()};
|
private Vector<MotionEvent.PointerProperties> pointerProperties = new Vector<MotionEvent.PointerProperties>();
|
||||||
private final MotionEvent.PointerCoords[] pointerCoords = {new MotionEvent.PointerCoords()};
|
private Vector<MotionEvent.PointerCoords> pointerCoords = new Vector<MotionEvent.PointerCoords>();
|
||||||
|
|
||||||
public EventController(Device device, DesktopConnection connection) {
|
public EventController(Device device, DesktopConnection connection) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
initPointer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPointer() {
|
private int getPointer(int id) {
|
||||||
MotionEvent.PointerProperties props = pointerProperties[0];
|
for (int i = 0; i < pointerProperties.size(); i++) {
|
||||||
props.id = 0;
|
if (id == pointerProperties.get(i).id) {
|
||||||
props.toolType = MotionEvent.TOOL_TYPE_FINGER;
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MotionEvent.PointerCoords coords = pointerCoords[0];
|
MotionEvent.PointerProperties props = new MotionEvent.PointerProperties();
|
||||||
|
props.id = id;
|
||||||
|
props.toolType = MotionEvent.TOOL_TYPE_FINGER;
|
||||||
|
pointerProperties.addElement(props);
|
||||||
|
|
||||||
|
MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
|
||||||
coords.orientation = 0;
|
coords.orientation = 0;
|
||||||
coords.pressure = 1;
|
coords.pressure = 1;
|
||||||
coords.size = 1;
|
coords.size = 1;
|
||||||
|
pointerCoords.addElement(coords);
|
||||||
|
return pointerProperties.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPointerCoords(Point point) {
|
private void releasePointer(int id) {
|
||||||
MotionEvent.PointerCoords coords = pointerCoords[0];
|
int index = -1;
|
||||||
|
for (int i = 0; i < pointerProperties.size(); i++) {
|
||||||
|
if (id == pointerProperties.get(i).id) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( -1 != index) {
|
||||||
|
pointerProperties.remove(index);
|
||||||
|
pointerCoords.remove(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPointerCoords(int id, Point point) {
|
||||||
|
int index = -1;
|
||||||
|
for (int i = 0; i < pointerProperties.size(); i++) {
|
||||||
|
if (id == pointerProperties.get(i).id) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( -1 != index) {
|
||||||
|
MotionEvent.PointerCoords coords = pointerCoords.get(index);
|
||||||
coords.x = point.x;
|
coords.x = point.x;
|
||||||
coords.y = point.y;
|
coords.y = point.y;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setScroll(int hScroll, int vScroll) {
|
private void setScroll(int id, int hScroll, int vScroll) {
|
||||||
MotionEvent.PointerCoords coords = pointerCoords[0];
|
int index = -1;
|
||||||
|
for (int i = 0; i < pointerProperties.size(); i++) {
|
||||||
|
if (id == pointerProperties.get(i).id) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( -1 != index) {
|
||||||
|
MotionEvent.PointerCoords coords = pointerCoords.get(index);
|
||||||
coords.setAxisValue(MotionEvent.AXIS_HSCROLL, hScroll);
|
coords.setAxisValue(MotionEvent.AXIS_HSCROLL, hScroll);
|
||||||
coords.setAxisValue(MotionEvent.AXIS_VSCROLL, vScroll);
|
coords.setAxisValue(MotionEvent.AXIS_VSCROLL, vScroll);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void control() throws IOException {
|
public void control() throws IOException {
|
||||||
// on start, turn screen on
|
// on start, turn screen on
|
||||||
|
@ -74,6 +118,9 @@ public class EventController {
|
||||||
case ControlEvent.TYPE_MOUSE:
|
case ControlEvent.TYPE_MOUSE:
|
||||||
injectMouse(controlEvent.getAction(), controlEvent.getButtons(), controlEvent.getPosition());
|
injectMouse(controlEvent.getAction(), controlEvent.getButtons(), controlEvent.getPosition());
|
||||||
break;
|
break;
|
||||||
|
case ControlEvent.TYPE_TOUCH:
|
||||||
|
injectTouch(controlEvent.getId(), controlEvent.getAction(), controlEvent.getPosition());
|
||||||
|
break;
|
||||||
case ControlEvent.TYPE_SCROLL:
|
case ControlEvent.TYPE_SCROLL:
|
||||||
injectScroll(controlEvent.getPosition(), controlEvent.getHScroll(), controlEvent.getVScroll());
|
injectScroll(controlEvent.getPosition(), controlEvent.getHScroll(), controlEvent.getVScroll());
|
||||||
break;
|
break;
|
||||||
|
@ -113,9 +160,65 @@ public class EventController {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean injectTouch(int id, int action, Position position) {
|
||||||
|
if (action != MotionEvent.ACTION_DOWN
|
||||||
|
&& action != MotionEvent.ACTION_UP
|
||||||
|
&& action != MotionEvent.ACTION_MOVE) {
|
||||||
|
Ln.w("Unsupported action: " + action);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (id < 0 || id > 9) {
|
||||||
|
Ln.w("Unsupported id[0-9]: " + id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = getPointer(id);
|
||||||
|
int convertAction = action;
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if (1 != pointerProperties.size()) {
|
||||||
|
convertAction = (index << 8) | MotionEvent.ACTION_POINTER_DOWN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
if (1 != pointerProperties.size()) {
|
||||||
|
convertAction = (index << 8) | convertAction;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if (1 != pointerProperties.size()) {
|
||||||
|
convertAction = (index << 8) | MotionEvent.ACTION_POINTER_UP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point point = device.getPhysicalPoint(position);
|
||||||
|
if (point == null) {
|
||||||
|
// ignore event
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointerProperties.isEmpty()) {
|
||||||
|
// ignore event
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
setPointerCoords(id, point);
|
||||||
|
MotionEvent.PointerProperties[] props = pointerProperties.toArray(new MotionEvent.PointerProperties[pointerProperties.size()]);
|
||||||
|
MotionEvent.PointerCoords[] coords = pointerCoords.toArray(new MotionEvent.PointerCoords[pointerCoords.size()]);
|
||||||
|
MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), convertAction,
|
||||||
|
pointerProperties.size(), props, coords, 0, 0, 1f, 1f, 0, 0,
|
||||||
|
InputDevice.SOURCE_TOUCHSCREEN, 0);
|
||||||
|
|
||||||
|
if (action == MotionEvent.ACTION_UP) {
|
||||||
|
releasePointer(id);
|
||||||
|
}
|
||||||
|
return injectEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean injectMouse(int action, int buttons, Position position) {
|
private boolean injectMouse(int action, int buttons, Position position) {
|
||||||
long now = SystemClock.uptimeMillis();
|
long now = SystemClock.uptimeMillis();
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
if (action == MotionEvent.ACTION_DOWN) {
|
||||||
|
getPointer(0);
|
||||||
lastMouseDown = now;
|
lastMouseDown = now;
|
||||||
}
|
}
|
||||||
Point point = device.getPhysicalPoint(position);
|
Point point = device.getPhysicalPoint(position);
|
||||||
|
@ -123,9 +226,21 @@ public class EventController {
|
||||||
// ignore event
|
// ignore event
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setPointerCoords(point);
|
|
||||||
MotionEvent event = MotionEvent.obtain(lastMouseDown, now, action, 1, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, 0, 0,
|
if (pointerProperties.isEmpty()) {
|
||||||
|
// ignore event
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
setPointerCoords(0, point);
|
||||||
|
MotionEvent.PointerProperties[] props = pointerProperties.toArray(new MotionEvent.PointerProperties[pointerProperties.size()]);
|
||||||
|
MotionEvent.PointerCoords[] coords = pointerCoords.toArray(new MotionEvent.PointerCoords[pointerCoords.size()]);
|
||||||
|
MotionEvent event = MotionEvent.obtain(lastMouseDown, now, action,
|
||||||
|
pointerProperties.size(), props, coords, 0, buttons, 1f, 1f, 0, 0,
|
||||||
InputDevice.SOURCE_TOUCHSCREEN, 0);
|
InputDevice.SOURCE_TOUCHSCREEN, 0);
|
||||||
|
|
||||||
|
if (action == MotionEvent.ACTION_UP) {
|
||||||
|
releasePointer(0);
|
||||||
|
}
|
||||||
return injectEvent(event);
|
return injectEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,9 +251,23 @@ public class EventController {
|
||||||
// ignore event
|
// ignore event
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setPointerCoords(point);
|
|
||||||
setScroll(hScroll, vScroll);
|
// init
|
||||||
MotionEvent event = MotionEvent.obtain(lastMouseDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, 0,
|
MotionEvent.PointerProperties[] props = {new MotionEvent.PointerProperties()};
|
||||||
|
props[0].id = 0;
|
||||||
|
props[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
|
||||||
|
MotionEvent.PointerCoords[] coords = {new MotionEvent.PointerCoords()};
|
||||||
|
coords[0].orientation = 0;
|
||||||
|
coords[0].pressure = 1;
|
||||||
|
coords[0].size = 1;
|
||||||
|
|
||||||
|
// set data
|
||||||
|
coords[0].x = point.x;
|
||||||
|
coords[0].y = point.y;
|
||||||
|
coords[0].setAxisValue(MotionEvent.AXIS_HSCROLL, hScroll);
|
||||||
|
coords[0].setAxisValue(MotionEvent.AXIS_VSCROLL, vScroll);
|
||||||
|
|
||||||
|
MotionEvent event = MotionEvent.obtain(lastMouseDown, now, MotionEvent.ACTION_SCROLL, 1, props, coords, 0, 0, 1f, 1f, 0,
|
||||||
0, InputDevice.SOURCE_MOUSE, 0);
|
0, InputDevice.SOURCE_MOUSE, 0);
|
||||||
return injectEvent(event);
|
return injectEvent(event);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue