Merge pull request #438 from barry-ran/dev

Dev
This commit is contained in:
Barry 2021-06-28 12:13:17 +08:00 committed by GitHub
commit e20d07fbf0
40 changed files with 980 additions and 266 deletions

21
CMakeLists.txt Executable file
View file

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
# Read version numbers from file
file (STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/QtScrcpy/version STRING_VERSION)
message(STATUS "QtScrcpy Version ${STRING_VERSION}")
project(QtScrcpy
VERSION ${STRING_VERSION}
LANGUAGES C CXX
)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
enable_language(OBJCXX)
endif()
# Split version numbers
string(REPLACE "." ";" VERSION_LIST ${STRING_VERSION})
list(GET VERSION_LIST 0 VERSION_MAJOR)
list(GET VERSION_LIST 1 VERSION_MINOR)
list(GET VERSION_LIST 2 VERSION_PATCH)
add_subdirectory(QtScrcpy)

318
QtScrcpy/CMakeLists.txt Executable file
View file

@ -0,0 +1,318 @@
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ***********************************************************
# Qt Package finding
# ***********************************************************
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Network LinguistTools REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Network LinguistTools REQUIRED)
# ***********************************************************
# Cross-platform settings
# ***********************************************************
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# FFmpeg cannot be compiled natively by MSVC version < 12.0 (2013)
if(MSVC_VERSION LESS 1800)
message(FATAL_ERROR "[QtScrcpy] FATAL ERROR: MSVC version is older than 12.0 (2013).")
endif()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
endif()
# ==================== macOS ====================
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# QS_MAC_RESOURCES: esource file list stored in Contents/MacOS
file(GLOB QS_MAC_RESOURCES "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/lib/*.dylib")
list(APPEND QS_MAC_RESOURCES
"${PROJECT_SOURCE_DIR}/third_party/scrcpy-server"
"${PROJECT_SOURCE_DIR}/adb/mac/adb"
)
# QS_MAC_CONFIG: Config file stored in Contents/MacOS/config
set(QS_MAC_CONFIG "${PROJECT_SOURCE_DIR}/config/config.ini")
endif()
set(QS_TS_FILES
${CMAKE_CURRENT_SOURCE_DIR}/res/i18n/zh_CN.ts
${CMAKE_CURRENT_SOURCE_DIR}/res/i18n/en_US.ts
)
set_source_files_properties(${QS_TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/res/i18n")
set(QS_SOURCES_MAIN
dialog.cpp
dialog.h
dialog.ui
${QS_TS_FILES}
)
set(QS_QRC_MAIN "${CMAKE_CURRENT_SOURCE_DIR}/res/res.qrc")
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) # Qt version 6
qt_create_translation(QS_QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${QS_TS_FILES})
if(WIN32)
qt_add_executable(${CMAKE_PROJECT_NAME} WIN32 MANUAL_FINALIZATION
main.cpp
${QS_SOURCES_MAIN}
${QS_QRC_MAIN}
)
elseif(UNIX)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
qt_add_executable(${CMAKE_PROJECT_NAME} MACOSX_BUNDLE MANUAL_FINALIZATION
main.cpp
${QS_SOURCES_MAIN}
${QS_MAC_RESOURCES}
${QS_MAC_CONFIG}
${QS_QRC_MAIN}
)
else()
qt_add_executable(${CMAKE_PROJECT_NAME} MANUAL_FINALIZATION
main.cpp
${QS_SOURCES_MAIN}
${QS_QRC_MAIN}
)
endif()
endif()
else() # Qt version 5
qt5_create_translation(QS_QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${QS_TS_FILES})
if(WIN32)
add_executable(${CMAKE_PROJECT_NAME} WIN32
main.cpp
${QS_SOURCES_MAIN}
${QS_QRC_MAIN}
)
elseif(UNIX)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_executable(${CMAKE_PROJECT_NAME} MACOSX_BUNDLE
main.cpp
${QS_SOURCES_MAIN}
${QS_MAC_RESOURCES}
${QS_MAC_CONFIG}
${QS_QRC_MAIN}
)
else()
add_executable(${CMAKE_PROJECT_NAME}
main.cpp
${QS_SOURCES_MAIN}
${QS_QRC_MAIN}
)
endif()
endif()
endif()
# ******************** Microsoft Windows ********************
if(WIN32)
message(STATUS "[QtScrcpy] Make for Microsoft Windows.")
# 通过rc的方式的话VERSION变量rc中获取不到,定义为宏方便rc中使用
# Define macros for .rc file
add_compile_definitions(
VERSION_MAJOR=${VERSION_MAJOR}
VERSION_MINOR=${VERSION_MINOR}
VERSION_PATCH=${VERSION_PATCH}
VERSION_RC_STR=\\\"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}\\\"
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # Compiler is 64-bit
message(STATUS "[QtScrcpy] 64-bit compiler detected.")
set(QS_LIB_PATH "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/lib/x64")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "[QtScrcpy] In debug mode.")
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/win/x64/debug"
)
else()
message(STATUS "[QtScrcpy] In release mode.")
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/win/x64/release")
endif()
set(QS_DLL_PATH "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/bin/x64")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) # Compiler is 32-bit
message(STATUS "[QtScrcpy] 32-bit compiler detected.")
set(QS_LIB_PATH "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/lib/x86")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "[QtScrcpy] In debug mode.")
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/win/x86/debug")
else()
message(STATUS "[QtScrcpy] In release mode.")
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/win/x86/release")
endif()
set(QS_DLL_PATH "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/bin/x86")
endif()
# 构建完成后复制DLL依赖库
# Copy DLL dependencies after building
get_target_property(QS_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_PROJECT_NAME} RUNTIME_OUTPUT_DIRECTORY)
file(GLOB QS_DLL_FILES "${QS_DLL_PATH}/*.dll")
foreach(QS_DLL_FILE ${QS_DLL_FILES})
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND
${CMAKE_COMMAND} -E copy_if_different
"${QS_DLL_FILE}" "${QS_RUNTIME_OUTPUT_DIRECTORY}"
)
endforeach()
# If MinGW is used, it is not appropriate to link static MSVC libs.
# Instead, we link DLLs directly
if(MSVC)
message(STATUS "[QtScrcpy] Microsoft Visual C++ is used.")
link_directories(${QS_LIB_PATH})
set(QS_EXTERNAL_LIBS_FFMPEG
avformat
avcodec
avutil
swscale
)
elseif(MINGW)
message(STATUS "[QtScrcpy] MinGW GCC is used.")
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
"-static"
${QS_DLL_FILES}
"-Wl,--enable-stdcall-fixup"
)
endif()
set(RC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/QtScrcpy.rc")
# ******************** Unix-like OSs ********************
elseif(UNIX)
set(QS_LIB_PATH "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/lib")
# ==================== macOS ====================
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(STATUS "[QtScrcpy] Make for macOS.")
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE ${QS_LIB_PATH})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/mac/debug")
else()
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/mac/release")
endif()
# Icon file stored in Contents/Resources
set(QS_MAC_ICON_NAME "QtScrcpy.icns")
set(QS_MAC_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/res/${QS_MAC_ICON_NAME}")
set_source_files_properties(${QS_MAC_RESOURCES} PROPERTIES
MACOSX_PACKAGE_LOCATION "MacOS"
)
set_source_files_properties(${QS_MAC_CONFIG} PROPERTIES
MACOSX_PACKAGE_LOCATION "MacOS/config"
)
set(QS_EXTERNAL_LIBS_FFMPEG
avformat.58
avcodec.58
avutil.56
swscale.5
)
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
# The base plist template file
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/res/Info_Mac.plist"
# The elements to be overwritten
MACOSX_BUNDLE_ICON_FILE "${QS_MAC_ICON_NAME}"
MACOSX_BUNDLE_BUNDLE_VERSION "${STRING_VERSION}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${STRING_VERSION}"
MACOSX_BUNDLE_LONG_VERSION_STRING "${STRING_VERSION}"
# Copy file(s) to Contents/Resources
RESOURCE "${QS_MAC_ICON_PATH}"
)
# =============== Non-Mac OSs (Linux, BSD, etc.) ===============
else()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/linux/debug")
else()
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/output/linux/release")
endif()
find_package(Threads REQUIRED)
message(STATUS "[QtScrcpy] Make for non-Mac Unix-like OS.")
set(INSTALLED_FFMPEG_FOUND false)
find_package(PkgConfig)
if(PkgConfig_FOUND)
pkg_check_modules(FFmpeg libavformat>=58 libavcodec>=58 libavutil>=56 libswscale>=5)
if(FFmpeg_FOUND)
set(INSTALLED_FFMPEG_FOUND true)
message(STATUS "[QtScrcpy] Development files of FFmpeg were detected in your OS and will be used.")
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE ${FFmpeg_LDFLAGS})
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE ${FFmpeg_CFLAGS})
set(QS_EXTERNAL_LIBS_FFMPEG ${FFmpeg_LIBRARIES})
endif()
endif()
if(NOT INSTALLED_FFMPEG_FOUND)
message(STATUS "[QtScrcpy] Development files of FFmpeg were not detected in your OS. Files within third_party/ffmpeg/ will be used.")
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE ${QS_LIB_PATH})
set(QS_EXTERNAL_LIBS_FFMPEG
avformat
avcodec
avutil
swscale
Threads::Threads
)
endif()
endif()
endif()
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
set(QS_SUBDIRECTORIES_MAIN
adb
common
device
devicemanage
fontawesome
uibase
util
)
foreach(QS_SUBDIRECTORY_MAIN ${QS_SUBDIRECTORIES_MAIN})
add_subdirectory(${QS_SUBDIRECTORY_MAIN})
endforeach()
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC
adb
devicemanage
)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Network
device
stream
ui
util
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(${CMAKE_PROJECT_NAME})
endif()

View file

@ -48,10 +48,6 @@ HEADERS += \
FORMS += \
dialog.ui
# 试用检查
# DEFINES += TRIAL_EXPIRE_CHECK
DEFINES += TRIAL_TIMES=10
# 子工程
include ($$PWD/common/common.pri)
include ($$PWD/adb/adb.pri)

11
QtScrcpy/adb/CMakeLists.txt Executable file
View file

@ -0,0 +1,11 @@
set(QS_SOURCES_ADB
adbprocess.h
adbprocess.cpp
)
add_library(adb ${QS_SOURCES_ADB})
target_include_directories(adb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(adb PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
util
)

6
QtScrcpy/common/CMakeLists.txt Executable file
View file

@ -0,0 +1,6 @@
set(QS_SOURCES_COMMON
qscrcpyevent.h
)
add_library(common INTERFACE ${QS_SOURCES_COMMON})
target_include_directories(common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

40
QtScrcpy/device/CMakeLists.txt Executable file
View file

@ -0,0 +1,40 @@
set(QS_SUBDIRECTORIES_DEVICE
android
controller
decoder
filehandler
recorder
render
server
stream
ui
)
set(QS_SOURCES_DEVICE
device.h
device.cpp
)
add_library(device ${QS_SOURCES_DEVICE})
target_include_directories(device PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
foreach(QS_SUBDIRECTORY_DEVICE ${QS_SUBDIRECTORIES_DEVICE})
add_subdirectory (${QS_SUBDIRECTORY_DEVICE})
endforeach()
target_link_libraries(device INTERFACE inputconvert)
target_link_libraries(device PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
# device (self)
controller
decoder
filehandler
recorder
server
stream
ui
util
mousetap
)

View file

@ -0,0 +1,7 @@
set(QS_SOURCES_DEVICE_ANDROID
input.h
keycodes.h
)
add_library(android INTERFACE ${QS_SOURCES_DEVICE_ANDROID})
target_include_directories(android INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

View file

@ -0,0 +1,26 @@
SET(QS_SUBDIRECTORIES_DEVICE_CONTROLLER
inputconvert
receiver
)
SET(QS_SOURCES_DEVICE_CONTROLLER
controller.h
controller.cpp
)
add_library(controller ${QS_SOURCES_DEVICE_CONTROLLER})
target_include_directories(controller PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
foreach(QS_SUBDIRECTORY_DEVICE_CONTROLLER ${QS_SUBDIRECTORIES_DEVICE_CONTROLLER})
add_subdirectory (${QS_SUBDIRECTORY_DEVICE_CONTROLLER})
endforeach()
target_link_libraries(controller PUBLIC
inputconvert
)
target_link_libraries(controller PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
receiver
server
)

View file

@ -0,0 +1,39 @@
SET(QS_SUBDIRECTORIES_DEVICE_CONTROLLER_INPUTCONVERT
keymap
)
set(QS_SOURCES_DEVICE_CONTROLLER_INPUTCONVERT
controlmsg.h
controlmsg.cpp
inputconvertbase.h
inputconvertbase.cpp
inputconvertgame.h
inputconvertgame.cpp
inputconvertnormal.h
inputconvertnormal.cpp
)
add_library(inputconvert ${QS_SOURCES_DEVICE_CONTROLLER_INPUTCONVERT})
target_include_directories(inputconvert PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
foreach(QS_SUBDIRECTORY_DEVICE_CONTROLLER_INPUTCONVERT ${QS_SUBDIRECTORIES_DEVICE_CONTROLLER_INPUTCONVERT})
add_subdirectory (${QS_SUBDIRECTORY_DEVICE_CONTROLLER_INPUTCONVERT})
endforeach()
target_link_libraries(inputconvert PUBLIC
common
# controller
android
)
target_link_libraries(inputconvert INTERFACE
# controller
# inputconvert (self)
keymap
)
target_link_libraries(inputconvert PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
controller
util
)

View file

@ -2,12 +2,18 @@
#include <QCursor>
#include <QGuiApplication>
#include <QTimer>
#include <QTime>
#include <QRandomGenerator>
#include "inputconvertgame.h"
#define CURSOR_POS_CHECK 50
InputConvertGame::InputConvertGame(Controller *controller) : InputConvertNormal(controller) {}
InputConvertGame::InputConvertGame(Controller *controller) : InputConvertNormal(controller) {
m_ctrlSteerWheel.delayData.timer = new QTimer(this);
m_ctrlSteerWheel.delayData.timer->setSingleShot(true);
connect(m_ctrlSteerWheel.delayData.timer, &QTimer::timeout, this, &InputConvertGame::onSteerWheelTimer);
}
InputConvertGame::~InputConvertGame() {}
@ -138,8 +144,10 @@ void InputConvertGame::updateSize(const QSize &frameSize, const QSize &showSize)
{
if (showSize != m_showSize) {
if (m_gameMap && m_keyMap.isValidMouseMoveMap()) {
#ifdef QT_NO_DEBUG
// show size change, resize grab cursor
emit grabCursor(true);
#endif
}
}
m_frameSize = frameSize;
@ -237,6 +245,55 @@ int InputConvertGame::getTouchID(int key)
// -------- steer wheel event --------
void InputConvertGame::getDelayQueue(const QPointF& start, const QPointF& end,
const double& distanceStep, const double& posStepconst,
quint32 lowestTimer, quint32 highestTimer,
QQueue<QPointF>& queuePos, QQueue<quint32>& queueTimer) {
double x1 = start.x();
double y1 = start.y();
double x2 = end.x();
double y2 = end.y();
double dx=x2-x1;
double dy=y2-y1;
double e=(fabs(dx)>fabs(dy))?fabs(dx):fabs(dy);
e /= distanceStep;
dx/=e;
dy/=e;
QQueue<QPointF> queue;
QQueue<quint32> queue2;
for(int i=1;i<=e;i++) {
QPointF pos(x1+(QRandomGenerator::global()->bounded(posStepconst*2)-posStepconst), y1+(QRandomGenerator::global()->bounded(posStepconst*2)-posStepconst));
queue.enqueue(pos);
queue2.enqueue(QRandomGenerator::global()->bounded(lowestTimer, highestTimer));
x1+=dx;
y1+=dy;
}
queuePos = queue;
queueTimer = queue2;
}
void InputConvertGame::onSteerWheelTimer() {
if(m_ctrlSteerWheel.delayData.queuePos.empty()) {
return;
}
int id = getTouchID(m_ctrlSteerWheel.touchKey);
m_ctrlSteerWheel.delayData.currentPos = m_ctrlSteerWheel.delayData.queuePos.dequeue();
sendTouchMoveEvent(id, m_ctrlSteerWheel.delayData.currentPos);
if(m_ctrlSteerWheel.delayData.queuePos.empty() && m_ctrlSteerWheel.delayData.pressedNum == 0) {
sendTouchUpEvent(id, m_ctrlSteerWheel.delayData.currentPos);
detachTouchID(m_ctrlSteerWheel.touchKey);
return;
}
if(!m_ctrlSteerWheel.delayData.queuePos.empty()) {
m_ctrlSteerWheel.delayData.timer->start(m_ctrlSteerWheel.delayData.queueTimer.dequeue());
}
}
void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const QKeyEvent *from)
{
int key = from->key();
@ -271,27 +328,43 @@ void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const Q
++pressedNum;
offset.rx() -= node.data.steerWheel.left.extendOffset;
}
m_ctrlSteerWheel.delayData.pressedNum = pressedNum;
// action
// last key release and timer no active, active timer to detouch
if (pressedNum == 0) {
// touch up release all
int id = getTouchID(m_ctrlSteerWheel.touchKey);
sendTouchUpEvent(id, node.data.steerWheel.centerPos + m_ctrlSteerWheel.lastOffset);
detachTouchID(m_ctrlSteerWheel.touchKey);
} else {
int id;
// first press, get key and touch down
if (pressedNum == 1 && flag) {
m_ctrlSteerWheel.touchKey = from->key();
id = attachTouchID(m_ctrlSteerWheel.touchKey);
sendTouchDownEvent(id, node.data.steerWheel.centerPos);
} else {
// jsut get touch id and move
id = getTouchID(m_ctrlSteerWheel.touchKey);
if (m_ctrlSteerWheel.delayData.timer->isActive()) {
m_ctrlSteerWheel.delayData.timer->stop();
m_ctrlSteerWheel.delayData.queueTimer.clear();
m_ctrlSteerWheel.delayData.queuePos.clear();
}
sendTouchMoveEvent(id, node.data.steerWheel.centerPos + offset);
sendTouchUpEvent(getTouchID(m_ctrlSteerWheel.touchKey), m_ctrlSteerWheel.delayData.currentPos);
detachTouchID(m_ctrlSteerWheel.touchKey);
return;
}
m_ctrlSteerWheel.lastOffset = offset;
// process steer wheel key event
m_ctrlSteerWheel.delayData.timer->stop();
m_ctrlSteerWheel.delayData.queueTimer.clear();
m_ctrlSteerWheel.delayData.queuePos.clear();
// first press, get key and touch down
if (pressedNum == 1 && flag) {
m_ctrlSteerWheel.touchKey = from->key();
int id = attachTouchID(m_ctrlSteerWheel.touchKey);
sendTouchDownEvent(id, node.data.steerWheel.centerPos);
getDelayQueue(node.data.steerWheel.centerPos, node.data.steerWheel.centerPos+offset,
0.01f, 0.002f, 2, 8,
m_ctrlSteerWheel.delayData.queuePos,
m_ctrlSteerWheel.delayData.queueTimer);
} else {
getDelayQueue(m_ctrlSteerWheel.delayData.currentPos, node.data.steerWheel.centerPos+offset,
0.01f, 0.002f, 2, 8,
m_ctrlSteerWheel.delayData.queuePos,
m_ctrlSteerWheel.delayData.queueTimer);
}
m_ctrlSteerWheel.delayData.timer->start();
return;
}
@ -349,18 +422,65 @@ void InputConvertGame::processKeyClickMulti(const KeyMap::DelayClickNode *nodes,
}
}
void InputConvertGame::onDragTimer() {
if(m_dragDelayData.queuePos.empty()) {
return;
}
int id = getTouchID(m_dragDelayData.pressKey);
m_dragDelayData.currentPos = m_dragDelayData.queuePos.dequeue();
sendTouchMoveEvent(id, m_dragDelayData.currentPos);
if(m_dragDelayData.queuePos.empty()) {
delete m_dragDelayData.timer;
m_dragDelayData.timer = nullptr;
sendTouchUpEvent(id, m_dragDelayData.currentPos);
detachTouchID(m_dragDelayData.pressKey);
m_dragDelayData.currentPos = QPointF();
m_dragDelayData.pressKey = 0;
return;
}
if(!m_dragDelayData.queuePos.empty()) {
m_dragDelayData.timer->start(m_dragDelayData.queueTimer.dequeue());
}
}
void InputConvertGame::processKeyDrag(const QPointF &startPos, QPointF endPos, const QKeyEvent *from)
{
if (QEvent::KeyPress == from->type()) {
// stop last
if (m_dragDelayData.timer && m_dragDelayData.timer->isActive()) {
m_dragDelayData.timer->stop();
delete m_dragDelayData.timer;
m_dragDelayData.timer = nullptr;
m_dragDelayData.queuePos.clear();
m_dragDelayData.queueTimer.clear();
sendTouchUpEvent(getTouchID(m_dragDelayData.pressKey), m_dragDelayData.currentPos);
detachTouchID(m_dragDelayData.pressKey);
m_dragDelayData.currentPos = QPointF();
m_dragDelayData.pressKey = 0;
}
// start this
int id = attachTouchID(from->key());
sendTouchDownEvent(id, startPos);
sendTouchMoveEvent(id, endPos);
}
if (QEvent::KeyRelease == from->type()) {
int id = getTouchID(from->key());
sendTouchUpEvent(id, endPos);
detachTouchID(from->key());
m_dragDelayData.timer = new QTimer(this);
m_dragDelayData.timer->setSingleShot(true);
connect(m_dragDelayData.timer, &QTimer::timeout, this, &InputConvertGame::onDragTimer);
m_dragDelayData.pressKey = from->key();
m_dragDelayData.currentPos = startPos;
m_dragDelayData.queuePos.clear();
m_dragDelayData.queueTimer.clear();
getDelayQueue(startPos, endPos,
0.01f, 0.002f, 0, 2,
m_dragDelayData.queuePos,
m_dragDelayData.queueTimer);
m_dragDelayData.timer->start();
}
}
@ -509,9 +629,10 @@ bool InputConvertGame::switchGameMap()
if (!m_keyMap.isValidMouseMoveMap()) {
return m_gameMap;
}
#ifdef QT_NO_DEBUG
// grab cursor and set cursor only mouse move map
emit grabCursor(m_gameMap);
#endif
hideMouseCursor(m_gameMap);
if (!m_gameMap) {

View file

@ -2,6 +2,7 @@
#define INPUTCONVERTGAME_H
#include <QPointF>
#include <QQueue>
#include "inputconvertnormal.h"
#include "keymap.h"
@ -60,9 +61,18 @@ protected:
bool checkCursorPos(const QMouseEvent *from);
void hideMouseCursor(bool hide);
void getDelayQueue(const QPointF& start, const QPointF& end,
const double& distanceStep, const double& posStepconst,
quint32 lowestTimer, quint32 highestTimer,
QQueue<QPointF>& queuePos, QQueue<quint32>& queueTimer);
protected:
void timerEvent(QTimerEvent *event);
private slots:
void onSteerWheelTimer();
void onDragTimer();
private:
QSize m_frameSize;
QSize m_showSize;
@ -82,8 +92,15 @@ private:
bool pressedDown = false;
bool pressedLeft = false;
bool pressedRight = false;
// for last up
QPointF lastOffset;
// for delay
struct {
QPointF currentPos;
QTimer* timer = nullptr;
QQueue<QPointF> queuePos;
QQueue<quint32> queueTimer;
int pressedNum = 0;
} delayData;
} m_ctrlSteerWheel;
// mouse move
@ -95,6 +112,15 @@ private:
int timer = 0;
bool smallEyes = false;
} m_ctrlMouseMove;
// for drag delay
struct {
QPointF currentPos;
QTimer* timer = nullptr;
QQueue<QPointF> queuePos;
QQueue<quint32> queueTimer;
int pressKey = 0;
} m_dragDelayData;
};
#endif // INPUTCONVERTGAME_H

View file

@ -0,0 +1,8 @@
set(QS_SOURCES_DEVICE_CONTROLLER_INPUTCONVERT_KEYMAP
keymap.h
keymap.cpp
)
add_library(keymap ${QS_SOURCES_DEVICE_CONTROLLER_INPUTCONVERT_KEYMAP})
target_include_directories(keymap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(keymap PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

View file

@ -0,0 +1,14 @@
SET(QS_SOURCES_DEVICE_CONTROLLER_RECEIVER
devicemsg.h
devicemsg.cpp
receiver.h
receiver.cpp
)
add_library(receiver ${QS_SOURCES_DEVICE_CONTROLLER_RECEIVER})
target_include_directories(receiver PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(receiver PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Network
util
)

View file

@ -0,0 +1,21 @@
set(QS_SOURCES_DEVICE_DECODER
avframeconvert.h
avframeconvert.cpp
decoder.h
decoder.cpp
fpscounter.h
fpscounter.cpp
videobuffer.h
videobuffer.cpp
)
add_library(decoder ${QS_SOURCES_DEVICE_DECODER})
target_include_directories(decoder PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
"${PROJECT_SOURCE_DIR}/third_party/ffmpeg/include"
)
target_link_libraries(decoder PUBLIC ${QS_EXTERNAL_LIBS_FFMPEG})
target_link_libraries(decoder PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
util
)

View file

@ -212,6 +212,7 @@ void Device::initSignals()
}
});
connect(m_server, &Server::connectToResult, this, [this](bool success, const QString &deviceName, const QSize &size) {
Q_UNUSED(deviceName);
if (success) {
double diff = m_startTimeCount.elapsed() / 1000.0;
qInfo() << QString("server start finish in %1s").arg(diff).toStdString().c_str();
@ -220,8 +221,11 @@ void Device::initSignals()
if (m_videoForm) {
// must be show before updateShowSize
m_videoForm->show();
m_videoForm->setWindowTitle(deviceName);
QString name = Config::getInstance().getNickName(m_params.serial);
if (name.isEmpty()) {
name = Config::getInstance().getTitle();
}
m_videoForm->setWindowTitle(name + "-" + m_params.serial);
m_videoForm->updateShowSize(size);
bool deviceVer = size.height() > size.width();

View file

@ -0,0 +1,9 @@
set(QS_SOURCES_DEVICE_FILEHANDLER
filehandler.h
filehandler.cpp
)
add_library(filehandler ${QS_SOURCES_DEVICE_FILEHANDLER})
target_include_directories(filehandler PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(filehandler PUBLIC adb)
target_link_libraries(filehandler PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

View file

@ -0,0 +1,14 @@
set(QS_SOURCES_DEVICE_RECORDER
recorder.h
recorder.cpp
)
add_library(recorder ${QS_SOURCES_DEVICE_RECORDER})
target_include_directories(recorder PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
"${PROJECT_SOURCE_DIR}/third_party/ffmpeg/include"
)
target_link_libraries(recorder PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
util
)

View file

@ -0,0 +1,8 @@
set(QS_SOURCES_DEVICE_RENDER
qyuvopenglwidget.h
qyuvopenglwidget.cpp
)
add_library(render ${QS_SOURCES_DEVICE_RENDER})
target_include_directories(render PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(render PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

View file

@ -0,0 +1,20 @@
set(QS_SOURCES_DEVICE_SERVER
server.h
server.cpp
tcpserver.h
tcpserver.cpp
videosocket.h
videosocket.cpp
)
add_library(server ${QS_SOURCES_DEVICE_SERVER})
target_include_directories(server PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(server PUBLIC
Qt${QT_VERSION_MAJOR}::Network
adb
)
target_link_libraries(server PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
common
util
)

View file

@ -0,0 +1,20 @@
set(QS_SOURCES_DEVICE_STREAM
stream.h
stream.cpp
)
add_library(stream ${QS_SOURCES_DEVICE_STREAM})
target_include_directories(stream PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
"${PROJECT_SOURCE_DIR}/third_party/ffmpeg/include"
)
target_link_libraries(stream PUBLIC ${QS_EXTERNAL_LIBS_FFMPEG})
target_link_libraries(stream PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
#controller
decoder
recorder
server
util
)

View file

@ -0,0 +1,23 @@
set(QS_SOURCES_DEVICE_UI
toolform.h
toolform.cpp
toolform.ui
videoform.h
videoform.cpp
videoform.ui
)
add_library(ui ${QS_SOURCES_DEVICE_UI})
target_include_directories(ui PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(ui PRIVATE "${PROJECT_SOURCE_DIR}/third_party/ffmpeg/include")
target_link_libraries(ui PUBLIC
device
uibase
)
target_link_libraries(ui PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
controller
render
fontawesome
util
)

View file

@ -367,16 +367,6 @@ QRect VideoForm::getScreenRect()
return screenRect;
}
bool VideoForm::checkTrialExpire()
{
static int trialTimes = 0;
if (++trialTimes > TRIAL_TIMES) {
QMessageBox::warning(this, "QtScrcpy", QStringLiteral("试用已结束,购买正式版本请联系作者"), QMessageBox::Ok);
return true;
}
return false;
}
void VideoForm::updateStyleSheet(bool vertical)
{
if (vertical) {
@ -534,12 +524,6 @@ void VideoForm::setDevice(Device *device)
void VideoForm::mousePressEvent(QMouseEvent *event)
{
#ifdef TRIAL_EXPIRE_CHECK
if (checkTrialExpire()) {
return;
}
#endif
if (event->button() == Qt::MiddleButton) {
if (m_device && !m_device->isCurrentCustomKeymap()) {
emit m_device->postGoHome();

View file

@ -45,7 +45,6 @@ private:
void moveCenter();
void installShortcut();
QRect getScreenRect();
bool checkTrialExpire();
protected:
void mousePressEvent(QMouseEvent *event);

View file

@ -0,0 +1,13 @@
set(QS_SOURCES_DEVICEMANAGE
devicemanage.h
devicemanage.cpp
)
add_library(devicemanage ${QS_SOURCES_DEVICEMANAGE})
target_include_directories(devicemanage PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(devicemanage PUBLIC device)
target_link_libraries(devicemanage PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
server
ui
)

View file

@ -46,7 +46,7 @@ Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog)
ui->connectedPhoneList->clear();
for (auto &item : devices) {
ui->serialBox->addItem(item);
ui->connectedPhoneList->addItem(item+"-"+Config::getInstance().getNickName(item));
ui->connectedPhoneList->addItem(Config::getInstance().getNickName(item) + "-" + item);
}
} else if (args.contains("show") && args.contains("wlan0")) {
QString ip = m_adb.getDeviceIPFromStdOut();
@ -77,18 +77,22 @@ Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog)
}
});
m_hideIcon = new QSystemTrayIcon();
m_hideIcon = new QSystemTrayIcon(this);
m_hideIcon->setIcon(QIcon(":/image/tray/logo.png"));
m_menu = new QMenu();
m_quit = new QAction();
m_showWindow = new QAction();;
m_menu = new QMenu(this);
m_quit = new QAction(this);
m_showWindow = new QAction(this);
m_showWindow->setText(tr("show"));
m_quit->setText(tr("quit"));
m_menu->addAction(m_showWindow);
m_menu->addAction(m_quit);
m_hideIcon->setContextMenu(m_menu);
m_hideIcon->show();
connect(m_showWindow, &QAction::triggered, this, &Dialog::slotShow);
connect(m_quit, SIGNAL(triggered()), this, SLOT(close()));
connect(m_quit, &QAction::triggered, this, [this](){
m_hideIcon->hide();
qApp->quit();
});
connect(m_hideIcon, &QSystemTrayIcon::activated,this,&Dialog::slotActivated);
}
@ -240,26 +244,12 @@ void Dialog::slotActivated(QSystemTrayIcon::ActivationReason reason)
void Dialog::closeEvent(QCloseEvent *event)
{
int res = QMessageBox::question(this,tr("warning"),tr("Quit or set tray?"),tr("Quit"),tr("Set tray"),tr("Cancel"));
if(res == 0)
{
event->accept();
}
else if(res == 1)
{
this->hide();
m_hideIcon->show();
m_hideIcon->showMessage(tr("Notice"),
tr("Hidden here!"),
QSystemTrayIcon::Information,
3000);
event->ignore();
}
else
{
event->ignore();
}
this->hide();
m_hideIcon->showMessage(tr("Notice"),
tr("Hidden here!"),
QSystemTrayIcon::Information,
3000);
event->ignore();
}
void Dialog::on_updateDevice_clicked()
@ -621,6 +611,10 @@ void Dialog::on_useSingleModeCheck_clicked()
ui->wirelessGroupBox->show();
ui->usbGroupBox->show();
}
QTimer::singleShot(0, this, [this](){
resize(width(), layout()->sizeHint().height());
});
}
void Dialog::on_serialBox_currentIndexChanged(const QString &arg1)

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>500</width>
<height>745</height>
<height>769</height>
</rect>
</property>
<property name="minimumSize">
@ -72,10 +72,22 @@
</item>
<item>
<widget class="QListWidget" name="connectedPhoneList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
<height>100</height>
</size>
</property>
</widget>
@ -751,10 +763,22 @@
</item>
<item>
<widget class="QTextEdit" name="outEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>140</height>
<height>120</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="focusPolicy">
@ -768,6 +792,19 @@
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>

View file

@ -0,0 +1,8 @@
set(QS_SOURCES_FONTAWESOME
iconhelper.h
iconhelper.cpp
)
add_library(fontawesome ${QS_SOURCES_FONTAWESOME})
target_include_directories(fontawesome PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(fontawesome PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

View file

@ -56,6 +56,10 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
QSurfaceFormat varFormat = QSurfaceFormat::defaultFormat();
varFormat.setVersion(2, 0);
varFormat.setProfile(QSurfaceFormat::NoProfile);
@ -104,13 +108,9 @@ int main(int argc, char *argv[])
g_mainDlg->setWindowTitle(Config::getInstance().getTitle());
g_mainDlg->show();
qInfo(
"%s",
QObject::tr("This software is completely open source and free. Strictly used for illegal purposes, or at your own risk. You can download it at the "
"following address:")
.toUtf8()
.data());
qInfo() << QString("QtScrcpy %1 <https://github.com/barry-ran/QtScrcpy>").arg(QCoreApplication::applicationVersion()).toUtf8();
qInfo() << QObject::tr("This software is completely open source and free. Use it at your own risk. You can download it at the "
"following address:");
qInfo() << QString("QtScrcpy %1 <https://github.com/barry-ran/QtScrcpy>").arg(QCoreApplication::applicationVersion());
int ret = a.exec();
@ -131,11 +131,11 @@ void installTranslator()
QString languagePath = ":/i18n/";
switch (language) {
case QLocale::Chinese:
languagePath += "QtScrcpy_zh.qm";
languagePath += "zh_CN.qm";
break;
case QLocale::English:
default:
languagePath += "QtScrcpy_en.qm";
languagePath += "en_US.qm";
}
translator.load(languagePath);

View file

@ -16,22 +16,18 @@
<translation type="vanished">file transfer failed</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="184"/>
<source>install apk</source>
<translation>install apk</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="186"/>
<source>file transfer</source>
<translation>file transfer</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="190"/>
<source>wait current %1 to complete</source>
<translation>wait current %1 to complete</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="193"/>
<source>%1 complete, save in %2</source>
<translation>%1 complete, save in %2</translation>
</message>
@ -41,7 +37,6 @@
<translation type="vanished">%1 complete\n save in %2</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="196"/>
<source>%1 failed</source>
<translation>%1 failed</translation>
</message>
@ -49,134 +44,108 @@
<context>
<name>Dialog</name>
<message>
<location filename="../../dialog.ui" line="562"/>
<source>Wireless</source>
<translation>Wireless</translation>
</message>
<message>
<location filename="../../dialog.ui" line="646"/>
<source>wireless connect</source>
<translation>wireless connect</translation>
</message>
<message>
<location filename="../../dialog.ui" line="662"/>
<source>wireless disconnect</source>
<translation>wireless disconnect</translation>
</message>
<message>
<location filename="../../dialog.ui" line="89"/>
<source>Start Config</source>
<translation>Start Config</translation>
</message>
<message>
<location filename="../../dialog.ui" line="225"/>
<source>record save path:</source>
<translation>record save path:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="242"/>
<location filename="../../dialog.cpp" line="449"/>
<source>select path</source>
<translation>select path</translation>
</message>
<message>
<location filename="../../dialog.ui" line="156"/>
<source>record format</source>
<translation>record format:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="380"/>
<source>record screen</source>
<translation>record screen</translation>
</message>
<message>
<location filename="../../dialog.ui" line="325"/>
<source>frameless</source>
<translation>frameless</translation>
</message>
<message>
<location filename="../../dialog.ui" line="32"/>
<source>Use Simple Mode</source>
<translatorcomment>Use Simple Mode</translatorcomment>
<translation>Use Simple Mode</translation>
</message>
<message>
<location filename="../../dialog.ui" line="42"/>
<source>Simple Mode</source>
<translatorcomment>Simple Mode</translatorcomment>
<translation>Simple Mode</translation>
</message>
<message>
<location filename="../../dialog.ui" line="53"/>
<source>WIFI Connect</source>
<translatorcomment>WIFI Connect</translatorcomment>
<translation>WIFI Connect</translation>
</message>
<message>
<location filename="../../dialog.ui" line="60"/>
<source>USB Connect</source>
<translatorcomment>USB Connect</translatorcomment>
<translation>USB Connect</translation>
</message>
<message>
<location filename="../../dialog.ui" line="69"/>
<source>Double click to connect:</source>
<translation>Double click to connect:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="184"/>
<source>lock orientation:</source>
<translation>lock orientation:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="387"/>
<source>show fps</source>
<translation>show fps</translation>
</message>
<message>
<location filename="../../dialog.ui" line="394"/>
<source>stay awake</source>
<translation>stay awake</translation>
</message>
<message>
<location filename="../../dialog.ui" line="421"/>
<source>device name:</source>
<translatorcomment>device name:</translatorcomment>
<translation>device name:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="438"/>
<source>update name</source>
<translatorcomment>update name</translatorcomment>
<translation>update name</translation>
</message>
<message>
<location filename="../../dialog.ui" line="519"/>
<source>stop all server</source>
<translation>stop all server</translation>
</message>
<message>
<location filename="../../dialog.ui" line="696"/>
<source>adb command:</source>
<translation>adb command:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="732"/>
<source>terminate</source>
<translation>terminate</translation>
</message>
<message>
<location filename="../../dialog.ui" line="719"/>
<source>execute</source>
<translation>execute</translation>
</message>
<message>
<location filename="../../dialog.ui" line="745"/>
<source>clear</source>
<translation>clear</translation>
</message>
<message>
<location filename="../../dialog.ui" line="370"/>
<source>reverse connection</source>
<translation>reverse connection</translation>
</message>
@ -185,57 +154,46 @@
<translation type="vanished">auto enable</translation>
</message>
<message>
<location filename="../../dialog.ui" line="354"/>
<source>background record</source>
<translation>background record</translation>
</message>
<message>
<location filename="../../dialog.ui" line="318"/>
<source>screen-off</source>
<translation>screen-off</translation>
</message>
<message>
<location filename="../../dialog.ui" line="287"/>
<source>apply</source>
<translation>apply</translation>
</message>
<message>
<location filename="../../dialog.ui" line="142"/>
<source>max size:</source>
<translation>max size:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="338"/>
<source>always on top</source>
<translation>always on top</translation>
</message>
<message>
<location filename="../../dialog.ui" line="280"/>
<source>refresh script</source>
<translation>refresh script</translation>
</message>
<message>
<location filename="../../dialog.ui" line="536"/>
<source>get device IP</source>
<translation>get device IP</translation>
</message>
<message>
<location filename="../../dialog.ui" line="407"/>
<source>USB line</source>
<translation>USB line</translation>
</message>
<message>
<location filename="../../dialog.ui" line="491"/>
<source>stop server</source>
<translation>stop server</translation>
</message>
<message>
<location filename="../../dialog.ui" line="481"/>
<source>start server</source>
<translation>start server</translation>
</message>
<message>
<location filename="../../dialog.ui" line="471"/>
<source>device serial:</source>
<translation>device serial:</translation>
</message>
@ -244,80 +202,66 @@
<translation type="vanished">Config</translation>
</message>
<message>
<location filename="../../dialog.ui" line="125"/>
<source>bit rate:</source>
<translation>bit rate:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="546"/>
<source>start adbd</source>
<translation>start adbd</translation>
</message>
<message>
<location filename="../../dialog.ui" line="526"/>
<source>refresh devices</source>
<translation>refresh devices</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="85"/>
<source>show</source>
<translatorcomment>show</translatorcomment>
<translation>show</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="86"/>
<source>quit</source>
<translatorcomment>quit</translatorcomment>
<translation>quit</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="121"/>
<source>original</source>
<translation>original</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="126"/>
<source>no lock</source>
<translation>no lock</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>warning</source>
<translatorcomment>Warning</translatorcomment>
<translation>Warning</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Quit or set tray?</source>
<translatorcomment>Quit or set tray?</translatorcomment>
<translation>Quit or set tray?</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Quit</source>
<translatorcomment>Quit</translatorcomment>
<translation>Quit</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Set tray</source>
<translatorcomment>Set tray</translatorcomment>
<translation>Set tray</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Cancel</source>
<translatorcomment>Cancel</translatorcomment>
<translation>Cancel</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="253"/>
<source>Notice</source>
<translatorcomment>Notice</translatorcomment>
<translation>Notice</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="254"/>
<source>Hidden here!</source>
<translatorcomment>Hidden here!</translatorcomment>
<translation>Hidden here!</translation>
@ -326,17 +270,14 @@
<context>
<name>InputConvertGame</name>
<message>
<location filename="../../device/controller/inputconvert/inputconvertgame.cpp" line="507"/>
<source>current keymap mode: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../device/controller/inputconvert/inputconvertgame.cpp" line="507"/>
<source>custom</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../device/controller/inputconvert/inputconvertgame.cpp" line="507"/>
<source>normal</source>
<translation type="unfinished"></translation>
</message>
@ -344,7 +285,6 @@
<context>
<name>KeyMap</name>
<message>
<location filename="../../device/controller/inputconvert/keymap/keymap.cpp" line="307"/>
<source>Script updated, current keymap mode:normal, Press ~ key to switch keymap mode</source>
<translation type="unfinished"></translation>
</message>
@ -362,25 +302,25 @@ You can download it at the following address:</source>
<translation type="vanished">This software is completely open source and free.\nStrictly used for illegal purposes, or at your own risk.\nYou can download it at the following address:</translation>
</message>
<message>
<location filename="../../main.cpp" line="109"/>
<source>This software is completely open source and free. Strictly used for illegal purposes, or at your own risk. You can download it at the following address:</source>
<translation>This software is completely open source and free. Strictly used for illegal purposes, or at your own risk. You can download it at the following address:</translation>
<translation type="vanished">This software is completely open source and free. Strictly used for illegal purposes, or at your own risk. You can download it at the following address:</translation>
</message>
<message>
<source>This software is completely open source and free. Use it at your own risk. You can download it at the following address:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ToolForm</name>
<message>
<location filename="../../device/ui/toolform.ui" line="14"/>
<source>Tool</source>
<translation>Tool</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="33"/>
<source>full screen</source>
<translation>full screen</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="56"/>
<source>expand notify</source>
<translation>expand notify</translation>
</message>
@ -393,52 +333,42 @@ You can download it at the following address:</source>
<translation type="vanished">turn on</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="66"/>
<source>touch switch</source>
<translation>touch switch</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="76"/>
<source>close screen</source>
<translation>close screen</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="86"/>
<source>power</source>
<translation>power</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="96"/>
<source>volume up</source>
<translation>volume up</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="106"/>
<source>volume down</source>
<translation>volume down</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="116"/>
<source>app switch</source>
<translation>app switch</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="126"/>
<source>menu</source>
<translation>menu</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="136"/>
<source>home</source>
<translation>home</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="146"/>
<source>return</source>
<translation>return</translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="156"/>
<source>screen shot</source>
<translation>screen shot</translation>
</message>
@ -458,7 +388,6 @@ You can download it at the following address:</source>
<translation type="vanished">file transfer failed</translation>
</message>
<message>
<location filename="../../device/ui/videoform.cpp" line="749"/>
<source>file does not exist</source>
<translation>file does not exist</translation>
</message>

View file

@ -16,22 +16,18 @@
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../device/device.cpp" line="184"/>
<source>install apk</source>
<translation>apk</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="186"/>
<source>file transfer</source>
<translation></translation>
</message>
<message>
<location filename="../../device/device.cpp" line="190"/>
<source>wait current %1 to complete</source>
<translation>%1</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="193"/>
<source>%1 complete, save in %2</source>
<translation>%1,%2</translation>
</message>
@ -41,7 +37,6 @@
<translation type="vanished">%1\n %2</translation>
</message>
<message>
<location filename="../../device/device.cpp" line="196"/>
<source>%1 failed</source>
<translation>%1 </translation>
</message>
@ -49,134 +44,108 @@
<context>
<name>Dialog</name>
<message>
<location filename="../../dialog.ui" line="562"/>
<source>Wireless</source>
<translation>线</translation>
</message>
<message>
<location filename="../../dialog.ui" line="646"/>
<source>wireless connect</source>
<translation>线</translation>
</message>
<message>
<location filename="../../dialog.ui" line="662"/>
<source>wireless disconnect</source>
<translation>线</translation>
</message>
<message>
<location filename="../../dialog.ui" line="89"/>
<source>Start Config</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="225"/>
<source>record save path:</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="242"/>
<location filename="../../dialog.cpp" line="449"/>
<source>select path</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="156"/>
<source>record format</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="380"/>
<source>record screen</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="325"/>
<source>frameless</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="32"/>
<source>Use Simple Mode</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="42"/>
<source>Simple Mode</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="53"/>
<source>WIFI Connect</source>
<translatorcomment>WIFI连接</translatorcomment>
<translation>WIFI连接</translation>
</message>
<message>
<location filename="../../dialog.ui" line="60"/>
<source>USB Connect</source>
<translatorcomment>USB连接</translatorcomment>
<translation>USB连接</translation>
</message>
<message>
<location filename="../../dialog.ui" line="69"/>
<source>Double click to connect:</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="184"/>
<source>lock orientation:</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="387"/>
<source>show fps</source>
<translation>fps</translation>
</message>
<message>
<location filename="../../dialog.ui" line="394"/>
<source>stay awake</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="421"/>
<source>device name:</source>
<translatorcomment>:</translatorcomment>
<translation>:</translation>
</message>
<message>
<location filename="../../dialog.ui" line="438"/>
<source>update name</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="519"/>
<source>stop all server</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="696"/>
<source>adb command:</source>
<translation>adb命令</translation>
</message>
<message>
<location filename="../../dialog.ui" line="732"/>
<source>terminate</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="719"/>
<source>execute</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="745"/>
<source>clear</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="370"/>
<source>reverse connection</source>
<translation></translation>
</message>
@ -185,57 +154,46 @@
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../dialog.ui" line="354"/>
<source>background record</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="318"/>
<source>screen-off</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="287"/>
<source>apply</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="142"/>
<source>max size:</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="338"/>
<source>always on top</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="280"/>
<source>refresh script</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="536"/>
<source>get device IP</source>
<translation>IP</translation>
</message>
<message>
<location filename="../../dialog.ui" line="407"/>
<source>USB line</source>
<translation>USB线</translation>
</message>
<message>
<location filename="../../dialog.ui" line="491"/>
<source>stop server</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="481"/>
<source>start server</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="471"/>
<source>device serial:</source>
<translation></translation>
</message>
@ -244,80 +202,66 @@
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../dialog.ui" line="125"/>
<source>bit rate:</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.ui" line="546"/>
<source>start adbd</source>
<translation>adbd</translation>
</message>
<message>
<location filename="../../dialog.ui" line="526"/>
<source>refresh devices</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="85"/>
<source>show</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="86"/>
<source>quit</source>
<translatorcomment>退</translatorcomment>
<translation>退</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="121"/>
<source>original</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="126"/>
<source>no lock</source>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>warning</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Quit or set tray?</source>
<translatorcomment>退</translatorcomment>
<translation>退</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Quit</source>
<translatorcomment>退</translatorcomment>
<translation>退</translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Set tray</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="243"/>
<source>Cancel</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="253"/>
<source>Notice</source>
<translatorcomment></translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../../dialog.cpp" line="254"/>
<source>Hidden here!</source>
<translatorcomment></translatorcomment>
<translation></translation>
@ -326,17 +270,14 @@
<context>
<name>InputConvertGame</name>
<message>
<location filename="../../device/controller/inputconvert/inputconvertgame.cpp" line="507"/>
<source>current keymap mode: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../device/controller/inputconvert/inputconvertgame.cpp" line="507"/>
<source>custom</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../device/controller/inputconvert/inputconvertgame.cpp" line="507"/>
<source>normal</source>
<translation type="unfinished"></translation>
</message>
@ -344,7 +285,6 @@
<context>
<name>KeyMap</name>
<message>
<location filename="../../device/controller/inputconvert/keymap/keymap.cpp" line="307"/>
<source>Script updated, current keymap mode:normal, Press ~ key to switch keymap mode</source>
<translation type="unfinished"></translation>
</message>
@ -352,35 +292,21 @@
<context>
<name>QObject</name>
<message>
<source>This software is completely open source and free, you can download it at the following address:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>This software is completely open source and free.
Strictly used for illegal purposes, or at your own risk.
You can download it at the following address:</source>
<translation type="vanished">.\n严禁用于非法用途.\n你可以在下面地址下载:</translation>
</message>
<message>
<location filename="../../main.cpp" line="109"/>
<source>This software is completely open source and free. Strictly used for illegal purposes, or at your own risk. You can download it at the following address:</source>
<translation>:</translation>
<source>This software is completely open source and free. Use it at your own risk. You can download it at the following address:</source>
<translation>使</translation>
</message>
</context>
<context>
<name>ToolForm</name>
<message>
<location filename="../../device/ui/toolform.ui" line="14"/>
<source>Tool</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="33"/>
<source>full screen</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="56"/>
<source>expand notify</source>
<translation></translation>
</message>
@ -393,52 +319,42 @@ You can download it at the following address:</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="66"/>
<source>touch switch</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="76"/>
<source>close screen</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="86"/>
<source>power</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="96"/>
<source>volume up</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="106"/>
<source>volume down</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="116"/>
<source>app switch</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="126"/>
<source>menu</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="136"/>
<source>home</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="146"/>
<source>return</source>
<translation></translation>
</message>
<message>
<location filename="../../device/ui/toolform.ui" line="156"/>
<source>screen shot</source>
<translation></translation>
</message>
@ -458,7 +374,6 @@ You can download it at the following address:</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../device/ui/videoform.cpp" line="749"/>
<source>file does not exist</source>
<translation></translation>
</message>

View file

@ -22,8 +22,8 @@
<file>qss/psblack/radiobutton_checked_disable.png</file>
<file>qss/psblack/radiobutton_unchecked.png</file>
<file>qss/psblack/radiobutton_unchecked_disable.png</file>
<file>i18n/QtScrcpy_en.qm</file>
<file>i18n/QtScrcpy_zh.qm</file>
<file>i18n/en_US.qm</file>
<file>i18n/zh_CN.qm</file>
<file>image/tray/logo.png</file>
</qresource>
</RCC>

10
QtScrcpy/uibase/CMakeLists.txt Executable file
View file

@ -0,0 +1,10 @@
set(QS_SOURCES_UIBASE
keepratiowidget.h
keepratiowidget.cpp
magneticwidget.h
magneticwidget.cpp
)
add_library(uibase ${QS_SOURCES_UIBASE})
target_include_directories(uibase PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(uibase PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

21
QtScrcpy/util/CMakeLists.txt Executable file
View file

@ -0,0 +1,21 @@
set(QS_SUBDIRECTORIES_UTIL
mousetap
)
set(QS_SOURCES_UTIL
bufferutil.h
bufferutil.cpp
compat.h
config.h
config.cpp
)
add_library(util ${QS_SOURCES_UTIL})
target_include_directories(util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
foreach(QS_SUBDIRECTORY_UTIL ${QS_SUBDIRECTORIES_UTIL})
add_subdirectory (${QS_SUBDIRECTORY_UTIL})
endforeach()
target_link_libraries(util PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

View file

@ -0,0 +1,50 @@
set(QS_SOURCES_UTIL_MOUSETAP
mousetap.h
mousetap.cpp
)
# Microsoft Windows
if(WIN32)
list(APPEND QS_SOURCES_UTIL_MOUSETAP
winmousetap.h
winmousetap.cpp
)
set(QS_EXTERNAL_LIBS_UTIL_MOUSETAP User32)
elseif(UNIX)
# macOS
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
find_library(APPKIT AppKit REQUIRED)
set(QS_EXTERNAL_LIBS_UTIL_MOUSETAP ${APPKIT})
list(APPEND QS_SOURCES_UTIL_MOUSETAP
cocoamousetap.h
cocoamousetap.mm
)
target_compile_options(mousetap "-mmacosx-version-min=10.6")
# Linux, BSD, etc.
else()
find_package(QT NAMES Qt6 Qt5 COMPONENTS X11Extras REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS X11Extras REQUIRED)
set(QS_EXTERNAL_LIBS_UTIL_MOUSETAP
Qt${QT_VERSION_MAJOR}::X11Extras
xcb
)
list(APPEND QS_SOURCES_UTIL_MOUSETAP
xmousetap.h
xmousetap.cpp
)
endif()
endif()
add_library(mousetap ${QS_SOURCES_UTIL_MOUSETAP})
target_link_libraries(mousetap PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
${QS_EXTERNAL_LIBS_UTIL_MOUSETAP})

View file

@ -1 +1 @@
0.0.0
1.6.0

View file

@ -72,7 +72,7 @@ cross-platform|self implemented|provided by Qt
language|C|C++
style|sync|async
keymap|no custom keymap|support custom keymap
build|meson+gradle|Qt Creator
build|meson+gradle|qmake or CMake
- It's very easy to customize your GUI with Qt
- Asynchronous programming of Qt-based signal slot mechanism improves performance
@ -246,9 +246,10 @@ There are several reasons listed as below according to importance (high to low).
All the dependencies are provided and it is easy to compile.
### PC client
1. Set up the Qt development environment on the target platform (Qt == 5.15.2, vs == 2019 (mingw not supported))
1. Set up the Qt development environment on the target platform.
An Up-to-date Qt5 (i.e. 5.15.2 or later) is recommended. For Windows, you can choose MSVC 2019 or MinGW 8.1.0, but please be noted that currently only **CMake** scripts support MinGW.
2. Clone the project
3. Open the project root directory all.pro with QtCreator
3. Open the project root directory `all.pro` or `CMakeLists.txt` with QtCreator
4. Compile and run
### Android (If you do not have special requirements, you can directly use the built-in scrcpy-server.jar)
@ -280,7 +281,7 @@ Since it is based on scrcpy, respect its Licence
[Barry CSDN](https://blog.csdn.net/rankun1)
An ordinary programmer, working mainly in C++ for desktop client development, graduated from Shandong for more than a year of steel simulation education software, and later moved to Shanghai to work in security, online education related fields, familiar with audio and video. I have an understanding of audio and video fields such as voice calls, live education, video conferencing and other related solutions. At the same time have android, linux server and other development experience.
An ordinary programmer, working mainly in C++ for desktop client development, graduated from Shandong for more than a year of steel simulation education software, and later moved to Shanghai to work in security, online education related fields, familiar with audio and video. I have an understanding of audio and video fields such as voice calls, live education, video conferencing and other related solutions. I also have experience in Android, Linux server and other kinds of development.
## Contributors
@ -310,4 +311,4 @@ Support this project with your organization. Your logo will show up here with a
<a href="https://opencollective.com/QtScrcpy/organization/6/website"><img src="https://opencollective.com/QtScrcpy/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/QtScrcpy/organization/7/website"><img src="https://opencollective.com/QtScrcpy/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/QtScrcpy/organization/8/website"><img src="https://opencollective.com/QtScrcpy/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/QtScrcpy/organization/9/website"><img src="https://opencollective.com/QtScrcpy/organization/9/avatar.svg"></a>
<a href="https://opencollective.com/QtScrcpy/organization/9/website"><img src="https://opencollective.com/QtScrcpy/organization/9/avatar.svg"></a>

View file

@ -69,7 +69,7 @@ QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备并进行显示和
编程语言|C|C++
编程方式|同步|异步
按键映射|不支持自定义|支持自定义按键映射
编译方式|meson+gradle|Qt Creator
编译方式|meson+gradle|qmake or CMake
- 使用Qt可以非常容易的定制自己的界面
- 基于Qt的信号槽机制的异步编程提高性能
@ -243,10 +243,11 @@ Mac OS平台你可以直接使用我编译好的可执行程序:
尽量提供了所有依赖资源,方便傻瓜式编译。
### PC端
1. 目标平台上搭建Qt开发环境(Qt == 5.15.2, vs == 2019 (**不支持mingw**))
1. 在目标平台上搭建Qt开发环境
我们建议使用最新的Qt5版本5.15.2或更高。在Windows上你可以自由选择MSVC 2019或MinGW 8.1.0,但需要注意的是现阶段只有**CMake**脚本提供了对MinGW的支持。
2. 克隆该项目
3. 使用QtCreator打开项目根目录all.pro
4. 编译,运行即可
3. 使用QtCreator打开项目根目录`all.pro`或`CMakeLists.txt`
4. 编译,运行
### Android端 没有修改需求的话直接使用自带的scrcpy-server即可
1. 目标平台上搭建Android开发环境
@ -276,4 +277,4 @@ Mac OS平台你可以直接使用我编译好的可执行程序:
[Barry的CSDN](https://blog.csdn.net/rankun1)
一枚普通的程序员工作中主要使用C++进行桌面客户端开发,一毕业在山东做过一年多钢铁仿真教育软件,后来转战上海先后从事安防,在线教育相关领域工作,对音视频比较熟悉,对音视频领域如语音通话,直播教育,视频会议等相关解决方案有所了解。同时具有androidlinux服务器等开发经验。
一枚普通的程序员工作中主要使用C++进行桌面客户端开发,一毕业在山东做过一年多钢铁仿真教育软件,后来转战上海先后从事安防,在线教育相关领域工作,对音视频比较熟悉,对音视频领域如语音通话,直播教育,视频会议等相关解决方案有所了解。同时具有AndroidLinux服务器等开发经验。

View file

@ -3,5 +3,5 @@ SUBDIRS = QtScrcpy
# 多语言翻译文件
TRANSLATIONS = \
$$PWD/QtScrcpy/res/i18n/QtScrcpy_zh.ts \
$$PWD/QtScrcpy/res/i18n/QtScrcpy_en.ts
$$PWD/QtScrcpy/res/i18n/zh_CN.ts \
$$PWD/QtScrcpy/res/i18n/en_US.ts