diff --git a/QtScrcpy/inputcontrol/controlevent.cpp b/QtScrcpy/inputcontrol/controlevent.cpp deleted file mode 100644 index 0e4c1da..0000000 --- a/QtScrcpy/inputcontrol/controlevent.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include - -#include "controlevent.h" -#include "bufferutil.h" - -ControlEvent::ControlEvent(ControlEventType controlEventType) - : QScrcpyEvent(Control) -{ - m_data.type = controlEventType; -} - -ControlEvent::~ControlEvent() -{ - if (CET_SET_CLIPBOARD == m_data.type - && Q_NULLPTR != m_data.setClipboardEvent.text) { - delete m_data.setClipboardEvent.text; - m_data.setClipboardEvent.text = Q_NULLPTR; - } else if (CET_TEXT == m_data.type - && Q_NULLPTR != m_data.textEvent.text){ - delete m_data.textEvent.text; - m_data.textEvent.text = Q_NULLPTR; - } -} - -void ControlEvent::setKeycodeEventData(AndroidKeyeventAction action, AndroidKeycode keycode, AndroidMetastate metastate) -{ - m_data.keycodeEvent.action = action; - m_data.keycodeEvent.keycode = keycode; - m_data.keycodeEvent.metastate = metastate; -} - -void ControlEvent::setTextEventData(QString& text) -{ - // write length (2 byte) + string (non nul-terminated) - if (CONTROL_EVENT_TEXT_MAX_LENGTH < text.length()) { - // injecting a text takes time, so limit the text length - text = text.left(CONTROL_EVENT_TEXT_MAX_LENGTH); - } - QByteArray tmp = text.toUtf8(); - m_data.textEvent.text = new char[tmp.length() + 1]; - memcpy(m_data.textEvent.text, tmp.data(), tmp.length()); - m_data.textEvent.text[tmp.length()] = '\0'; -} - -void ControlEvent::setMouseEventData(AndroidMotioneventAction action, AndroidMotioneventButtons buttons, QRect position) -{ - m_data.mouseEvent.action = action; - m_data.mouseEvent.buttons = buttons; - m_data.mouseEvent.position = position; -} - -void ControlEvent::setTouchEventData(quint32 id, AndroidMotioneventAction action, QRect position) -{ - m_data.touchEvent.action = action; - m_data.touchEvent.id = id; - m_data.touchEvent.position = position; -} - -void ControlEvent::setScrollEventData(QRect position, qint32 hScroll, qint32 vScroll) -{ - m_data.scrollEvent.position = position; - m_data.scrollEvent.hScroll = hScroll; - m_data.scrollEvent.vScroll = vScroll; -} - -void ControlEvent::setSetClipboardEventData(QString &text) -{ - if (text.isEmpty()) { - return; - } - if (CONTROL_EVENT_CLIPBOARD_TEXT_MAX_LENGTH < text.length()) { - text = text.left(CONTROL_EVENT_CLIPBOARD_TEXT_MAX_LENGTH); - } - - QByteArray tmp = text.toUtf8(); - m_data.setClipboardEvent.text = new char[tmp.length() + 1]; - memcpy(m_data.setClipboardEvent.text, tmp.data(), tmp.length()); - m_data.setClipboardEvent.text[tmp.length()] = '\0'; -} - -void ControlEvent::writePosition(QBuffer &buffer, const QRect& value) -{ - BufferUtil::write16(buffer, value.left()); - BufferUtil::write16(buffer, value.top()); - BufferUtil::write16(buffer, value.width()); - BufferUtil::write16(buffer, value.height()); -} - -QByteArray ControlEvent::serializeData() -{ - QByteArray byteArray; - QBuffer buffer(&byteArray); - buffer.open(QBuffer::WriteOnly); - buffer.putChar(m_data.type); - - switch (m_data.type) { - case CET_KEYCODE: - buffer.putChar(m_data.keycodeEvent.action); - BufferUtil::write32(buffer, m_data.keycodeEvent.keycode); - BufferUtil::write32(buffer, m_data.keycodeEvent.metastate); - break; - case CET_TEXT: - BufferUtil::write16(buffer, strlen(m_data.textEvent.text)); - buffer.write(m_data.textEvent.text, strlen(m_data.textEvent.text)); - break; - case CET_MOUSE: - buffer.putChar(m_data.mouseEvent.action); - BufferUtil::write32(buffer, m_data.mouseEvent.buttons); - writePosition(buffer, m_data.mouseEvent.position); - break; - case CET_TOUCH: - buffer.putChar(m_data.touchEvent.id); - buffer.putChar(m_data.touchEvent.action); - writePosition(buffer, m_data.touchEvent.position); - break; - case CET_SCROLL: - writePosition(buffer, m_data.scrollEvent.position); - BufferUtil::write32(buffer, m_data.scrollEvent.hScroll); - BufferUtil::write32(buffer, m_data.scrollEvent.vScroll); - break; - case CET_SET_CLIPBOARD: - BufferUtil::write16(buffer, strlen(m_data.setClipboardEvent.text)); - buffer.write(m_data.setClipboardEvent.text, strlen(m_data.setClipboardEvent.text)); - break; - case CET_BACK_OR_SCREEN_ON: - case CET_EXPAND_NOTIFICATION_PANEL: - case CET_COLLAPSE_NOTIFICATION_PANEL: - case CET_GET_CLIPBOARD: - break; - default: - qDebug() << "Unknown event type:" << m_data.type; - break; - } - buffer.close(); - return byteArray; -} diff --git a/QtScrcpy/inputcontrol/controlevent.h b/QtScrcpy/inputcontrol/controlevent.h deleted file mode 100644 index 67f99a0..0000000 --- a/QtScrcpy/inputcontrol/controlevent.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef CONTROLEVENT_H -#define CONTROLEVENT_H - -#include -#include -#include - -#include "qscrcpyevent.h" -#include "input.h" -#include "keycodes.h" - -#define CONTROL_EVENT_TEXT_MAX_LENGTH 300 -#define CONTROL_EVENT_CLIPBOARD_TEXT_MAX_LENGTH 4093 -// ControlEvent -class ControlEvent : public QScrcpyEvent -{ -public: - enum ControlEventType { - CET_NULL = -1, - CET_KEYCODE = 0, - CET_TEXT, - CET_MOUSE, - CET_SCROLL, - CET_BACK_OR_SCREEN_ON, - CET_EXPAND_NOTIFICATION_PANEL, - CET_COLLAPSE_NOTIFICATION_PANEL, - CET_GET_CLIPBOARD, - CET_SET_CLIPBOARD, - - CET_TOUCH, - }; - - ControlEvent(ControlEventType controlEventType); - virtual ~ControlEvent(); - - void setKeycodeEventData(AndroidKeyeventAction action, AndroidKeycode keycode, AndroidMetastate metastate); - void setTextEventData(QString& text); - void setMouseEventData(AndroidMotioneventAction action, AndroidMotioneventButtons buttons, QRect position); - // id 代表一个触摸点,最多支持10个触摸点[0,9] - // action 只能是AMOTION_EVENT_ACTION_DOWN,AMOTION_EVENT_ACTION_UP,AMOTION_EVENT_ACTION_MOVE - // position action动作对应的位置 - void setTouchEventData(quint32 id, AndroidMotioneventAction action, QRect position); - void setScrollEventData(QRect position, qint32 hScroll, qint32 vScroll); - void setSetClipboardEventData(QString& text); - - QByteArray serializeData(); - -private: - void writePosition(QBuffer& buffer, const QRect& value); - -private: - struct ControlEventData { - ControlEventType type = CET_NULL; - union { - struct { - AndroidKeyeventAction action; - AndroidKeycode keycode; - AndroidMetastate metastate; - } keycodeEvent; - struct { - char* text = Q_NULLPTR; - } textEvent; - struct { - AndroidMotioneventAction action; - AndroidMotioneventButtons buttons; - QRect position; - } mouseEvent; - struct { - quint32 id; - AndroidMotioneventAction action; - QRect position; - } touchEvent; - struct { - QRect position; - qint32 hScroll; - qint32 vScroll; - } scrollEvent; - struct { - char *text = Q_NULLPTR; - } setClipboardEvent; - }; - - ControlEventData(){} - ~ControlEventData(){} - }; - - ControlEventData m_data; -}; - -#endif // CONTROLEVENT_H diff --git a/QtScrcpy/inputcontrol/controller.cpp b/QtScrcpy/inputcontrol/controller.cpp index dcd867e..5929730 100644 --- a/QtScrcpy/inputcontrol/controller.cpp +++ b/QtScrcpy/inputcontrol/controller.cpp @@ -2,7 +2,7 @@ #include "controller.h" #include "videosocket.h" -#include "controlevent.h" +#include "controlmsg.h" #include "receiver.h" Controller::Controller(QObject* parent) : QObject(parent) @@ -29,26 +29,26 @@ QTcpSocket *Controller::getControlSocket() return m_controlSocket; } -void Controller::postControlEvent(ControlEvent *controlEvent) +void Controller::postControlMsg(ControlMsg *controlMsg) { - if (controlEvent) { - QCoreApplication::postEvent(this, controlEvent); + if (controlMsg) { + QCoreApplication::postEvent(this, controlMsg); } } void Controller::test(QRect rc) { - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_MOUSE); - controlEvent->setMouseEventData(AMOTION_EVENT_ACTION_DOWN, AMOTION_EVENT_BUTTON_PRIMARY, rc); - postControlEvent(controlEvent); + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_MOUSE); + controlMsg->setInjectMouseMsgData(AMOTION_EVENT_ACTION_DOWN, AMOTION_EVENT_BUTTON_PRIMARY, rc); + postControlMsg(controlMsg); } bool Controller::event(QEvent *event) { - if (event && event->type() == ControlEvent::Control) { - ControlEvent* controlEvent = dynamic_cast(event); - if (controlEvent) { - sendControl(controlEvent->serializeData()); + if (event && event->type() == ControlMsg::Control) { + ControlMsg* controlMsg = dynamic_cast(event); + if (controlMsg) { + sendControl(controlMsg->serializeData()); } return true; } diff --git a/QtScrcpy/inputcontrol/controller.h b/QtScrcpy/inputcontrol/controller.h index 1522f3c..a046284 100644 --- a/QtScrcpy/inputcontrol/controller.h +++ b/QtScrcpy/inputcontrol/controller.h @@ -5,7 +5,7 @@ #include class QTcpSocket; -class ControlEvent; +class ControlMsg; class Receiver; class Controller : public QObject { @@ -16,7 +16,7 @@ public: void setControlSocket(QTcpSocket* controlSocket); QTcpSocket* getControlSocket(); - void postControlEvent(ControlEvent* controlEvent); + void postControlMsg(ControlMsg* controlMsg); void test(QRect rc); protected: diff --git a/QtScrcpy/inputcontrol/controlmsg.cpp b/QtScrcpy/inputcontrol/controlmsg.cpp new file mode 100644 index 0000000..9226ec4 --- /dev/null +++ b/QtScrcpy/inputcontrol/controlmsg.cpp @@ -0,0 +1,136 @@ +#include + +#include "controlmsg.h" +#include "bufferutil.h" + +ControlMsg::ControlMsg(ControlMsgType controlMsgType) + : QScrcpyEvent(Control) +{ + m_data.type = controlMsgType; +} + +ControlMsg::~ControlMsg() +{ + if (CMT_SET_CLIPBOARD == m_data.type + && Q_NULLPTR != m_data.setClipboardMsg.text) { + delete m_data.setClipboardMsg.text; + m_data.setClipboardMsg.text = Q_NULLPTR; + } else if (CMT_INJECT_TEXT == m_data.type + && Q_NULLPTR != m_data.injectTextMsg.text){ + delete m_data.injectTextMsg.text; + m_data.injectTextMsg.text = Q_NULLPTR; + } +} + +void ControlMsg::setInjectKeycodeMsgData(AndroidKeyeventAction action, AndroidKeycode keycode, AndroidMetastate metastate) +{ + m_data.injectKeycodeMsg.action = action; + m_data.injectKeycodeMsg.keycode = keycode; + m_data.injectKeycodeMsg.metastate = metastate; +} + +void ControlMsg::setInjectTextMsgData(QString& text) +{ + // write length (2 byte) + string (non nul-terminated) + if (CONTROL_MSG_TEXT_MAX_LENGTH < text.length()) { + // injecting a text takes time, so limit the text length + text = text.left(CONTROL_MSG_TEXT_MAX_LENGTH); + } + QByteArray tmp = text.toUtf8(); + m_data.injectTextMsg.text = new char[tmp.length() + 1]; + memcpy(m_data.injectTextMsg.text, tmp.data(), tmp.length()); + m_data.injectTextMsg.text[tmp.length()] = '\0'; +} + +void ControlMsg::setInjectMouseMsgData(AndroidMotioneventAction action, AndroidMotioneventButtons buttons, QRect position) +{ + m_data.injectMouseMsg.action = action; + m_data.injectMouseMsg.buttons = buttons; + m_data.injectMouseMsg.position = position; +} + +void ControlMsg::setInjectTouchMsgData(quint32 id, AndroidMotioneventAction action, QRect position) +{ + m_data.injectTouchMsg.action = action; + m_data.injectTouchMsg.id = id; + m_data.injectTouchMsg.position = position; +} + +void ControlMsg::setInjectScrollMsgData(QRect position, qint32 hScroll, qint32 vScroll) +{ + m_data.injectScrollMsg.position = position; + m_data.injectScrollMsg.hScroll = hScroll; + m_data.injectScrollMsg.vScroll = vScroll; +} + +void ControlMsg::setSetClipboardMsgData(QString &text) +{ + if (text.isEmpty()) { + return; + } + if (CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH < text.length()) { + text = text.left(CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH); + } + + QByteArray tmp = text.toUtf8(); + m_data.setClipboardMsg.text = new char[tmp.length() + 1]; + memcpy(m_data.setClipboardMsg.text, tmp.data(), tmp.length()); + m_data.setClipboardMsg.text[tmp.length()] = '\0'; +} + +void ControlMsg::writePosition(QBuffer &buffer, const QRect& value) +{ + BufferUtil::write16(buffer, value.left()); + BufferUtil::write16(buffer, value.top()); + BufferUtil::write16(buffer, value.width()); + BufferUtil::write16(buffer, value.height()); +} + +QByteArray ControlMsg::serializeData() +{ + QByteArray byteArray; + QBuffer buffer(&byteArray); + buffer.open(QBuffer::WriteOnly); + buffer.putChar(m_data.type); + + switch (m_data.type) { + case CMT_INJECT_KEYCODE: + buffer.putChar(m_data.injectKeycodeMsg.action); + BufferUtil::write32(buffer, m_data.injectKeycodeMsg.keycode); + BufferUtil::write32(buffer, m_data.injectKeycodeMsg.metastate); + break; + case CMT_INJECT_TEXT: + BufferUtil::write16(buffer, strlen(m_data.injectTextMsg.text)); + buffer.write(m_data.injectTextMsg.text, strlen(m_data.injectTextMsg.text)); + break; + case CMT_INJECT_MOUSE: + buffer.putChar(m_data.injectMouseMsg.action); + BufferUtil::write32(buffer, m_data.injectMouseMsg.buttons); + writePosition(buffer, m_data.injectMouseMsg.position); + break; + case CMT_INJECT_TOUCH: + buffer.putChar(m_data.injectTouchMsg.id); + buffer.putChar(m_data.injectTouchMsg.action); + writePosition(buffer, m_data.injectTouchMsg.position); + break; + case CMT_INJECT_SCROLL: + writePosition(buffer, m_data.injectScrollMsg.position); + BufferUtil::write32(buffer, m_data.injectScrollMsg.hScroll); + BufferUtil::write32(buffer, m_data.injectScrollMsg.vScroll); + break; + case CMT_SET_CLIPBOARD: + BufferUtil::write16(buffer, strlen(m_data.setClipboardMsg.text)); + buffer.write(m_data.setClipboardMsg.text, strlen(m_data.setClipboardMsg.text)); + break; + case CMT_BACK_OR_SCREEN_ON: + case CMT_EXPAND_NOTIFICATION_PANEL: + case CMT_COLLAPSE_NOTIFICATION_PANEL: + case CMT_GET_CLIPBOARD: + break; + default: + qDebug() << "Unknown event type:" << m_data.type; + break; + } + buffer.close(); + return byteArray; +} diff --git a/QtScrcpy/inputcontrol/controlmsg.h b/QtScrcpy/inputcontrol/controlmsg.h new file mode 100644 index 0000000..d137475 --- /dev/null +++ b/QtScrcpy/inputcontrol/controlmsg.h @@ -0,0 +1,90 @@ +#ifndef CONTROLMSG_H +#define CONTROLMSG_H + +#include +#include +#include + +#include "qscrcpyevent.h" +#include "input.h" +#include "keycodes.h" + +#define CONTROL_MSG_TEXT_MAX_LENGTH 300 +#define CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH 4093 +// ControlMsg +class ControlMsg : public QScrcpyEvent +{ +public: + enum ControlMsgType { + CMT_NULL = -1, + CMT_INJECT_KEYCODE = 0, + CMT_INJECT_TEXT, + CMT_INJECT_MOUSE, + CMT_INJECT_SCROLL, + CMT_BACK_OR_SCREEN_ON, + CMT_EXPAND_NOTIFICATION_PANEL, + CMT_COLLAPSE_NOTIFICATION_PANEL, + CMT_GET_CLIPBOARD, + CMT_SET_CLIPBOARD, + + CMT_INJECT_TOUCH, + }; + + ControlMsg(ControlMsgType controlMsgType); + virtual ~ControlMsg(); + + void setInjectKeycodeMsgData(AndroidKeyeventAction action, AndroidKeycode keycode, AndroidMetastate metastate); + void setInjectTextMsgData(QString& text); + void setInjectMouseMsgData(AndroidMotioneventAction action, AndroidMotioneventButtons buttons, QRect position); + // id 代表一个触摸点,最多支持10个触摸点[0,9] + // action 只能是AMOTION_EVENT_ACTION_DOWN,AMOTION_EVENT_ACTION_UP,AMOTION_EVENT_ACTION_MOVE + // position action动作对应的位置 + void setInjectTouchMsgData(quint32 id, AndroidMotioneventAction action, QRect position); + void setInjectScrollMsgData(QRect position, qint32 hScroll, qint32 vScroll); + void setSetClipboardMsgData(QString& text); + + QByteArray serializeData(); + +private: + void writePosition(QBuffer& buffer, const QRect& value); + +private: + struct ControlMsgData { + ControlMsgType type = CMT_NULL; + union { + struct { + AndroidKeyeventAction action; + AndroidKeycode keycode; + AndroidMetastate metastate; + } injectKeycodeMsg; + struct { + char* text = Q_NULLPTR; + } injectTextMsg; + struct { + AndroidMotioneventAction action; + AndroidMotioneventButtons buttons; + QRect position; + } injectMouseMsg; + struct { + quint32 id; + AndroidMotioneventAction action; + QRect position; + } injectTouchMsg; + struct { + QRect position; + qint32 hScroll; + qint32 vScroll; + } injectScrollMsg; + struct { + char *text = Q_NULLPTR; + } setClipboardMsg; + }; + + ControlMsgData(){} + ~ControlMsgData(){} + }; + + ControlMsgData m_data; +}; + +#endif // CONTROLMSG_H diff --git a/QtScrcpy/inputcontrol/deviceevent.cpp b/QtScrcpy/inputcontrol/deviceevent.cpp deleted file mode 100644 index 668fbcf..0000000 --- a/QtScrcpy/inputcontrol/deviceevent.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include - -#include "deviceevent.h" -#include "bufferutil.h" - -DeviceEvent::DeviceEvent(QObject *parent) : QObject(parent) -{ - -} - -DeviceEvent::~DeviceEvent() -{ - if (DET_GET_CLIPBOARD == m_data.type - && Q_NULLPTR != m_data.clipboardEvent.text) { - delete m_data.clipboardEvent.text; - m_data.clipboardEvent.text = Q_NULLPTR; - } -} - -DeviceEvent::DeviceEventType DeviceEvent::type() -{ - return m_data.type; -} - -void DeviceEvent::getClipboardEventData(QString& text) -{ - text = QString::fromUtf8(m_data.clipboardEvent.text); -} - -qint32 DeviceEvent::deserialize(QByteArray& byteArray) -{ - QBuffer buf(&byteArray); - buf.open(QBuffer::ReadOnly); - - qint64 len = buf.size(); - char c = 0; - qint32 ret = 0; - - if (len < 3) { - // at least type + empty string length - return 0; // not available - } - - buf.getChar(&c); - m_data.type = (DeviceEventType)c; - switch (m_data.type) { - case DET_GET_CLIPBOARD: { - quint16 clipboardLen = BufferUtil::read16(buf); - if (clipboardLen > len - 3) { - ret = 0; // not available - break; - } - - QByteArray text = buf.readAll(); - m_data.clipboardEvent.text = new char[text.length() + 1]; - memcpy(m_data.clipboardEvent.text, text.data(), text.length()); - m_data.clipboardEvent.text[text.length()] = '\0'; - - ret = 3 + clipboardLen; - break; - } - default: - qWarning("Unsupported device event type: %d", (int) m_data.type); - ret = -1; // error, we cannot recover - } - - buf.close(); - return ret; -} diff --git a/QtScrcpy/inputcontrol/deviceevent.h b/QtScrcpy/inputcontrol/deviceevent.h deleted file mode 100644 index 7f0be20..0000000 --- a/QtScrcpy/inputcontrol/deviceevent.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef DEVICEEVENT_H -#define DEVICEEVENT_H - -#include - -#define DEVICE_EVENT_QUEUE_SIZE 64 -#define DEVICE_EVENT_TEXT_MAX_LENGTH 4093 -#define DEVICE_EVENT_SERIALIZED_MAX_SIZE (3 + DEVICE_EVENT_TEXT_MAX_LENGTH) - -class DeviceEvent : public QObject -{ - Q_OBJECT -public: - enum DeviceEventType { - DET_NULL = -1, - // 和服务端对应 - DET_GET_CLIPBOARD = 0, - }; - explicit DeviceEvent(QObject *parent = nullptr); - virtual ~DeviceEvent(); - - DeviceEvent::DeviceEventType type(); - void getClipboardEventData(QString& text); - - qint32 deserialize(QByteArray& byteArray); - -private: - struct DeviceEventData { - DeviceEventType type = DET_NULL; - union { - struct { - char* text = Q_NULLPTR; - } clipboardEvent; - }; - DeviceEventData(){} - ~DeviceEventData(){} - }; - - DeviceEventData m_data; -}; - -#endif // DEVICEEVENT_H diff --git a/QtScrcpy/inputcontrol/devicemsg.cpp b/QtScrcpy/inputcontrol/devicemsg.cpp new file mode 100644 index 0000000..9439802 --- /dev/null +++ b/QtScrcpy/inputcontrol/devicemsg.cpp @@ -0,0 +1,69 @@ +#include + +#include "devicemsg.h" +#include "bufferutil.h" + +DeviceMsg::DeviceMsg(QObject *parent) : QObject(parent) +{ + +} + +DeviceMsg::~DeviceMsg() +{ + if (DMT_GET_CLIPBOARD == m_data.type + && Q_NULLPTR != m_data.clipboardMsg.text) { + delete m_data.clipboardMsg.text; + m_data.clipboardMsg.text = Q_NULLPTR; + } +} + +DeviceMsg::DeviceMsgType DeviceMsg::type() +{ + return m_data.type; +} + +void DeviceMsg::getClipboardMsgData(QString& text) +{ + text = QString::fromUtf8(m_data.clipboardMsg.text); +} + +qint32 DeviceMsg::deserialize(QByteArray& byteArray) +{ + QBuffer buf(&byteArray); + buf.open(QBuffer::ReadOnly); + + qint64 len = buf.size(); + char c = 0; + qint32 ret = 0; + + if (len < 3) { + // at least type + empty string length + return 0; // not available + } + + buf.getChar(&c); + m_data.type = (DeviceMsgType)c; + switch (m_data.type) { + case DMT_GET_CLIPBOARD: { + quint16 clipboardLen = BufferUtil::read16(buf); + if (clipboardLen > len - 3) { + ret = 0; // not available + break; + } + + QByteArray text = buf.readAll(); + m_data.clipboardMsg.text = new char[text.length() + 1]; + memcpy(m_data.clipboardMsg.text, text.data(), text.length()); + m_data.clipboardMsg.text[text.length()] = '\0'; + + ret = 3 + clipboardLen; + break; + } + default: + qWarning("Unsupported device msg type: %d", (int) m_data.type); + ret = -1; // error, we cannot recover + } + + buf.close(); + return ret; +} diff --git a/QtScrcpy/inputcontrol/devicemsg.h b/QtScrcpy/inputcontrol/devicemsg.h new file mode 100644 index 0000000..e7fb68a --- /dev/null +++ b/QtScrcpy/inputcontrol/devicemsg.h @@ -0,0 +1,42 @@ +#ifndef DEVICEMSG_H +#define DEVICEMSG_H + +#include + +#define DEVICE_MSG_QUEUE_SIZE 64 +#define DEVICE_MSG_TEXT_MAX_LENGTH 4093 +#define DEVICE_MSG_SERIALIZED_MAX_SIZE (3 + DEVICE_MSG_TEXT_MAX_LENGTH) + +class DeviceMsg : public QObject +{ + Q_OBJECT +public: + enum DeviceMsgType { + DMT_NULL = -1, + // 和服务端对应 + DMT_GET_CLIPBOARD = 0, + }; + explicit DeviceMsg(QObject *parent = nullptr); + virtual ~DeviceMsg(); + + DeviceMsg::DeviceMsgType type(); + void getClipboardMsgData(QString& text); + + qint32 deserialize(QByteArray& byteArray); + +private: + struct DeviceMsgData { + DeviceMsgType type = DMT_NULL; + union { + struct { + char* text = Q_NULLPTR; + } clipboardMsg; + }; + DeviceMsgData(){} + ~DeviceMsgData(){} + }; + + DeviceMsgData m_data; +}; + +#endif // DEVICEMSG_H diff --git a/QtScrcpy/inputcontrol/inputcontrol.pri b/QtScrcpy/inputcontrol/inputcontrol.pri index af7fc9c..0c3d8bb 100644 --- a/QtScrcpy/inputcontrol/inputcontrol.pri +++ b/QtScrcpy/inputcontrol/inputcontrol.pri @@ -1,18 +1,18 @@ HEADERS += \ - $$PWD/controlevent.h \ $$PWD/controller.h \ $$PWD/inputconvertbase.h \ $$PWD/inputconvertgame.h \ $$PWD/inputconvertnormal.h \ - $$PWD/deviceevent.h \ - $$PWD/receiver.h + $$PWD/receiver.h \ + $$PWD/controlmsg.h \ + $$PWD/devicemsg.h SOURCES += \ - $$PWD/controlevent.cpp \ $$PWD/controller.cpp \ $$PWD/inputconvertbase.cpp \ $$PWD/inputconvertgame.cpp \ $$PWD/inputconvertnormal.cpp \ - $$PWD/deviceevent.cpp \ - $$PWD/receiver.cpp + $$PWD/receiver.cpp \ + $$PWD/controlmsg.cpp \ + $$PWD/devicemsg.cpp diff --git a/QtScrcpy/inputcontrol/inputconvertbase.cpp b/QtScrcpy/inputcontrol/inputconvertbase.cpp index 44bda0b..59282d4 100644 --- a/QtScrcpy/inputcontrol/inputconvertbase.cpp +++ b/QtScrcpy/inputcontrol/inputconvertbase.cpp @@ -15,10 +15,10 @@ void InputConvertBase::setControlSocket(QTcpSocket *controlSocket) m_controller.setControlSocket(controlSocket); } -void InputConvertBase::sendControlEvent(ControlEvent *event) +void InputConvertBase::sendControlMsg(ControlMsg *msg) { - if (event) { - m_controller.postControlEvent(event); + if (msg) { + m_controller.postControlMsg(msg); } } diff --git a/QtScrcpy/inputcontrol/inputconvertbase.h b/QtScrcpy/inputcontrol/inputconvertbase.h index 123c6ec..55fb229 100644 --- a/QtScrcpy/inputcontrol/inputconvertbase.h +++ b/QtScrcpy/inputcontrol/inputconvertbase.h @@ -5,7 +5,7 @@ #include #include -#include "controlevent.h" +#include "controlmsg.h" #include "controller.h" class InputConvertBase @@ -21,7 +21,7 @@ public: virtual void keyEvent(const QKeyEvent* from, const QSize& frameSize, const QSize& showSize) = 0; void setControlSocket(QTcpSocket* controlSocket); - void sendControlEvent(ControlEvent* event); + void sendControlMsg(ControlMsg* msg); private: Controller m_controller; diff --git a/QtScrcpy/inputcontrol/inputconvertgame.cpp b/QtScrcpy/inputcontrol/inputconvertgame.cpp index bfb3f1f..c243993 100644 --- a/QtScrcpy/inputcontrol/inputconvertgame.cpp +++ b/QtScrcpy/inputcontrol/inputconvertgame.cpp @@ -111,12 +111,12 @@ void InputConvertGame::sendTouchEvent(int id, QPointF pos, AndroidMotioneventAct if (0 > id || MULTI_TOUCH_MAX_NUM-1 < id) { return; } - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_TOUCH); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_TOUCH); + if (!controlMsg) { return; } - controlEvent->setTouchEventData(id, action, QRect(calcFrameAbsolutePos(pos).toPoint(), m_frameSize)); - sendControlEvent(controlEvent); + controlMsg->setInjectTouchMsgData(id, action, QRect(calcFrameAbsolutePos(pos).toPoint(), m_frameSize)); + sendControlMsg(controlMsg); } QPointF InputConvertGame::calcFrameAbsolutePos(QPointF relativePos) diff --git a/QtScrcpy/inputcontrol/inputconvertnormal.cpp b/QtScrcpy/inputcontrol/inputconvertnormal.cpp index 925f52e..5cb46df 100644 --- a/QtScrcpy/inputcontrol/inputconvertnormal.cpp +++ b/QtScrcpy/inputcontrol/inputconvertnormal.cpp @@ -39,12 +39,12 @@ void InputConvertNormal::mouseEvent(const QMouseEvent* from, const QSize& frameS pos.setY(pos.y() * frameSize.height() / showSize.height()); // set data - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_MOUSE); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_MOUSE); + if (!controlMsg) { return; } - controlEvent->setMouseEventData(action, convertMouseButtons(from->buttons()), QRect(pos.toPoint(), frameSize)); - sendControlEvent(controlEvent); + controlMsg->setInjectMouseMsgData(action, convertMouseButtons(from->buttons()), QRect(pos.toPoint(), frameSize)); + sendControlMsg(controlMsg); } void InputConvertNormal::wheelEvent(const QWheelEvent *from, const QSize& frameSize, const QSize& showSize) @@ -72,12 +72,12 @@ void InputConvertNormal::wheelEvent(const QWheelEvent *from, const QSize& frameS pos.setY(pos.y() * frameSize.height() / showSize.height()); // set data - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_SCROLL); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_SCROLL); + if (!controlMsg) { return; } - controlEvent->setScrollEventData(QRect(pos.toPoint(), frameSize), hScroll, vScroll); - sendControlEvent(controlEvent); + controlMsg->setInjectScrollMsgData(QRect(pos.toPoint(), frameSize), hScroll, vScroll); + sendControlMsg(controlMsg); } void InputConvertNormal::keyEvent(const QKeyEvent *from, const QSize& frameSize, const QSize& showSize) @@ -108,12 +108,12 @@ void InputConvertNormal::keyEvent(const QKeyEvent *from, const QSize& frameSize, } // set data - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_KEYCODE); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_KEYCODE); + if (!controlMsg) { return; } - controlEvent->setKeycodeEventData(action, keyCode, convertMetastate(from->modifiers())); - sendControlEvent(controlEvent); + controlMsg->setInjectKeycodeMsgData(action, keyCode, convertMetastate(from->modifiers())); + sendControlMsg(controlMsg); } AndroidMotioneventButtons InputConvertNormal::convertMouseButtons(Qt::MouseButtons buttonState) diff --git a/QtScrcpy/inputcontrol/receiver.cpp b/QtScrcpy/inputcontrol/receiver.cpp index 51c8cc0..d59a443 100644 --- a/QtScrcpy/inputcontrol/receiver.cpp +++ b/QtScrcpy/inputcontrol/receiver.cpp @@ -4,7 +4,7 @@ #include "receiver.h" #include "controller.h" -#include "deviceevent.h" +#include "devicemsg.h" Receiver::Receiver(Controller* controller) : QObject(controller) { @@ -26,24 +26,24 @@ void Receiver::onReadyRead() while (controlSocket->bytesAvailable()) { QByteArray byteArray = controlSocket->peek(controlSocket->bytesAvailable()); - DeviceEvent deviceEvent; - qint32 consume = deviceEvent.deserialize(byteArray); + DeviceMsg deviceMsg; + qint32 consume = deviceMsg.deserialize(byteArray); if (0 >= consume) { break; } controlSocket->read(consume); - processEvent(&deviceEvent); + processMsg(&deviceMsg); } } -void Receiver::processEvent(DeviceEvent *deviceEvent) +void Receiver::processMsg(DeviceMsg *deviceMsg) { - switch (deviceEvent->type()) { - case DeviceEvent::DET_GET_CLIPBOARD: + switch (deviceMsg->type()) { + case DeviceMsg::DMT_GET_CLIPBOARD: { QClipboard *board = QApplication::clipboard(); QString text; - deviceEvent->getClipboardEventData(text); + deviceMsg->getClipboardMsgData(text); board->setText(text); break; } diff --git a/QtScrcpy/inputcontrol/receiver.h b/QtScrcpy/inputcontrol/receiver.h index ba9bc4c..917ff25 100644 --- a/QtScrcpy/inputcontrol/receiver.h +++ b/QtScrcpy/inputcontrol/receiver.h @@ -4,7 +4,7 @@ #include class Controller; -class DeviceEvent; +class DeviceMsg; class Receiver : public QObject { Q_OBJECT @@ -16,7 +16,7 @@ public slots: void onReadyRead(); protected: - void processEvent(DeviceEvent *deviceEvent); + void processMsg(DeviceMsg *deviceMsg); private: QPointer m_controller; diff --git a/QtScrcpy/videoform.cpp b/QtScrcpy/videoform.cpp index fcc455f..4546d9d 100644 --- a/QtScrcpy/videoform.cpp +++ b/QtScrcpy/videoform.cpp @@ -20,7 +20,7 @@ #include "ui_videoform.h" #include "iconhelper.h" #include "toolform.h" -#include "controlevent.h" +#include "controlmsg.h" #include "mousetap/mousetap.h" VideoForm::VideoForm(const QString& serial, quint16 maxSize, quint32 bitRate, const QString& fileName, QWidget *parent) : @@ -341,50 +341,50 @@ void VideoForm::postVolumeDown() void VideoForm::postTurnOn() { - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_BACK_OR_SCREEN_ON); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_BACK_OR_SCREEN_ON); + if (!controlMsg) { return; } - m_inputConvert.sendControlEvent(controlEvent); + m_inputConvert.sendControlMsg(controlMsg); } void VideoForm::expandNotificationPanel() { - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_EXPAND_NOTIFICATION_PANEL); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_EXPAND_NOTIFICATION_PANEL); + if (!controlMsg) { return; } - m_inputConvert.sendControlEvent(controlEvent); + m_inputConvert.sendControlMsg(controlMsg); } void VideoForm::collapseNotificationPanel() { - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_COLLAPSE_NOTIFICATION_PANEL); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_COLLAPSE_NOTIFICATION_PANEL); + if (!controlMsg) { return; } - m_inputConvert.sendControlEvent(controlEvent); + m_inputConvert.sendControlMsg(controlMsg); } void VideoForm::requestDeviceClipboard() { - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_GET_CLIPBOARD); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_GET_CLIPBOARD); + if (!controlMsg) { return; } - m_inputConvert.sendControlEvent(controlEvent); + m_inputConvert.sendControlMsg(controlMsg); } void VideoForm::setDeviceClipboard() { QClipboard *board = QApplication::clipboard(); QString text = board->text(); - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_SET_CLIPBOARD); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_SET_CLIPBOARD); + if (!controlMsg) { return; } - controlEvent->setSetClipboardEventData(text); - m_inputConvert.sendControlEvent(controlEvent); + controlMsg->setSetClipboardMsgData(text); + m_inputConvert.sendControlMsg(controlMsg); } void VideoForm::clipboardPaste() @@ -396,12 +396,12 @@ void VideoForm::clipboardPaste() void VideoForm::postTextInput(QString& text) { - ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_TEXT); - if (!controlEvent) { + ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_TEXT); + if (!controlMsg) { return; } - controlEvent->setTextEventData(text); - m_inputConvert.sendControlEvent(controlEvent); + controlMsg->setInjectTextMsgData(text); + m_inputConvert.sendControlMsg(controlMsg); } void VideoForm::staysOnTop(bool top) @@ -426,19 +426,19 @@ void VideoForm::postGoHome() void VideoForm::postKeyCodeClick(AndroidKeycode keycode) { - ControlEvent* controlEventDown = new ControlEvent(ControlEvent::CET_KEYCODE); + ControlMsg* controlEventDown = new ControlMsg(ControlMsg::CMT_INJECT_KEYCODE); if (!controlEventDown) { return; } - controlEventDown->setKeycodeEventData(AKEY_EVENT_ACTION_DOWN, keycode, AMETA_NONE); - m_inputConvert.sendControlEvent(controlEventDown); + controlEventDown->setInjectKeycodeMsgData(AKEY_EVENT_ACTION_DOWN, keycode, AMETA_NONE); + m_inputConvert.sendControlMsg(controlEventDown); - ControlEvent* controlEventUp = new ControlEvent(ControlEvent::CET_KEYCODE); + ControlMsg* controlEventUp = new ControlMsg(ControlMsg::CMT_INJECT_KEYCODE); if (!controlEventUp) { return; } - controlEventUp->setKeycodeEventData(AKEY_EVENT_ACTION_UP, keycode, AMETA_NONE); - m_inputConvert.sendControlEvent(controlEventUp); + controlEventUp->setInjectKeycodeMsgData(AKEY_EVENT_ACTION_UP, keycode, AMETA_NONE); + m_inputConvert.sendControlMsg(controlEventUp); } void VideoForm::mousePressEvent(QMouseEvent *event) diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java similarity index 56% rename from server/src/main/java/com/genymobile/scrcpy/ControlEvent.java rename to server/src/main/java/com/genymobile/scrcpy/ControlMessage.java index 1196ea1..73bb4b5 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java @@ -1,21 +1,21 @@ package com.genymobile.scrcpy; /** - * Union of all supported event types, identified by their {@code type}. + * Union of all supported msg types, identified by their {@code type}. */ -public final class ControlEvent { +public final class ControlMessage { - public static final int TYPE_KEYCODE = 0; - public static final int TYPE_TEXT = 1; - public static final int TYPE_MOUSE = 2; - public static final int TYPE_SCROLL = 3; + public static final int TYPE_INJECT_KEYCODE = 0; + public static final int TYPE_INJECT_TEXT = 1; + public static final int TYPE_INJECT_MOUSE = 2; + public static final int TYPE_INJECT_SCROLL = 3; public static final int TYPE_BACK_OR_SCREEN_ON = 4; public static final int TYPE_EXPAND_NOTIFICATION_PANEL = 5; public static final int TYPE_COLLAPSE_NOTIFICATION_PANEL = 6; public static final int TYPE_GET_CLIPBOARD = 7; public static final int TYPE_SET_CLIPBOARD = 8; - public static final int TYPE_TOUCH = 9; + public static final int TYPE_INJECT_TOUCH = 9; private int type; @@ -29,61 +29,61 @@ public final class ControlEvent { private int hScroll; private int vScroll; - private ControlEvent() { + private ControlMessage() { } - public static ControlEvent createKeycodeControlEvent(int action, int keycode, int metaState) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_KEYCODE; + public static ControlMessage createInjectKeycode(int action, int keycode, int metaState) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_KEYCODE; event.action = action; event.keycode = keycode; event.metaState = metaState; return event; } - public static ControlEvent createTextControlEvent(String text) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_TEXT; + public static ControlMessage createInjectText(String text) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_TEXT; event.text = text; return event; } - public static ControlEvent createMotionControlEvent(int action, int buttons, Position position) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_MOUSE; + public static ControlMessage createInjectMotion(int action, int buttons, Position position) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_MOUSE; event.action = action; event.buttons = buttons; event.position = position; return event; } - public static ControlEvent createMotionTouchEvent(int id, int action, Position position) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_TOUCH; + public static ControlMessage createInjectMotionTouch(int id, int action, Position position) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_TOUCH; event.action = action; event.id = id; event.position = position; return event; } - public static ControlEvent createScrollControlEvent(Position position, int hScroll, int vScroll) { - ControlEvent event = new ControlEvent(); - event.type = TYPE_SCROLL; + public static ControlMessage createInjectScroll(Position position, int hScroll, int vScroll) { + ControlMessage event = new ControlMessage(); + event.type = TYPE_INJECT_SCROLL; event.position = position; event.hScroll = hScroll; event.vScroll = vScroll; return event; } - public static ControlEvent createSetClipboardControlEvent(String text) { - ControlEvent event = new ControlEvent(); + public static ControlMessage createSetClipboard(String text) { + ControlMessage event = new ControlMessage(); event.type = TYPE_SET_CLIPBOARD; event.text = text; return event; } - public static ControlEvent createSimpleControlEvent(int type) { - ControlEvent event = new ControlEvent(); + public static ControlMessage createEmpty(int type) { + ControlMessage event = new ControlMessage(); event.type = type; return event; } diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java similarity index 60% rename from server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java rename to server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java index f4688c0..c06b599 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java @@ -6,12 +6,12 @@ import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -public class ControlEventReader { +public class ControlMessageReader { - private static final int KEYCODE_PAYLOAD_LENGTH = 9; - 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 INJECT_KEYCODE_PAYLOAD_LENGTH = 9; + private static final int INJECT_MOUSE_PAYLOAD_LENGTH = 13; + private static final int INJECT_SCROLL_PAYLOAD_LENGTH = 16; + private static final int INJECT_TOUCH_PAYLOAD_LENGTH = 10; public static final int TEXT_MAX_LENGTH = 300; public static final int CLIPBOARD_TEXT_MAX_LENGTH = 4093; @@ -21,7 +21,7 @@ public class ControlEventReader { private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer); private final byte[] textBuffer = new byte[CLIPBOARD_TEXT_MAX_LENGTH]; - public ControlEventReader() { + public ControlMessageReader() { // invariant: the buffer is always in "get" mode buffer.limit(0); } @@ -38,43 +38,43 @@ public class ControlEventReader { int head = buffer.position(); int r = input.read(rawBuffer, head, rawBuffer.length - head); if (r == -1) { - throw new EOFException("Event controller socket closed"); + throw new EOFException("Controller socket closed"); } buffer.position(head + r); buffer.flip(); } - public ControlEvent next() { + public ControlMessage next() { if (!buffer.hasRemaining()) { return null; } int savedPosition = buffer.position(); int type = buffer.get(); - ControlEvent controlEvent; + ControlMessage controlEvent; switch (type) { - case ControlEvent.TYPE_KEYCODE: - controlEvent = parseKeycodeControlEvent(); + case ControlMessage.TYPE_INJECT_KEYCODE: + controlEvent = parseInjectKeycode(); break; - case ControlEvent.TYPE_TEXT: - controlEvent = parseTextControlEvent(); + case ControlMessage.TYPE_INJECT_TEXT: + controlEvent = parseInjectText(); break; - case ControlEvent.TYPE_MOUSE: - controlEvent = parseMouseControlEvent(); + case ControlMessage.TYPE_INJECT_MOUSE: + controlEvent = parseInjectMouse(); break; - case ControlEvent.TYPE_TOUCH: - controlEvent = parseMouseTouchEvent(); + case ControlMessage.TYPE_INJECT_TOUCH: + controlEvent = parseInjectMouseTouch(); break; - case ControlEvent.TYPE_SCROLL: - controlEvent = parseScrollControlEvent(); + case ControlMessage.TYPE_INJECT_SCROLL: + controlEvent = parseInjectScroll(); break; - case ControlEvent.TYPE_SET_CLIPBOARD: - controlEvent = parseSetClipboardEvent(); + case ControlMessage.TYPE_SET_CLIPBOARD: + controlEvent = parseSetClipboard(); break; - case ControlEvent.TYPE_BACK_OR_SCREEN_ON: - case ControlEvent.TYPE_EXPAND_NOTIFICATION_PANEL: - case ControlEvent.TYPE_COLLAPSE_NOTIFICATION_PANEL: - case ControlEvent.TYPE_GET_CLIPBOARD: - controlEvent = ControlEvent.createSimpleControlEvent(type); + case ControlMessage.TYPE_BACK_OR_SCREEN_ON: + case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL: + case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL: + case ControlMessage.TYPE_GET_CLIPBOARD: + controlEvent = ControlMessage.createEmpty(type); break; default: Ln.w("Unknown event type: " + type); @@ -89,14 +89,14 @@ public class ControlEventReader { return controlEvent; } - private ControlEvent parseKeycodeControlEvent() { - if (buffer.remaining() < KEYCODE_PAYLOAD_LENGTH) { + private ControlMessage parseInjectKeycode() { + if (buffer.remaining() < INJECT_KEYCODE_PAYLOAD_LENGTH) { return null; } int action = toUnsigned(buffer.get()); int keycode = buffer.getInt(); int metaState = buffer.getInt(); - return ControlEvent.createKeycodeControlEvent(action, keycode, metaState); + return ControlMessage.createInjectKeycode(action, keycode, metaState); } private String parseString() { @@ -111,50 +111,50 @@ public class ControlEventReader { return new String(textBuffer, 0, len, StandardCharsets.UTF_8); } - private ControlEvent parseTextControlEvent() { + private ControlMessage parseInjectText() { String text = parseString(); if (text == null) { return null; } - return ControlEvent.createTextControlEvent(text); + return ControlMessage.createInjectText(text); } - private ControlEvent parseMouseControlEvent() { - if (buffer.remaining() < MOUSE_PAYLOAD_LENGTH) { + private ControlMessage parseInjectMouse() { + if (buffer.remaining() < INJECT_MOUSE_PAYLOAD_LENGTH) { return null; } int action = toUnsigned(buffer.get()); int buttons = buffer.getInt(); Position position = readPosition(buffer); - return ControlEvent.createMotionControlEvent(action, buttons, position); + return ControlMessage.createInjectMotion(action, buttons, position); } - private ControlEvent parseMouseTouchEvent() { - if (buffer.remaining() < TOUCH_PAYLOAD_LENGTH) { + private ControlMessage parseInjectMouseTouch() { + if (buffer.remaining() < INJECT_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); + return ControlMessage.createInjectMotionTouch(id, action, position); } - private ControlEvent parseScrollControlEvent() { - if (buffer.remaining() < SCROLL_PAYLOAD_LENGTH) { + private ControlMessage parseInjectScroll() { + if (buffer.remaining() < INJECT_SCROLL_PAYLOAD_LENGTH) { return null; } Position position = readPosition(buffer); int hScroll = buffer.getInt(); int vScroll = buffer.getInt(); - return ControlEvent.createScrollControlEvent(position, hScroll, vScroll); + return ControlMessage.createInjectScroll(position, hScroll, vScroll); } - private ControlEvent parseSetClipboardEvent() { + private ControlMessage parseSetClipboard() { String text = parseString(); if (text == null) { return null; } - return ControlEvent.createSetClipboardControlEvent(text); + return ControlMessage.createSetClipboard(text); } private static Position readPosition(ByteBuffer buffer) { diff --git a/server/src/main/java/com/genymobile/scrcpy/EventController.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java similarity index 87% rename from server/src/main/java/com/genymobile/scrcpy/EventController.java rename to server/src/main/java/com/genymobile/scrcpy/Controller.java index 0bf6055..5aeb252 100644 --- a/server/src/main/java/com/genymobile/scrcpy/EventController.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -13,11 +13,11 @@ import android.view.MotionEvent; import java.io.IOException; import java.util.Vector; -public class EventController { +public class Controller { private final Device device; private final DesktopConnection connection; - private final EventSender sender; + private final DeviceMessageSender sender; private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); @@ -25,10 +25,10 @@ public class EventController { private Vector pointerProperties = new Vector(); private Vector pointerCoords = new Vector(); - public EventController(Device device, DesktopConnection connection) { + public Controller(Device device, DesktopConnection connection) { this.device = device; this.connection = connection; - sender = new EventSender(connection); + sender = new DeviceMessageSender(connection); } private int getPointer(int id) { @@ -98,7 +98,7 @@ public class EventController { } } - public EventSender getSender() { + public DeviceMessageSender getSender() { return sender; } @@ -112,38 +112,38 @@ public class EventController { } private void handleEvent() throws IOException { - ControlEvent controlEvent = connection.receiveControlEvent(); - switch (controlEvent.getType()) { - case ControlEvent.TYPE_KEYCODE: - injectKeycode(controlEvent.getAction(), controlEvent.getKeycode(), controlEvent.getMetaState()); + ControlMessage msg = connection.receiveControlMessage(); + switch (msg.getType()) { + case ControlMessage.TYPE_INJECT_KEYCODE: + injectKeycode(msg.getAction(), msg.getKeycode(), msg.getMetaState()); break; - case ControlEvent.TYPE_TEXT: - injectText(controlEvent.getText()); + case ControlMessage.TYPE_INJECT_TEXT: + injectText(msg.getText()); break; - case ControlEvent.TYPE_MOUSE: - injectMouse(controlEvent.getAction(), controlEvent.getButtons(), controlEvent.getPosition()); + case ControlMessage.TYPE_INJECT_MOUSE: + injectMouse(msg.getAction(), msg.getButtons(), msg.getPosition()); break; - case ControlEvent.TYPE_TOUCH: - injectTouch(controlEvent.getId(), controlEvent.getAction(), controlEvent.getPosition()); + case ControlMessage.TYPE_INJECT_TOUCH: + injectTouch(msg.getId(), msg.getAction(), msg.getPosition()); break; - case ControlEvent.TYPE_SCROLL: - injectScroll(controlEvent.getPosition(), controlEvent.getHScroll(), controlEvent.getVScroll()); + case ControlMessage.TYPE_INJECT_SCROLL: + injectScroll(msg.getPosition(), msg.getHScroll(), msg.getVScroll()); break; - case ControlEvent.TYPE_BACK_OR_SCREEN_ON: + case ControlMessage.TYPE_BACK_OR_SCREEN_ON: pressBackOrTurnScreenOn(); break; - case ControlEvent.TYPE_EXPAND_NOTIFICATION_PANEL: + case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL: device.expandNotificationPanel(); break; - case ControlEvent.TYPE_COLLAPSE_NOTIFICATION_PANEL: + case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL: device.collapsePanels(); break; - case ControlEvent.TYPE_GET_CLIPBOARD: + case ControlMessage.TYPE_GET_CLIPBOARD: String clipboardText = device.getClipboardText(); sender.pushClipboardText(clipboardText); break; - case ControlEvent.TYPE_SET_CLIPBOARD: - device.setClipboardText(controlEvent.getText()); + case ControlMessage.TYPE_SET_CLIPBOARD: + device.setClipboardText(msg.getText()); break; default: // do nothing diff --git a/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java b/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java index 99aa9d2..e375cf5 100644 --- a/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java +++ b/server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java @@ -25,8 +25,8 @@ public final class DesktopConnection implements Closeable { private final OutputStream controlOutputStream; - private final ControlEventReader reader = new ControlEventReader(); - private final DeviceEventWriter writer = new DeviceEventWriter(); + private final ControlMessageReader reader = new ControlMessageReader(); + private final DeviceMessageWriter writer = new DeviceMessageWriter(); private DesktopConnection(LocalSocket videoSocket, LocalSocket controlSocket) throws IOException { this.videoSocket = videoSocket; @@ -105,16 +105,16 @@ public final class DesktopConnection implements Closeable { return videoFd; } - public ControlEvent receiveControlEvent() throws IOException { - ControlEvent event = reader.next(); - while (event == null) { + public ControlMessage receiveControlMessage() throws IOException { + ControlMessage msg = reader.next(); + while (msg == null) { reader.readFrom(controlInputStream); - event = reader.next(); + msg = reader.next(); } - return event; + return msg; } - public void sendDeviceEvent(DeviceEvent event) throws IOException { - writer.writeTo(event, controlOutputStream); + public void sendDeviceMessage(DeviceMessage msg) throws IOException { + writer.writeTo(msg, controlOutputStream); } } diff --git a/server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java b/server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java deleted file mode 100644 index 97bcbfc..0000000 --- a/server/src/main/java/com/genymobile/scrcpy/DeviceEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.genymobile.scrcpy; - -public final class DeviceEvent { - - public static final int TYPE_GET_CLIPBOARD = 0; - - private int type; - private String text; - - private DeviceEvent() { - } - - public static DeviceEvent createGetClipboardEvent(String text) { - DeviceEvent event = new DeviceEvent(); - event.type = TYPE_GET_CLIPBOARD; - event.text = text; - return event; - } - - public int getType() { - return type; - } - - public String getText() { - return text; - } -} diff --git a/server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java b/server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java new file mode 100644 index 0000000..c6eebd3 --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/DeviceMessage.java @@ -0,0 +1,27 @@ +package com.genymobile.scrcpy; + +public final class DeviceMessage { + + public static final int TYPE_CLIPBOARD = 0; + + private int type; + private String text; + + private DeviceMessage() { + } + + public static DeviceMessage createClipboard(String text) { + DeviceMessage event = new DeviceMessage(); + event.type = TYPE_CLIPBOARD; + event.text = text; + return event; + } + + public int getType() { + return type; + } + + public String getText() { + return text; + } +} diff --git a/server/src/main/java/com/genymobile/scrcpy/EventSender.java b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageSender.java similarity index 74% rename from server/src/main/java/com/genymobile/scrcpy/EventSender.java rename to server/src/main/java/com/genymobile/scrcpy/DeviceMessageSender.java index 9f50b16..846bc43 100644 --- a/server/src/main/java/com/genymobile/scrcpy/EventSender.java +++ b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageSender.java @@ -2,13 +2,13 @@ package com.genymobile.scrcpy; import java.io.IOException; -public final class EventSender { +public final class DeviceMessageSender { private final DesktopConnection connection; private String clipboardText; - public EventSender(DesktopConnection connection) { + public DeviceMessageSender(DesktopConnection connection) { this.connection = connection; } @@ -27,8 +27,8 @@ public final class EventSender { text = clipboardText; clipboardText = null; } - DeviceEvent event = DeviceEvent.createGetClipboardEvent(text); - connection.sendDeviceEvent(event); + DeviceMessage msg = DeviceMessage.createClipboard(text); + connection.sendDeviceMessage(msg); } } } diff --git a/server/src/main/java/com/genymobile/scrcpy/DeviceEventWriter.java b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageWriter.java similarity index 72% rename from server/src/main/java/com/genymobile/scrcpy/DeviceEventWriter.java rename to server/src/main/java/com/genymobile/scrcpy/DeviceMessageWriter.java index e183a22..6b11a51 100644 --- a/server/src/main/java/com/genymobile/scrcpy/DeviceEventWriter.java +++ b/server/src/main/java/com/genymobile/scrcpy/DeviceMessageWriter.java @@ -5,7 +5,7 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -public class DeviceEventWriter { +public class DeviceMessageWriter { public static final int CLIPBOARD_TEXT_MAX_LENGTH = 4093; private static final int MAX_EVENT_SIZE = CLIPBOARD_TEXT_MAX_LENGTH + 3; @@ -14,12 +14,12 @@ public class DeviceEventWriter { private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer); @SuppressWarnings("checkstyle:MagicNumber") - public void writeTo(DeviceEvent event, OutputStream output) throws IOException { + public void writeTo(DeviceMessage msg, OutputStream output) throws IOException { buffer.clear(); - buffer.put((byte) DeviceEvent.TYPE_GET_CLIPBOARD); - switch (event.getType()) { - case DeviceEvent.TYPE_GET_CLIPBOARD: - String text = event.getText(); + buffer.put((byte) DeviceMessage.TYPE_CLIPBOARD); + switch (msg.getType()) { + case DeviceMessage.TYPE_CLIPBOARD: + String text = msg.getText(); byte[] raw = text.getBytes(StandardCharsets.UTF_8); int len = StringUtils.getUtf8TruncationIndex(raw, CLIPBOARD_TEXT_MAX_LENGTH); buffer.putShort((short) len); @@ -27,7 +27,7 @@ public class DeviceEventWriter { output.write(rawBuffer, 0, buffer.position()); break; default: - Ln.w("Unknown device event: " + event.getType()); + Ln.w("Unknown device msg: " + msg.getType()); break; } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index ed8a40f..95dbdb3 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -20,11 +20,11 @@ public final class Server { try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) { ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate()); - EventController controller = new EventController(device, connection); + Controller controller = new Controller(device, connection); // asynchronous - startEventController(controller); - startEventSender(controller.getSender()); + startController(controller); + startDeviceMessageSender(controller.getSender()); try { // synchronous @@ -36,7 +36,7 @@ public final class Server { } } - private static void startEventController(final EventController controller) { + private static void startController(final Controller controller) { new Thread(new Runnable() { @Override public void run() { @@ -44,13 +44,13 @@ public final class Server { controller.control(); } catch (IOException e) { // this is expected on close - Ln.d("Event controller stopped"); + Ln.d("Controller stopped"); } } }).start(); } - private static void startEventSender(final EventSender sender) { + private static void startDeviceMessageSender(final DeviceMessageSender sender) { new Thread(new Runnable() { @Override public void run() { @@ -58,7 +58,7 @@ public final class Server { sender.loop(); } catch (IOException | InterruptedException e) { // this is expected on close - Ln.d("Event sender stopped"); + Ln.d("Devide message sender stopped"); } } }).start(); diff --git a/server/src/test/java/com/genymobile/scrcpy/ControlEventReaderTest.java b/server/src/test/java/com/genymobile/scrcpy/ControlEventReaderTest.java deleted file mode 100644 index 3e97096..0000000 --- a/server/src/test/java/com/genymobile/scrcpy/ControlEventReaderTest.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.genymobile.scrcpy; - -import android.view.KeyEvent; -import android.view.MotionEvent; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - - -public class ControlEventReaderTest { - - @Test - public void testParseKeycodeEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_KEYCODE); - dos.writeByte(KeyEvent.ACTION_UP); - dos.writeInt(KeyEvent.KEYCODE_ENTER); - dos.writeInt(KeyEvent.META_CTRL_ON); - byte[] packet = bos.toByteArray(); - - reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); - - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); - Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction()); - Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode()); - Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); - } - - @Test - public void testParseTextEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_TEXT); - byte[] text = "testé".getBytes(StandardCharsets.UTF_8); - dos.writeShort(text.length); - dos.write(text); - byte[] packet = bos.toByteArray(); - - reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); - - Assert.assertEquals(ControlEvent.TYPE_TEXT, event.getType()); - Assert.assertEquals("testé", event.getText()); - } - - @Test - public void testParseLongTextEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_TEXT); - byte[] text = new byte[ControlEventReader.TEXT_MAX_LENGTH]; - Arrays.fill(text, (byte) 'a'); - dos.writeShort(text.length); - dos.write(text); - byte[] packet = bos.toByteArray(); - - reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); - - Assert.assertEquals(ControlEvent.TYPE_TEXT, event.getType()); - Assert.assertEquals(new String(text, StandardCharsets.US_ASCII), event.getText()); - } - - @Test - public void testParseMouseEvent() throws IOException { - ControlEventReader reader = new ControlEventReader(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - dos.writeByte(ControlEvent.TYPE_KEYCODE); - dos.writeByte(MotionEvent.ACTION_DOWN); - dos.writeInt(MotionEvent.BUTTON_PRIMARY); - dos.writeInt(KeyEvent.META_CTRL_ON); - byte[] packet = bos.toByteArray(); - - reader.readFrom(new ByteArrayInputStream(packet)); - ControlEvent event = reader.next(); - - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); - Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction()); - Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode()); - Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); - } - - @Test - public void testMultiEvents() throws IOException { - ControlEventReader reader = new ControlEventReader(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - - dos.writeByte(ControlEvent.TYPE_KEYCODE); - dos.writeByte(KeyEvent.ACTION_UP); - dos.writeInt(KeyEvent.KEYCODE_ENTER); - dos.writeInt(KeyEvent.META_CTRL_ON); - - dos.writeByte(ControlEvent.TYPE_KEYCODE); - dos.writeByte(MotionEvent.ACTION_DOWN); - dos.writeInt(MotionEvent.BUTTON_PRIMARY); - dos.writeInt(KeyEvent.META_CTRL_ON); - - byte[] packet = bos.toByteArray(); - reader.readFrom(new ByteArrayInputStream(packet)); - - ControlEvent event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); - Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction()); - Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode()); - Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); - - event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); - Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction()); - Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode()); - Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); - } - - @Test - public void testPartialEvents() throws IOException { - ControlEventReader reader = new ControlEventReader(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(bos); - - dos.writeByte(ControlEvent.TYPE_KEYCODE); - dos.writeByte(KeyEvent.ACTION_UP); - dos.writeInt(KeyEvent.KEYCODE_ENTER); - dos.writeInt(KeyEvent.META_CTRL_ON); - - dos.writeByte(ControlEvent.TYPE_KEYCODE); - dos.writeByte(MotionEvent.ACTION_DOWN); - - byte[] packet = bos.toByteArray(); - reader.readFrom(new ByteArrayInputStream(packet)); - - ControlEvent event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); - Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction()); - Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode()); - Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); - - event = reader.next(); - Assert.assertNull(event); // the event is not complete - - bos.reset(); - dos.writeInt(MotionEvent.BUTTON_PRIMARY); - dos.writeInt(KeyEvent.META_CTRL_ON); - packet = bos.toByteArray(); - reader.readFrom(new ByteArrayInputStream(packet)); - - // the event is now complete - event = reader.next(); - Assert.assertEquals(ControlEvent.TYPE_KEYCODE, event.getType()); - Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction()); - Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode()); - Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState()); - } -} diff --git a/third_party/scrcpy-server.jar b/third_party/scrcpy-server.jar index 5f8ad87..aaad381 100644 Binary files a/third_party/scrcpy-server.jar and b/third_party/scrcpy-server.jar differ