mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-03-26 05:54:51 +01:00
Compare commits
28 Commits
display_pa
...
uhid.34
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce532d2979 | ||
|
|
cb088d9bf6 | ||
|
|
661c20b45a | ||
|
|
5b0eb374f8 | ||
|
|
8657930adb | ||
|
|
36ae04119a | ||
|
|
670b3cd900 | ||
|
|
77a4c4c361 | ||
|
|
7db63bcf4c | ||
|
|
771a4e0585 | ||
|
|
5519e3edc8 | ||
|
|
e1012d28a9 | ||
|
|
ad058e9bf8 | ||
|
|
6e59eab337 | ||
|
|
7d424cd8d0 | ||
|
|
31d6a8bb82 | ||
|
|
767f09f062 | ||
|
|
0fa3a0bbb2 | ||
|
|
eea8a509ff | ||
|
|
3ed48181ca | ||
|
|
5262bdc5b8 | ||
|
|
cb4fe32bc3 | ||
|
|
a682693bb1 | ||
|
|
925ec0fc7e | ||
|
|
3eb386ef1e | ||
|
|
d42d92af38 | ||
|
|
d73a6e6968 | ||
|
|
31efed3538 |
2
LICENSE
2
LICENSE
@@ -188,7 +188,7 @@
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2024 Romain Vimont
|
||||
Copyright (C) 2018-2023 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
18
README.md
18
README.md
@@ -1,8 +1,4 @@
|
||||
**This GitHub repo (<https://github.com/Genymobile/scrcpy>) is the only official
|
||||
source for the project. Do not download releases from random websites, even if
|
||||
their name contains `scrcpy`.**
|
||||
|
||||
# scrcpy (v2.4)
|
||||
# scrcpy (v2.3.1)
|
||||
|
||||
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
||||
|
||||
@@ -84,22 +80,20 @@ Here are just some common examples.
|
||||
scrcpy --video-codec=h265 -m1920 --max-fps=60 --no-audio -K # short version
|
||||
```
|
||||
|
||||
- Record the device camera in H.265 at 1920x1080 (and microphone) to an MP4
|
||||
file:
|
||||
- Record the device camera in H.265 at 1920x1080 (and microphone) to an MP4 file:
|
||||
|
||||
```bash
|
||||
scrcpy --video-source=camera --video-codec=h265 --camera-size=1920x1080 --record=file.mp4
|
||||
```
|
||||
|
||||
- Capture the device front camera and expose it as a webcam on the computer (on
|
||||
Linux):
|
||||
- Capture the device front camera and expose it as a webcam on the computer (on Linux):
|
||||
|
||||
```bash
|
||||
scrcpy --video-source=camera --camera-size=1920x1080 --camera-facing=front --v4l2-sink=/dev/video2 --no-playback
|
||||
```
|
||||
|
||||
- Control the device without mirroring by simulating a physical keyboard and
|
||||
mouse (USB debugging not required):
|
||||
- Control the device without mirroring by simulating a physical keyboard and mouse
|
||||
(USB debugging not required):
|
||||
|
||||
```bash
|
||||
scrcpy --otg
|
||||
@@ -173,7 +167,7 @@ work][donate]:
|
||||
## Licence
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2024 Romain Vimont
|
||||
Copyright (C) 2018-2023 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
1
app/deps/.gitignore
vendored
1
app/deps/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/work
|
||||
@@ -1,27 +0,0 @@
|
||||
This directory (app/deps/) contains:
|
||||
|
||||
*.sh : shell scripts to download and build dependencies
|
||||
|
||||
patches/ : patches to fix dependencies (used by scripts)
|
||||
|
||||
work/sources/ : downloaded tarballs and extracted folders
|
||||
ffmpeg-6.1.1.tar.xz
|
||||
ffmpeg-6.1.1/
|
||||
libusb-1.0.27.tar.gz
|
||||
libusb-1.0.27/
|
||||
...
|
||||
work/build/ : build dirs for each dependency/version/architecture
|
||||
ffmpeg-6.1.1/win32/
|
||||
ffmpeg-6.1.1/win64/
|
||||
libusb-1.0.27/win32/
|
||||
libusb-1.0.27/win64/
|
||||
...
|
||||
work/install/ : install dirs for each architexture
|
||||
win32/bin/
|
||||
win32/include/
|
||||
win32/lib/
|
||||
win32/share/
|
||||
win64/bin/
|
||||
win64/include/
|
||||
win64/lib/
|
||||
win64/share/
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DEPS_DIR"
|
||||
. common
|
||||
|
||||
VERSION=34.0.5
|
||||
FILENAME=platform-tools_r$VERSION-windows.zip
|
||||
PROJECT_DIR=platform-tools-$VERSION
|
||||
SHA256SUM=3f8320152704377de150418a3c4c9d07d16d80a6c0d0d8f7289c22c499e33571
|
||||
|
||||
cd "$SOURCES_DIR"
|
||||
|
||||
if [[ -d "$PROJECT_DIR" ]]
|
||||
then
|
||||
echo "$PWD/$PROJECT_DIR" found
|
||||
else
|
||||
get_file "https://dl.google.com/android/repository/$FILENAME" "$FILENAME" "$SHA256SUM"
|
||||
mkdir -p "$PROJECT_DIR"
|
||||
cd "$PROJECT_DIR"
|
||||
ZIP_PREFIX=platform-tools
|
||||
unzip "../$FILENAME" \
|
||||
"$ZIP_PREFIX"/AdbWinApi.dll \
|
||||
"$ZIP_PREFIX"/AdbWinUsbApi.dll \
|
||||
"$ZIP_PREFIX"/adb.exe
|
||||
mv "$ZIP_PREFIX"/* .
|
||||
rmdir "$ZIP_PREFIX"
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_DIR/$HOST/bin"
|
||||
cd "$INSTALL_DIR/$HOST/bin"
|
||||
cp -r "$SOURCES_DIR/$PROJECT_DIR"/. "$INSTALL_DIR/$HOST/bin/"
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# This file is intended to be sourced by other scripts, not executed
|
||||
|
||||
if [[ $# != 1 ]]
|
||||
then
|
||||
# <host>: win32 or win64
|
||||
echo "Syntax: $0 <host>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HOST="$1"
|
||||
|
||||
if [[ "$HOST" = win32 ]]
|
||||
then
|
||||
HOST_TRIPLET=i686-w64-mingw32
|
||||
elif [[ "$HOST" = win64 ]]
|
||||
then
|
||||
HOST_TRIPLET=x86_64-w64-mingw32
|
||||
else
|
||||
echo "Unsupported host: $HOST" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DEPS_DIR"
|
||||
|
||||
PATCHES_DIR="$PWD/patches"
|
||||
|
||||
WORK_DIR="$PWD/work"
|
||||
SOURCES_DIR="$WORK_DIR/sources"
|
||||
BUILD_DIR="$WORK_DIR/build"
|
||||
INSTALL_DIR="$WORK_DIR/install"
|
||||
|
||||
mkdir -p "$INSTALL_DIR" "$SOURCES_DIR" "$WORK_DIR"
|
||||
|
||||
checksum() {
|
||||
local file="$1"
|
||||
local sum="$2"
|
||||
echo "$file: verifying checksum..."
|
||||
echo "$sum $file" | sha256sum -c
|
||||
}
|
||||
|
||||
get_file() {
|
||||
local url="$1"
|
||||
local file="$2"
|
||||
local sum="$3"
|
||||
if [[ -f "$file" ]]
|
||||
then
|
||||
echo "$file: found"
|
||||
else
|
||||
echo "$file: not found, downloading..."
|
||||
wget "$url" -O "$file"
|
||||
fi
|
||||
checksum "$file" "$sum"
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DEPS_DIR"
|
||||
. common
|
||||
|
||||
VERSION=6.1.1
|
||||
FILENAME=ffmpeg-$VERSION.tar.xz
|
||||
PROJECT_DIR=ffmpeg-$VERSION
|
||||
SHA256SUM=8684f4b00f94b85461884c3719382f1261f0d9eb3d59640a1f4ac0873616f968
|
||||
|
||||
cd "$SOURCES_DIR"
|
||||
|
||||
if [[ -d "$PROJECT_DIR" ]]
|
||||
then
|
||||
echo "$PWD/$PROJECT_DIR" found
|
||||
else
|
||||
get_file "https://ffmpeg.org/releases/$FILENAME" "$FILENAME" "$SHA256SUM"
|
||||
tar xf "$FILENAME" # First level directory is "$PROJECT_DIR"
|
||||
patch -d "$PROJECT_DIR" -p1 < "$PATCHES_DIR"/ffmpeg-6.1-fix-build.patch
|
||||
fi
|
||||
|
||||
mkdir -p "$BUILD_DIR/$PROJECT_DIR"
|
||||
cd "$BUILD_DIR/$PROJECT_DIR"
|
||||
|
||||
if [[ "$HOST" = win32 ]]
|
||||
then
|
||||
ARCH=x86
|
||||
elif [[ "$HOST" = win64 ]]
|
||||
then
|
||||
ARCH=x86_64
|
||||
else
|
||||
echo "Unsupported host: $HOST" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# -static-libgcc to avoid missing libgcc_s_dw2-1.dll
|
||||
# -static to avoid dynamic dependency to zlib
|
||||
export CFLAGS='-static-libgcc -static'
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
export LDFLAGS='-static-libgcc -static'
|
||||
|
||||
if [[ -d "$HOST" ]]
|
||||
then
|
||||
echo "'$PWD/$HOST' already exists, not reconfigured"
|
||||
cd "$HOST"
|
||||
else
|
||||
mkdir "$HOST"
|
||||
cd "$HOST"
|
||||
|
||||
"$SOURCES_DIR/$PROJECT_DIR"/configure \
|
||||
--prefix="$INSTALL_DIR/$HOST" \
|
||||
--enable-cross-compile \
|
||||
--target-os=mingw32 \
|
||||
--arch="$ARCH" \
|
||||
--cross-prefix="${HOST_TRIPLET}-" \
|
||||
--cc="${HOST_TRIPLET}-gcc" \
|
||||
--extra-cflags="-O2 -fPIC" \
|
||||
--enable-shared \
|
||||
--disable-static \
|
||||
--disable-programs \
|
||||
--disable-doc \
|
||||
--disable-swscale \
|
||||
--disable-postproc \
|
||||
--disable-avfilter \
|
||||
--disable-avdevice \
|
||||
--disable-network \
|
||||
--disable-everything \
|
||||
--enable-swresample \
|
||||
--enable-decoder=h264 \
|
||||
--enable-decoder=hevc \
|
||||
--enable-decoder=av1 \
|
||||
--enable-decoder=pcm_s16le \
|
||||
--enable-decoder=opus \
|
||||
--enable-decoder=aac \
|
||||
--enable-decoder=flac \
|
||||
--enable-decoder=png \
|
||||
--enable-protocol=file \
|
||||
--enable-demuxer=image2 \
|
||||
--enable-parser=png \
|
||||
--enable-zlib \
|
||||
--enable-muxer=matroska \
|
||||
--enable-muxer=mp4 \
|
||||
--enable-muxer=opus \
|
||||
--enable-muxer=flac \
|
||||
--enable-muxer=wav \
|
||||
--disable-vulkan
|
||||
fi
|
||||
|
||||
make -j
|
||||
make install
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DEPS_DIR"
|
||||
. common
|
||||
|
||||
VERSION=1.0.27
|
||||
FILENAME=libusb-$VERSION.tar.gz
|
||||
PROJECT_DIR=libusb-$VERSION
|
||||
SHA256SUM=e8f18a7a36ecbb11fb820bd71540350d8f61bcd9db0d2e8c18a6fb80b214a3de
|
||||
|
||||
cd "$SOURCES_DIR"
|
||||
|
||||
if [[ -d "$PROJECT_DIR" ]]
|
||||
then
|
||||
echo "$PWD/$PROJECT_DIR" found
|
||||
else
|
||||
get_file "https://github.com/libusb/libusb/archive/refs/tags/v$VERSION.tar.gz" "$FILENAME" "$SHA256SUM"
|
||||
tar xf "$FILENAME" # First level directory is "$PROJECT_DIR"
|
||||
fi
|
||||
|
||||
mkdir -p "$BUILD_DIR/$PROJECT_DIR"
|
||||
cd "$BUILD_DIR/$PROJECT_DIR"
|
||||
|
||||
export CFLAGS='-O2'
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
|
||||
if [[ -d "$HOST" ]]
|
||||
then
|
||||
echo "'$PWD/$HOST' already exists, not reconfigured"
|
||||
cd "$HOST"
|
||||
else
|
||||
mkdir "$HOST"
|
||||
cd "$HOST"
|
||||
|
||||
"$SOURCES_DIR/$PROJECT_DIR"/bootstrap.sh
|
||||
"$SOURCES_DIR/$PROJECT_DIR"/configure \
|
||||
--prefix="$INSTALL_DIR/$HOST" \
|
||||
--host="$HOST_TRIPLET" \
|
||||
--enable-shared \
|
||||
--disable-static
|
||||
fi
|
||||
|
||||
make -j
|
||||
make install-strip
|
||||
@@ -1,27 +0,0 @@
|
||||
From 03c80197afb324da38c9b70254231e3fdcfa68fc Mon Sep 17 00:00:00 2001
|
||||
From: Romain Vimont <rom@rom1v.com>
|
||||
Date: Sun, 12 Nov 2023 17:58:50 +0100
|
||||
Subject: [PATCH] Fix FFmpeg 6.1 build
|
||||
|
||||
Build failed on tag n6.1 With --enable-decoder=av1 but without
|
||||
--enable-muxer=av1.
|
||||
---
|
||||
libavcodec/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
|
||||
index 580a8d6b54..aff19b670c 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -249,7 +249,7 @@ OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \
|
||||
OBJS-$(CONFIG_ATRAC9_DECODER) += atrac9dec.o
|
||||
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||
-OBJS-$(CONFIG_AV1_DECODER) += av1dec.o
|
||||
+OBJS-$(CONFIG_AV1_DECODER) += av1dec.o av1_parse.o
|
||||
OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_AV1_MEDIACODEC_ENCODER) += mediacodecenc.o
|
||||
--
|
||||
2.42.0
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DEPS_DIR"
|
||||
. common
|
||||
|
||||
VERSION=2.28.5
|
||||
FILENAME=SDL-$VERSION.tar.gz
|
||||
PROJECT_DIR=SDL-release-$VERSION
|
||||
SHA256SUM=9f0556e4a24ef5b267010038ad9e9948b62f236d5bcc4b22179f95ef62d84023
|
||||
|
||||
cd "$SOURCES_DIR"
|
||||
|
||||
if [[ -d "$PROJECT_DIR" ]]
|
||||
then
|
||||
echo "$PWD/$PROJECT_DIR" found
|
||||
else
|
||||
get_file "https://github.com/libsdl-org/SDL/archive/refs/tags/release-$VERSION.tar.gz" "$FILENAME" "$SHA256SUM"
|
||||
tar xf "$FILENAME" # First level directory is "$PROJECT_DIR"
|
||||
fi
|
||||
|
||||
mkdir -p "$BUILD_DIR/$PROJECT_DIR"
|
||||
cd "$BUILD_DIR/$PROJECT_DIR"
|
||||
|
||||
export CFLAGS='-O2'
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
|
||||
if [[ -d "$HOST" ]]
|
||||
then
|
||||
echo "'$PWD/$HOST' already exists, not reconfigured"
|
||||
cd "$HOST"
|
||||
else
|
||||
mkdir "$HOST"
|
||||
cd "$HOST"
|
||||
|
||||
"$SOURCES_DIR/$PROJECT_DIR"/configure \
|
||||
--prefix="$INSTALL_DIR/$HOST" \
|
||||
--host="$HOST_TRIPLET" \
|
||||
--enable-shared \
|
||||
--disable-static
|
||||
fi
|
||||
|
||||
make -j
|
||||
# There is no "make install-strip"
|
||||
make install
|
||||
# Strip manually
|
||||
${HOST_TRIPLET}-strip "$INSTALL_DIR/$HOST/bin/SDL2.dll"
|
||||
1
app/prebuilt-deps/.gitignore
vendored
Normal file
1
app/prebuilt-deps/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/data
|
||||
22
app/prebuilt-deps/common
Executable file
22
app/prebuilt-deps/common
Executable file
@@ -0,0 +1,22 @@
|
||||
PREBUILT_DATA_DIR=data
|
||||
|
||||
checksum() {
|
||||
local file="$1"
|
||||
local sum="$2"
|
||||
echo "$file: verifying checksum..."
|
||||
echo "$sum $file" | sha256sum -c
|
||||
}
|
||||
|
||||
get_file() {
|
||||
local url="$1"
|
||||
local file="$2"
|
||||
local sum="$3"
|
||||
if [[ -f "$file" ]]
|
||||
then
|
||||
echo "$file: found"
|
||||
else
|
||||
echo "$file: not found, downloading..."
|
||||
wget "$url" -O "$file"
|
||||
fi
|
||||
checksum "$file" "$sum"
|
||||
}
|
||||
32
app/prebuilt-deps/prepare-adb.sh
Executable file
32
app/prebuilt-deps/prepare-adb.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DIR"
|
||||
. common
|
||||
mkdir -p "$PREBUILT_DATA_DIR"
|
||||
cd "$PREBUILT_DATA_DIR"
|
||||
|
||||
DEP_DIR=platform-tools-34.0.5
|
||||
|
||||
FILENAME=platform-tools_r34.0.5-windows.zip
|
||||
SHA256SUM=3f8320152704377de150418a3c4c9d07d16d80a6c0d0d8f7289c22c499e33571
|
||||
|
||||
if [[ -d "$DEP_DIR" ]]
|
||||
then
|
||||
echo "$DEP_DIR" found
|
||||
exit 0
|
||||
fi
|
||||
|
||||
get_file "https://dl.google.com/android/repository/$FILENAME" \
|
||||
"$FILENAME" "$SHA256SUM"
|
||||
|
||||
mkdir "$DEP_DIR"
|
||||
cd "$DEP_DIR"
|
||||
|
||||
ZIP_PREFIX=platform-tools
|
||||
unzip "../$FILENAME" \
|
||||
"$ZIP_PREFIX"/AdbWinApi.dll \
|
||||
"$ZIP_PREFIX"/AdbWinUsbApi.dll \
|
||||
"$ZIP_PREFIX"/adb.exe
|
||||
mv "$ZIP_PREFIX"/* .
|
||||
rmdir "$ZIP_PREFIX"
|
||||
30
app/prebuilt-deps/prepare-ffmpeg.sh
Executable file
30
app/prebuilt-deps/prepare-ffmpeg.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DIR"
|
||||
. common
|
||||
mkdir -p "$PREBUILT_DATA_DIR"
|
||||
cd "$PREBUILT_DATA_DIR"
|
||||
|
||||
VERSION=6.1-scrcpy-3
|
||||
DEP_DIR="ffmpeg-$VERSION"
|
||||
|
||||
FILENAME="$DEP_DIR".7z
|
||||
SHA256SUM=b646d18a3d543a4e4c46881568213499f22e4454a464e1552f03f2ac9cc3a05a
|
||||
|
||||
if [[ -d "$DEP_DIR" ]]
|
||||
then
|
||||
echo "$DEP_DIR" found
|
||||
exit 0
|
||||
fi
|
||||
|
||||
get_file "https://github.com/rom1v/scrcpy-deps/releases/download/$VERSION/$FILENAME" \
|
||||
"$FILENAME" "$SHA256SUM"
|
||||
|
||||
mkdir "$DEP_DIR"
|
||||
cd "$DEP_DIR"
|
||||
|
||||
ZIP_PREFIX=ffmpeg
|
||||
7z x "../$FILENAME"
|
||||
mv "$ZIP_PREFIX"/* .
|
||||
rmdir "$ZIP_PREFIX"
|
||||
39
app/prebuilt-deps/prepare-libusb.sh
Executable file
39
app/prebuilt-deps/prepare-libusb.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DIR"
|
||||
. common
|
||||
mkdir -p "$PREBUILT_DATA_DIR"
|
||||
cd "$PREBUILT_DATA_DIR"
|
||||
|
||||
VERSION=1.0.26
|
||||
DEP_DIR="libusb-$VERSION"
|
||||
|
||||
FILENAME="libusb-$VERSION-binaries.7z"
|
||||
SHA256SUM=9c242696342dbde9cdc47239391f71833939bf9f7aa2bbb28cdaabe890465ec5
|
||||
|
||||
if [[ -d "$DEP_DIR" ]]
|
||||
then
|
||||
echo "$DEP_DIR" found
|
||||
exit 0
|
||||
fi
|
||||
|
||||
get_file "https://github.com/libusb/libusb/releases/download/v$VERSION/$FILENAME" \
|
||||
"$FILENAME" "$SHA256SUM"
|
||||
|
||||
mkdir "$DEP_DIR"
|
||||
cd "$DEP_DIR"
|
||||
|
||||
7z x "../$FILENAME" \
|
||||
"libusb-$VERSION-binaries/libusb-MinGW-Win32/" \
|
||||
"libusb-$VERSION-binaries/libusb-MinGW-Win32/" \
|
||||
"libusb-$VERSION-binaries/libusb-MinGW-x64/" \
|
||||
"libusb-$VERSION-binaries/libusb-MinGW-x64/"
|
||||
|
||||
mv "libusb-$VERSION-binaries/libusb-MinGW-Win32" .
|
||||
mv "libusb-$VERSION-binaries/libusb-MinGW-x64" .
|
||||
rm -rf "libusb-$VERSION-binaries"
|
||||
|
||||
# Rename the dll to get the same library name on all platforms
|
||||
mv libusb-MinGW-Win32/bin/msys-usb-1.0.dll libusb-MinGW-Win32/bin/libusb-1.0.dll
|
||||
mv libusb-MinGW-x64/bin/msys-usb-1.0.dll libusb-MinGW-x64/bin/libusb-1.0.dll
|
||||
34
app/prebuilt-deps/prepare-sdl.sh
Executable file
34
app/prebuilt-deps/prepare-sdl.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
DIR=$(dirname ${BASH_SOURCE[0]})
|
||||
cd "$DIR"
|
||||
. common
|
||||
mkdir -p "$PREBUILT_DATA_DIR"
|
||||
cd "$PREBUILT_DATA_DIR"
|
||||
|
||||
VERSION=2.28.5
|
||||
DEP_DIR="SDL2-$VERSION"
|
||||
|
||||
FILENAME="SDL2-devel-$VERSION-mingw.tar.gz"
|
||||
SHA256SUM=3c0c655c2ebf67cad48fead72761d1601740ded30808952c3274ba223d226c21
|
||||
|
||||
if [[ -d "$DEP_DIR" ]]
|
||||
then
|
||||
echo "$DEP_DIR" found
|
||||
exit 0
|
||||
fi
|
||||
|
||||
get_file "https://github.com/libsdl-org/SDL/releases/download/release-$VERSION/$FILENAME" \
|
||||
"$FILENAME" "$SHA256SUM"
|
||||
|
||||
mkdir "$DEP_DIR"
|
||||
cd "$DEP_DIR"
|
||||
|
||||
TAR_PREFIX="$DEP_DIR" # root directory inside the tar has the same name
|
||||
tar xf "../$FILENAME" --strip-components=1 \
|
||||
"$TAR_PREFIX"/i686-w64-mingw32/bin/SDL2.dll \
|
||||
"$TAR_PREFIX"/i686-w64-mingw32/include/ \
|
||||
"$TAR_PREFIX"/i686-w64-mingw32/lib/ \
|
||||
"$TAR_PREFIX"/x86_64-w64-mingw32/bin/SDL2.dll \
|
||||
"$TAR_PREFIX"/x86_64-w64-mingw32/include/ \
|
||||
"$TAR_PREFIX"/x86_64-w64-mingw32/lib/ \
|
||||
@@ -13,7 +13,7 @@ BEGIN
|
||||
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
|
||||
VALUE "OriginalFilename", "scrcpy.exe"
|
||||
VALUE "ProductName", "scrcpy"
|
||||
VALUE "ProductVersion", "2.4"
|
||||
VALUE "ProductVersion", "2.3.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
12
app/scrcpy.1
12
app/scrcpy.1
@@ -190,6 +190,8 @@ For "uhid" and "aoa", the keyboard layout must be configured (once and for all)
|
||||
|
||||
adb shell am start -a android.settings.HARD_KEYBOARD_SETTINGS
|
||||
|
||||
If mirroring is enabled, the shortcot MOD+k opens it.
|
||||
|
||||
This option is only available when the HID keyboard is enabled (or a physical keyboard is connected).
|
||||
|
||||
Also see \fB\-\-mouse\fR.
|
||||
@@ -577,14 +579,6 @@ Flip display horizontally
|
||||
.B MOD+Shift+Up, MOD+Shift+Down
|
||||
Flip display vertically
|
||||
|
||||
.TP
|
||||
.B MOD+z
|
||||
Pause or re-pause display
|
||||
|
||||
.TP
|
||||
.B MOD+Shift+z
|
||||
Unpause display
|
||||
|
||||
.TP
|
||||
.B MOD+g
|
||||
Resize window to 1:1 (pixel\-perfect)
|
||||
@@ -722,7 +716,7 @@ Report bugs to <https://github.com/Genymobile/scrcpy/issues>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2018 Genymobile <https://www.genymobile.com>
|
||||
|
||||
Copyright \(co 2018\-2024 Romain Vimont <rom@rom1v.com>
|
||||
Copyright \(co 2018\-2023 Romain Vimont <rom@rom1v.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0.
|
||||
|
||||
|
||||
@@ -374,11 +374,11 @@ static const struct sc_option options[] = {
|
||||
"Possible values are \"disabled\", \"sdk\", \"uhid\" and "
|
||||
"\"aoa\".\n"
|
||||
"\"disabled\" does not send keyboard inputs to the device.\n"
|
||||
"\"sdk\" uses the Android system API to deliver keyboard "
|
||||
"\"sdk\" uses the Android system API to deliver keyboard\n"
|
||||
"events to applications.\n"
|
||||
"\"uhid\" simulates a physical HID keyboard using the Linux "
|
||||
"UHID kernel module on the device.\n"
|
||||
"\"aoa\" simulates a physical keyboard using the AOAv2 "
|
||||
"UHID kernel module on the device."
|
||||
"\"aoa\" simulates a physical HID keyboard using the AOAv2\n"
|
||||
"protocol. It may only work over USB.\n"
|
||||
"For \"uhid\" and \"aoa\", the keyboard layout must be "
|
||||
"configured (once and for all) on the device, via Settings -> "
|
||||
@@ -477,11 +477,11 @@ static const struct sc_option options[] = {
|
||||
"Possible values are \"disabled\", \"sdk\", \"uhid\" and "
|
||||
"\"aoa\".\n"
|
||||
"\"disabled\" does not send mouse inputs to the device.\n"
|
||||
"\"sdk\" uses the Android system API to deliver mouse events"
|
||||
"to applications.\n"
|
||||
"\"sdk\" uses the Android system API to deliver mouse\n"
|
||||
"events to applications.\n"
|
||||
"\"uhid\" simulates a physical HID mouse using the Linux UHID "
|
||||
"kernel module on the device.\n"
|
||||
"\"aoa\" simulates a physical mouse using the AOAv2 protocol. "
|
||||
"kernel module on the device."
|
||||
"\"aoa\" simulates a physical mouse using the AOAv2 protocol\n"
|
||||
"It may only work over USB.\n"
|
||||
"In \"uhid\" and \"aoa\" modes, the computer mouse is captured "
|
||||
"to control the device directly (relative mouse mode).\n"
|
||||
@@ -583,7 +583,7 @@ static const struct sc_option options[] = {
|
||||
"mirroring is disabled.\n"
|
||||
"LAlt, LSuper or RSuper toggle the mouse capture mode, to give "
|
||||
"control of the mouse back to the computer.\n"
|
||||
"Keyboard and mouse may be disabled separately using"
|
||||
"Keyboard and mouse may be disabled separately using\n"
|
||||
"--keyboard=disabled and --mouse=disabled.\n"
|
||||
"It may only work over USB.\n"
|
||||
"See --keyboard and --mouse.",
|
||||
@@ -900,14 +900,6 @@ static const struct sc_shortcut shortcuts[] = {
|
||||
.shortcuts = { "MOD+Shift+Up", "MOD+Shift+Down" },
|
||||
.text = "Flip display vertically",
|
||||
},
|
||||
{
|
||||
.shortcuts = { "MOD+z" },
|
||||
.text = "Pause or re-pause display",
|
||||
},
|
||||
{
|
||||
.shortcuts = { "MOD+Shift+z" },
|
||||
.text = "Unpause display",
|
||||
},
|
||||
{
|
||||
.shortcuts = { "MOD+g" },
|
||||
.text = "Resize window to 1:1 (pixel-perfect)",
|
||||
|
||||
@@ -59,10 +59,9 @@ sc_display_init(struct sc_display *display, SDL_Window *window, bool mipmaps) {
|
||||
LOGI("Trilinear filtering disabled");
|
||||
}
|
||||
} else if (mipmaps) {
|
||||
LOGD("Trilinear filtering disabled (not an OpenGL renderer)");
|
||||
LOGD("Trilinear filtering disabled (not an OpenGL renderer");
|
||||
}
|
||||
|
||||
display->texture = NULL;
|
||||
display->pending.flags = 0;
|
||||
display->pending.frame = NULL;
|
||||
|
||||
|
||||
@@ -402,7 +402,6 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
const SDL_KeyboardEvent *event) {
|
||||
// controller is NULL if --no-control is requested
|
||||
bool control = im->controller;
|
||||
bool paused = im->screen->paused;
|
||||
|
||||
SDL_Keycode keycode = event->keysym.sym;
|
||||
uint16_t mod = event->keysym.mod;
|
||||
@@ -428,51 +427,46 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP;
|
||||
switch (keycode) {
|
||||
case SDLK_h:
|
||||
if (im->kp && !shift && !repeat && !paused) {
|
||||
if (im->kp && !shift && !repeat) {
|
||||
action_home(im, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_b: // fall-through
|
||||
case SDLK_BACKSPACE:
|
||||
if (im->kp && !shift && !repeat && !paused) {
|
||||
if (im->kp && !shift && !repeat) {
|
||||
action_back(im, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_s:
|
||||
if (im->kp && !shift && !repeat && !paused) {
|
||||
if (im->kp && !shift && !repeat) {
|
||||
action_app_switch(im, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_m:
|
||||
if (im->kp && !shift && !repeat && !paused) {
|
||||
if (im->kp && !shift && !repeat) {
|
||||
action_menu(im, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_p:
|
||||
if (im->kp && !shift && !repeat && !paused) {
|
||||
if (im->kp && !shift && !repeat) {
|
||||
action_power(im, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_o:
|
||||
if (control && !repeat && down && !paused) {
|
||||
if (control && !repeat && down) {
|
||||
enum sc_screen_power_mode mode = shift
|
||||
? SC_SCREEN_POWER_MODE_NORMAL
|
||||
: SC_SCREEN_POWER_MODE_OFF;
|
||||
set_screen_power_mode(im, mode);
|
||||
}
|
||||
return;
|
||||
case SDLK_z:
|
||||
if (down && !repeat) {
|
||||
sc_screen_set_paused(im->screen, !shift);
|
||||
}
|
||||
return;
|
||||
case SDLK_DOWN:
|
||||
if (shift) {
|
||||
if (!repeat & down) {
|
||||
apply_orientation_transform(im,
|
||||
SC_ORIENTATION_FLIP_180);
|
||||
}
|
||||
} else if (im->kp && !paused) {
|
||||
} else if (im->kp) {
|
||||
// forward repeated events
|
||||
action_volume_down(im, action);
|
||||
}
|
||||
@@ -483,7 +477,7 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
apply_orientation_transform(im,
|
||||
SC_ORIENTATION_FLIP_180);
|
||||
}
|
||||
} else if (im->kp && !paused) {
|
||||
} else if (im->kp) {
|
||||
// forward repeated events
|
||||
action_volume_up(im, action);
|
||||
}
|
||||
@@ -511,17 +505,17 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
}
|
||||
return;
|
||||
case SDLK_c:
|
||||
if (im->kp && !shift && !repeat && down && !paused) {
|
||||
if (im->kp && !shift && !repeat && down) {
|
||||
get_device_clipboard(im, SC_COPY_KEY_COPY);
|
||||
}
|
||||
return;
|
||||
case SDLK_x:
|
||||
if (im->kp && !shift && !repeat && down && !paused) {
|
||||
if (im->kp && !shift && !repeat && down) {
|
||||
get_device_clipboard(im, SC_COPY_KEY_CUT);
|
||||
}
|
||||
return;
|
||||
case SDLK_v:
|
||||
if (im->kp && !repeat && down && !paused) {
|
||||
if (im->kp && !repeat && down) {
|
||||
if (shift || im->legacy_paste) {
|
||||
// inject the text as input events
|
||||
clipboard_paste(im);
|
||||
@@ -553,7 +547,7 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
}
|
||||
return;
|
||||
case SDLK_n:
|
||||
if (control && !repeat && down && !paused) {
|
||||
if (control && !repeat && down) {
|
||||
if (shift) {
|
||||
collapse_panels(im);
|
||||
} else if (im->key_repeat == 0) {
|
||||
@@ -564,12 +558,12 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
}
|
||||
return;
|
||||
case SDLK_r:
|
||||
if (control && !shift && !repeat && down && !paused) {
|
||||
if (control && !shift && !repeat && down) {
|
||||
rotate_device(im);
|
||||
}
|
||||
return;
|
||||
case SDLK_k:
|
||||
if (control && !shift && !repeat && down && !paused
|
||||
if (control && !shift && !repeat && down
|
||||
&& im->kp && im->kp->hid) {
|
||||
// Only if the current keyboard is hid
|
||||
open_hard_keyboard_settings(im);
|
||||
@@ -580,7 +574,7 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!im->kp || paused) {
|
||||
if (!im->kp) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -628,6 +622,7 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_mouse_motion(struct sc_input_manager *im,
|
||||
const SDL_MouseMotionEvent *event) {
|
||||
|
||||
if (event->which == SDL_TOUCH_MOUSEID) {
|
||||
// simulated from touch events, so it's a duplicate
|
||||
return;
|
||||
@@ -700,16 +695,16 @@ sc_input_manager_process_touch(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_mouse_button(struct sc_input_manager *im,
|
||||
const SDL_MouseButtonEvent *event) {
|
||||
bool control = im->controller;
|
||||
|
||||
if (event->which == SDL_TOUCH_MOUSEID) {
|
||||
// simulated from touch events, so it's a duplicate
|
||||
return;
|
||||
}
|
||||
|
||||
bool control = im->controller;
|
||||
bool paused = im->screen->paused;
|
||||
bool down = event->type == SDL_MOUSEBUTTONDOWN;
|
||||
if (!im->forward_all_clicks) {
|
||||
if (control && !paused) {
|
||||
if (control) {
|
||||
enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP;
|
||||
|
||||
if (im->kp && event->button == SDL_BUTTON_X1) {
|
||||
@@ -752,7 +747,7 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im,
|
||||
// otherwise, send the click event to the device
|
||||
}
|
||||
|
||||
if (!im->mp || paused) {
|
||||
if (!im->mp) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -890,10 +885,9 @@ void
|
||||
sc_input_manager_handle_event(struct sc_input_manager *im,
|
||||
const SDL_Event *event) {
|
||||
bool control = im->controller;
|
||||
bool paused = im->screen->paused;
|
||||
switch (event->type) {
|
||||
case SDL_TEXTINPUT:
|
||||
if (!im->kp || paused) {
|
||||
if (!im->kp) {
|
||||
break;
|
||||
}
|
||||
sc_input_manager_process_text_input(im, &event->text);
|
||||
@@ -905,13 +899,13 @@ sc_input_manager_handle_event(struct sc_input_manager *im,
|
||||
sc_input_manager_process_key(im, &event->key);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
if (!im->mp || paused) {
|
||||
if (!im->mp) {
|
||||
break;
|
||||
}
|
||||
sc_input_manager_process_mouse_motion(im, &event->motion);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (!im->mp || paused) {
|
||||
if (!im->mp) {
|
||||
break;
|
||||
}
|
||||
sc_input_manager_process_mouse_wheel(im, &event->wheel);
|
||||
@@ -925,7 +919,7 @@ sc_input_manager_handle_event(struct sc_input_manager *im,
|
||||
case SDL_FINGERMOTION:
|
||||
case SDL_FINGERDOWN:
|
||||
case SDL_FINGERUP:
|
||||
if (!im->mp || paused) {
|
||||
if (!im->mp) {
|
||||
break;
|
||||
}
|
||||
sc_input_manager_process_touch(im, &event->tfinger);
|
||||
|
||||
@@ -106,6 +106,7 @@ static BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
|
||||
|
||||
static void
|
||||
sdl_set_hints(const char *render_driver) {
|
||||
|
||||
if (render_driver && !SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver)) {
|
||||
LOGW("Could not set render driver");
|
||||
}
|
||||
@@ -311,10 +312,6 @@ scrcpy_generate_scid(void) {
|
||||
enum scrcpy_exit_code
|
||||
scrcpy(struct scrcpy_options *options) {
|
||||
static struct scrcpy scrcpy;
|
||||
#ifndef NDEBUG
|
||||
// Detect missing initializations
|
||||
memset(&scrcpy, 42, sizeof(scrcpy));
|
||||
#endif
|
||||
struct scrcpy *s = &scrcpy;
|
||||
|
||||
// Minimal SDL initialization
|
||||
@@ -408,12 +405,6 @@ scrcpy(struct scrcpy_options *options) {
|
||||
return SCRCPY_EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (options->video_playback) {
|
||||
// Set hints before starting the server thread to avoid race conditions
|
||||
// in SDL
|
||||
sdl_set_hints(options->render_driver);
|
||||
}
|
||||
|
||||
if (!sc_server_start(&s->server)) {
|
||||
goto end;
|
||||
}
|
||||
@@ -430,6 +421,10 @@ scrcpy(struct scrcpy_options *options) {
|
||||
assert(!options->video_playback || options->video);
|
||||
assert(!options->audio_playback || options->audio);
|
||||
|
||||
if (options->video_playback) {
|
||||
sdl_set_hints(options->render_driver);
|
||||
}
|
||||
|
||||
if (options->video_playback ||
|
||||
(options->control && options->clipboard_autosync)) {
|
||||
// Initialize the video subsystem even if --no-video or
|
||||
@@ -662,6 +657,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||
kp = &s->keyboard_uhid.key_processor;
|
||||
}
|
||||
|
||||
// mouse_input_mode may have been reset if AOA mode failed
|
||||
if (options->mouse_input_mode == SC_MOUSE_INPUT_MODE_SDK) {
|
||||
sc_mouse_sdk_init(&s->mouse_sdk, &s->controller);
|
||||
mp = &s->mouse_sdk.mouse_processor;
|
||||
|
||||
@@ -362,8 +362,6 @@ sc_screen_init(struct sc_screen *screen,
|
||||
screen->maximized = false;
|
||||
screen->minimized = false;
|
||||
screen->mouse_capture_key_pressed = 0;
|
||||
screen->paused = false;
|
||||
screen->resume_frame = NULL;
|
||||
|
||||
screen->req.x = params->window_x;
|
||||
screen->req.y = params->window_y;
|
||||
@@ -616,10 +614,13 @@ prepare_for_frame(struct sc_screen *screen, struct sc_size new_frame_size) {
|
||||
}
|
||||
|
||||
static bool
|
||||
sc_screen_apply_frame(struct sc_screen *screen) {
|
||||
sc_screen_update_frame(struct sc_screen *screen) {
|
||||
av_frame_unref(screen->frame);
|
||||
sc_frame_buffer_consume(&screen->fb, screen->frame);
|
||||
AVFrame *frame = screen->frame;
|
||||
|
||||
sc_fps_counter_add_rendered_frame(&screen->fps_counter);
|
||||
|
||||
AVFrame *frame = screen->frame;
|
||||
struct sc_size new_frame_size = {frame->width, frame->height};
|
||||
enum sc_display_result res = prepare_for_frame(screen, new_frame_size);
|
||||
if (res == SC_DISPLAY_RESULT_ERROR) {
|
||||
@@ -654,54 +655,6 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
sc_screen_update_frame(struct sc_screen *screen) {
|
||||
if (screen->paused) {
|
||||
if (!screen->resume_frame) {
|
||||
screen->resume_frame = av_frame_alloc();
|
||||
if (!screen->resume_frame) {
|
||||
LOG_OOM();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
av_frame_unref(screen->resume_frame);
|
||||
}
|
||||
sc_frame_buffer_consume(&screen->fb, screen->resume_frame);
|
||||
return true;
|
||||
}
|
||||
|
||||
av_frame_unref(screen->frame);
|
||||
sc_frame_buffer_consume(&screen->fb, screen->frame);
|
||||
return sc_screen_apply_frame(screen);
|
||||
}
|
||||
|
||||
void
|
||||
sc_screen_set_paused(struct sc_screen *screen, bool paused) {
|
||||
if (!paused && !screen->paused) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
if (screen->paused && screen->resume_frame) {
|
||||
// If display screen was paused, refresh the frame immediately, even if
|
||||
// the new state is also paused.
|
||||
av_frame_free(&screen->frame);
|
||||
screen->frame = screen->resume_frame;
|
||||
screen->resume_frame = NULL;
|
||||
sc_screen_apply_frame(screen);
|
||||
}
|
||||
|
||||
if (!paused) {
|
||||
LOGI("Display screen unpaused");
|
||||
} else if (!screen->paused) {
|
||||
LOGI("Display screen paused");
|
||||
} else {
|
||||
LOGI("Display screen re-paused");
|
||||
}
|
||||
|
||||
screen->paused = paused;
|
||||
}
|
||||
|
||||
void
|
||||
sc_screen_switch_fullscreen(struct sc_screen *screen) {
|
||||
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
@@ -64,9 +64,6 @@ struct sc_screen {
|
||||
SDL_Keycode mouse_capture_key_pressed;
|
||||
|
||||
AVFrame *frame;
|
||||
|
||||
bool paused;
|
||||
AVFrame *resume_frame;
|
||||
};
|
||||
|
||||
struct sc_screen_params {
|
||||
@@ -138,10 +135,6 @@ void
|
||||
sc_screen_set_orientation(struct sc_screen *screen,
|
||||
enum sc_orientation orientation);
|
||||
|
||||
// set the display pause state
|
||||
void
|
||||
sc_screen_set_paused(struct sc_screen *screen, bool paused);
|
||||
|
||||
// react to SDL events
|
||||
// If this function returns false, scrcpy must exit with an error.
|
||||
bool
|
||||
|
||||
@@ -23,8 +23,7 @@ struct sc_key_processor {
|
||||
*/
|
||||
bool async_paste;
|
||||
|
||||
/**
|
||||
* Set by the implementation to indicate that the keyboard is HID. In
|
||||
/** Set by the implementation to indicate that the keyboard is HID. In
|
||||
* practice, it is used to react on a shortcut to open the hard keyboard
|
||||
* settings only if the keyboard is HID.
|
||||
*/
|
||||
|
||||
@@ -233,10 +233,10 @@ install` must be run as root)._
|
||||
|
||||
#### Option 2: Use prebuilt server
|
||||
|
||||
- [`scrcpy-server-v2.4`][direct-scrcpy-server]
|
||||
<sub>SHA-256: `93c272b7438605c055e127f7444064ed78fa9ca49f81156777fd201e79ce7ba3`</sub>
|
||||
- [`scrcpy-server-v2.3.1`][direct-scrcpy-server]
|
||||
<sub>SHA-256: `f6814822fc308a7a532f253485c9038183c6296a6c5df470a9e383b4f8e7605b`</sub>
|
||||
|
||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-server-v2.4
|
||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-server-v2.3.1
|
||||
|
||||
Download the prebuilt server somewhere, and specify its path during the Meson
|
||||
configuration:
|
||||
|
||||
@@ -67,6 +67,14 @@ computer.
|
||||
An option `--tcpip` allows to configure the connection automatically. There are
|
||||
two variants.
|
||||
|
||||
If the device (accessible at 192.168.1.1 in this example) already listens on a
|
||||
port (typically 5555) for incoming _adb_ connections, then run:
|
||||
|
||||
```bash
|
||||
scrcpy --tcpip=192.168.1.1 # default port is 5555
|
||||
scrcpy --tcpip=192.168.1.1:5555
|
||||
```
|
||||
|
||||
If _adb_ TCP/IP mode is disabled on the device (or if you don't know the IP
|
||||
address), connect the device over USB, then run:
|
||||
|
||||
@@ -77,14 +85,6 @@ scrcpy --tcpip # without arguments
|
||||
It will automatically find the device IP address and adb port, enable TCP/IP
|
||||
mode if necessary, then connect to the device before starting.
|
||||
|
||||
If the device (accessible at 192.168.1.1 in this example) already listens on a
|
||||
port (typically 5555) for incoming _adb_ connections, then run:
|
||||
|
||||
```bash
|
||||
scrcpy --tcpip=192.168.1.1 # default port is 5555
|
||||
scrcpy --tcpip=192.168.1.1:5555
|
||||
```
|
||||
|
||||
|
||||
### Manual
|
||||
|
||||
|
||||
@@ -67,16 +67,12 @@ More precisely, hold down <kbd>Ctrl</kbd> while pressing the left-click button.
|
||||
Until the left-click button is released, all mouse movements scale and rotate
|
||||
the content (if supported by the app) relative to the center of the screen.
|
||||
|
||||
https://github.com/Genymobile/scrcpy/assets/543275/26c4a920-9805-43f1-8d4c-608752d04767
|
||||
|
||||
To simulate a tilt gesture: <kbd>Shift</kbd>+_click-and-move-up-or-down_.
|
||||
|
||||
https://github.com/Genymobile/scrcpy/assets/543275/1e252341-4a90-4b29-9d11-9153b324669f
|
||||
|
||||
Technically, _scrcpy_ generates additional touch events from a "virtual finger"
|
||||
at a location inverted through the center of the screen. When pressing
|
||||
<kbd>Ctrl</kbd> the _x_ and _y_ coordinates are inverted. Using <kbd>Shift</kbd>
|
||||
only inverts _x_.
|
||||
<kbd>Ctrl</kbd> the x and y coordinates are inverted. Using <kbd>Shift</kbd>
|
||||
only inverts x.
|
||||
|
||||
This only works for the default mouse mode (`--mouse=sdk`).
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ options for this mouse mode to work. See
|
||||
|
||||
Two modes allow to simulate a physical HID mouse on the device.
|
||||
|
||||
In these modes, the computer mouse is "captured": the mouse pointer disappears
|
||||
In these modes, the computer mouse is "captured": the mouse pointer disapeears
|
||||
from the computer and appears on the Android device instead.
|
||||
|
||||
Special capture keys, either <kbd>Alt</kbd> or <kbd>Super</kbd>, toggle
|
||||
|
||||
@@ -34,4 +34,4 @@ It only works if the device is connected over USB.
|
||||
|
||||
## OTG issues on Windows
|
||||
|
||||
See [FAQ](/FAQ.md#otg-issues-on-windows).
|
||||
See [FAQ](/FAQ.md#hidotg-issues-on-windows).
|
||||
|
||||
@@ -28,8 +28,6 @@ _<kbd>[Super]</kbd> is typically the <kbd>Windows</kbd> or <kbd>Cmd</kbd> key._
|
||||
| Rotate display right | <kbd>MOD</kbd>+<kbd>→</kbd> _(right)_
|
||||
| Flip display horizontally | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>←</kbd> _(left)_ \| <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>→</kbd> _(right)_
|
||||
| Flip display vertically | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>↑</kbd> _(up)_ \| <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>↓</kbd> _(down)_
|
||||
| Pause or re-pause display | <kbd>MOD</kbd>+<kbd>z</kbd>
|
||||
| Unpause display | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>z</kbd>
|
||||
| Resize window to 1:1 (pixel-perfect) | <kbd>MOD</kbd>+<kbd>g</kbd>
|
||||
| Resize window to remove black borders | <kbd>MOD</kbd>+<kbd>w</kbd> \| _Double-left-click¹_
|
||||
| Click on `HOME` | <kbd>MOD</kbd>+<kbd>h</kbd> \| _Middle-click_
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
Download the [latest release]:
|
||||
|
||||
- [`scrcpy-win64-v2.4.zip`][direct-win64] (64-bit)
|
||||
<sub>SHA-256: `9dc56f21bfa455352ec0c58b40feaf2fb02d67372910a4235e298ece286ff3a9`</sub>
|
||||
- [`scrcpy-win32-v2.4.zip`][direct-win32] (32-bit)
|
||||
<sub>SHA-256: `cf92acc45eef37c6ee2db819f92e420ced3bc50f1348dd57f7d6ca1fc80f6116`</sub>
|
||||
- [`scrcpy-win64-v2.3.1.zip`][direct-win64] (64-bit)
|
||||
<sub>SHA-256: `f1f78ac98214078425804e524a1bed515b9d4b8a05b78d210a4ced2b910b262d`</sub>
|
||||
- [`scrcpy-win32-v2.3.1.zip`][direct-win32] (32-bit)
|
||||
<sub>SHA-256: `5dffc2d432e9b8b5b0e16f12e71428c37c70d9124cfbe7620df0b41b7efe91ff`</sub>
|
||||
|
||||
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-win64-v2.4.zip
|
||||
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-win32-v2.4.zip
|
||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-win64-v2.3.1.zip
|
||||
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-win32-v2.3.1.zip
|
||||
|
||||
and extract it.
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
set -e
|
||||
|
||||
BUILDDIR=build-auto
|
||||
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-server-v2.4
|
||||
PREBUILT_SERVER_SHA256=93c272b7438605c055e127f7444064ed78fa9ca49f81156777fd201e79ce7ba3
|
||||
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-server-v2.3.1
|
||||
PREBUILT_SERVER_SHA256=f6814822fc308a7a532f253485c9038183c6296a6c5df470a9e383b4f8e7605b
|
||||
|
||||
echo "[scrcpy] Downloading prebuilt server..."
|
||||
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('scrcpy', 'c',
|
||||
version: '2.4',
|
||||
version: '2.3.1',
|
||||
meson_version: '>= 0.48',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
|
||||
50
release.mk
50
release.mk
@@ -62,38 +62,38 @@ build-server:
|
||||
meson setup "$(SERVER_BUILD_DIR)" --buildtype release -Dcompile_app=false )
|
||||
ninja -C "$(SERVER_BUILD_DIR)"
|
||||
|
||||
prepare-deps-win32:
|
||||
@app/deps/adb.sh win32
|
||||
@app/deps/sdl.sh win32
|
||||
@app/deps/ffmpeg.sh win32
|
||||
@app/deps/libusb.sh win32
|
||||
prepare-deps:
|
||||
@app/prebuilt-deps/prepare-adb.sh
|
||||
@app/prebuilt-deps/prepare-sdl.sh
|
||||
@app/prebuilt-deps/prepare-ffmpeg.sh
|
||||
@app/prebuilt-deps/prepare-libusb.sh
|
||||
|
||||
prepare-deps-win64:
|
||||
@app/deps/adb.sh win64
|
||||
@app/deps/sdl.sh win64
|
||||
@app/deps/ffmpeg.sh win64
|
||||
@app/deps/libusb.sh win64
|
||||
|
||||
build-win32: prepare-deps-win32
|
||||
build-win32: prepare-deps
|
||||
rm -rf "$(WIN32_BUILD_DIR)"
|
||||
mkdir -p "$(WIN32_BUILD_DIR)/local"
|
||||
cp -r app/prebuilt-deps/data/ffmpeg-6.1-scrcpy-3/win32/. "$(WIN32_BUILD_DIR)/local/"
|
||||
cp -r app/prebuilt-deps/data/SDL2-2.28.5/i686-w64-mingw32/. "$(WIN32_BUILD_DIR)/local/"
|
||||
cp -r app/prebuilt-deps/data/libusb-1.0.26/libusb-MinGW-Win32/. "$(WIN32_BUILD_DIR)/local/"
|
||||
meson setup "$(WIN32_BUILD_DIR)" \
|
||||
--pkg-config-path="app/deps/work/install/win32/lib/pkgconfig" \
|
||||
-Dc_args="-I$(PWD)/app/deps/work/install/win32/include" \
|
||||
-Dc_link_args="-L$(PWD)/app/deps/work/install/win32/lib" \
|
||||
--pkg-config-path="$(WIN32_BUILD_DIR)/local/lib/pkgconfig" \
|
||||
-Dc_args="-I$(PWD)/$(WIN32_BUILD_DIR)/local/include" \
|
||||
-Dc_link_args="-L$(PWD)/$(WIN32_BUILD_DIR)/local/lib" \
|
||||
--cross-file=cross_win32.txt \
|
||||
--buildtype=release --strip -Db_lto=true \
|
||||
-Dcompile_server=false \
|
||||
-Dportable=true
|
||||
ninja -C "$(WIN32_BUILD_DIR)"
|
||||
|
||||
build-win64: prepare-deps-win64
|
||||
build-win64: prepare-deps
|
||||
rm -rf "$(WIN64_BUILD_DIR)"
|
||||
mkdir -p "$(WIN64_BUILD_DIR)/local"
|
||||
cp -r app/prebuilt-deps/data/ffmpeg-6.1-scrcpy-3/win64/. "$(WIN64_BUILD_DIR)/local/"
|
||||
cp -r app/prebuilt-deps/data/SDL2-2.28.5/x86_64-w64-mingw32/. "$(WIN64_BUILD_DIR)/local/"
|
||||
cp -r app/prebuilt-deps/data/libusb-1.0.26/libusb-MinGW-x64/. "$(WIN64_BUILD_DIR)/local/"
|
||||
meson setup "$(WIN64_BUILD_DIR)" \
|
||||
--pkg-config-path="app/deps/work/install/win64/lib/pkgconfig" \
|
||||
-Dc_args="-I$(PWD)/app/deps/work/install/win64/include" \
|
||||
-Dc_link_args="-L$(PWD)/app/deps/work/install/win64/lib" \
|
||||
--pkg-config-path="$(WIN64_BUILD_DIR)/local/lib/pkgconfig" \
|
||||
-Dc_args="-I$(PWD)/$(WIN64_BUILD_DIR)/local/include" \
|
||||
-Dc_link_args="-L$(PWD)/$(WIN64_BUILD_DIR)/local/lib" \
|
||||
--cross-file=cross_win64.txt \
|
||||
--buildtype=release --strip -Db_lto=true \
|
||||
-Dcompile_server=false \
|
||||
@@ -108,8 +108,10 @@ dist-win32: build-server build-win32
|
||||
cp app/data/scrcpy-noconsole.vbs "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/data/icon.png "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/data/open_a_terminal_here.bat "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/deps/work/install/win32/bin/*.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/deps/work/install/win32/bin/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/prebuilt-deps/data/platform-tools-34.0.5/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/prebuilt-deps/data/platform-tools-34.0.5/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp app/prebuilt-deps/data/platform-tools-34.0.5/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp "$(WIN32_BUILD_DIR)"/local/bin/*.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
|
||||
dist-win64: build-server build-win64
|
||||
mkdir -p "$(DIST)/$(WIN64_TARGET_DIR)"
|
||||
@@ -119,8 +121,10 @@ dist-win64: build-server build-win64
|
||||
cp app/data/scrcpy-noconsole.vbs "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/data/icon.png "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/data/open_a_terminal_here.bat "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/deps/work/install/win64/bin/*.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/deps/work/install/win64/bin/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/prebuilt-deps/data/platform-tools-34.0.5/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/prebuilt-deps/data/platform-tools-34.0.5/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp app/prebuilt-deps/data/platform-tools-34.0.5/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp "$(WIN64_BUILD_DIR)"/local/bin/*.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
|
||||
zip-win32: dist-win32
|
||||
cd "$(DIST)"; \
|
||||
|
||||
@@ -7,8 +7,8 @@ android {
|
||||
applicationId "com.genymobile.scrcpy"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 34
|
||||
versionCode 20400
|
||||
versionName "2.4"
|
||||
versionCode 20301
|
||||
versionName "2.3.1"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
set -e
|
||||
|
||||
SCRCPY_DEBUG=false
|
||||
SCRCPY_VERSION_NAME=2.4
|
||||
SCRCPY_VERSION_NAME=2.3.1
|
||||
|
||||
PLATFORM=${ANDROID_PLATFORM:-34}
|
||||
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-34.0.0}
|
||||
|
||||
Reference in New Issue
Block a user