Compare commits

...

19 Commits

Author SHA1 Message Date
Romain Vimont
eff50368bf Add pinch-to-zoom simulation
If Ctrl is hold when the left-click button is pressed, enable
pinch-to-zoom to scale and rotate relative to the center of the screen.

Fixes #24 <https://github.com/Genymobile/scrcpy/issues/24>
2020-08-09 16:58:51 +02:00
Yu-Chen Lin
a59a15777d Fix missing change of Ctrl key in README
PR #1652 <https://github.com/Genymobile/scrcpy/pull/1652>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-08-09 11:14:38 +02:00
Jozef Hollý
a2cb63e344 Add packaging status
PR #1650 <https://github.com/Genymobile/scrcpy/pull/1650>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-08-08 13:18:23 +02:00
Romain Vimont
f03a3edde6 Update links to v1.15.1 in README and BUILD 2020-08-07 12:13:27 +02:00
Romain Vimont
633a51e9c4 Bump version to 1.15.1 2020-08-07 12:01:34 +02:00
Romain Vimont
976761956f Fix uninitialized repeat count in key events
A new "repeat" field has been added by
3c1ed5d86c, but it was not initialized in
every code path.

As a consequence, keycodes generated by shortcuts were sent with an
undetermined value, breaking some shortcuts (especially HOME) randomly.

Fixes #1643 <https://github.com/Genymobile/scrcpy/issues/1643>
2020-08-07 11:32:11 +02:00
Romain Vimont
521f2fe994 Update links to v1.15 in README and BUILD 2020-08-06 21:56:06 +02:00
Romain Vimont
edc4f7675f Bump version to 1.15 2020-08-06 21:00:48 +02:00
Romain Vimont
712f1fa6b2 Upgrade FFmpeg (4.3.1) for Windows
Include the latest version of FFmpeg in Windows releases.
2020-08-06 21:00:48 +02:00
Romain Vimont
1ba06037f8 Upgrade platform-tools (30.0.4) for Windows
Include the latest version of adb in Windows releases.
2020-08-06 21:00:48 +02:00
Romain Vimont
da63e3774b Merge branch 'master' into dev 2020-08-06 21:00:15 +02:00
brunoais
cf9d44979c Keep the screen off on powering on
PR #1577 <https://github.com/Genymobile/scrcpy/pull/1577>
Fixes #1573 <https://github.com/Genymobile/scrcpy/issues/1573>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-08-03 19:51:58 +02:00
xeropresence
84f1d9e375 Add --no-key-repeat cli option
Add an option to avoid forwarding repeated key events.

PR #1623 <https://github.com/Genymobile/scrcpy/pull/1623>
Refs #1013 <https://github.com/Genymobile/scrcpy/issues/1013>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-08-03 19:51:55 +02:00
NGAU Zeonfung
5086e7b744 Update BUILD.md
Update the macOS section.

PR #1559 <https://github.com/Genymobile/scrcpy/pull/1559>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-07-07 20:50:09 +02:00
axxx007xxxz
e99b896ae2 README: Add Fedora install instructions
PR #1549 <https://github.com/Genymobile/scrcpy/pull/1549>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-06-27 15:51:44 +02:00
Hossam Elbadissi
8c27f59aa5 Improve linguistic
PR #1543 <https://github.com/Genymobile/scrcpy/pull/1543>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-06-25 22:08:02 +02:00
AreYouLoco?
42641d2737 Fix typo in README.md
PR #1523 <https://github.com/Genymobile/scrcpy/pull/1523>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-06-18 21:13:35 +02:00
Romain Vimont
3c0fc8f54f Mention sndcpy 2020-06-09 22:09:23 +02:00
Louis Leseur
1b73eff3c9 Add missing file in build_without_gradle.sh
Fixes #1481 <https://github.com/Genymobile/scrcpy/issues/1481>
PR #1482 <https://github.com/Genymobile/scrcpy/pull/1482>

Signed-off-by: Louis Leseur <louis.leseur@gmail.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-06-07 22:00:35 +02:00
16 changed files with 206 additions and 56 deletions

View File

@@ -176,8 +176,8 @@ Additionally, if you want to build the server, install Java 8 from Caskroom, and
make it avaliable from the `PATH`:
```bash
brew tap caskroom/versions
brew cask install java8
brew tap homebrew/cask-versions
brew cask install adoptopenjdk/openjdk/adoptopenjdk8
export JAVA_HOME="$(/usr/libexec/java_home --version 1.8)"
export PATH="$JAVA_HOME/bin:$PATH"
```
@@ -190,12 +190,17 @@ See [pierlon/scrcpy-docker](https://github.com/pierlon/scrcpy-docker).
## Common steps
If you want to build the server, install the [Android SDK] (_Android Studio_),
and set `ANDROID_HOME` to its directory. For example:
and set `ANDROID_SDK_ROOT` to its directory. For example:
[Android SDK]: https://developer.android.com/studio/index.html
```bash
export ANDROID_HOME=~/android/sdk
# Linux
export ANDROID_SDK_ROOT=~/Android/Sdk
# Mac
export ANDROID_SDK_ROOT=~/Library/Android/sdk
# Windows
set ANDROID_SDK_ROOT=%LOCALAPPDATA%\Android\sdk
```
If you don't want to build the server, use the [prebuilt server].
@@ -249,10 +254,10 @@ You can then [run](README.md#run) _scrcpy_.
## Prebuilt server
- [`scrcpy-server-v1.14`][direct-scrcpy-server]
_(SHA-256: 1d1b18a2b80e956771fd63b99b414d2d028713a8f12ddfa5a369709ad4295620)_
- [`scrcpy-server-v1.15.1`][direct-scrcpy-server]
_(SHA-256: fe06bd6a30da8c89860bf5e16eecce2b5054d4644c84289670ce00ca5d1637c3)_
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.14/scrcpy-server-v1.14
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.15.1/scrcpy-server-v1.15.1
Download the prebuilt server somewhere, and specify its path during the Meson
configuration:

View File

@@ -100,11 +100,11 @@ dist-win32: build-server build-win32 build-win32-noconsole
cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server "$(DIST)/$(WIN32_TARGET_DIR)/"
cp "$(WIN32_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
cp "$(WIN32_NOCONSOLE_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/scrcpy-noconsole.exe"
cp prebuilt-deps/ffmpeg-4.2.2-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win32-shared/bin/swscale-5.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/swscale-5.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
@@ -115,11 +115,11 @@ dist-win64: build-server build-win64 build-win64-noconsole
cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server "$(DIST)/$(WIN64_TARGET_DIR)/"
cp "$(WIN64_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
cp "$(WIN64_NOCONSOLE_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/scrcpy-noconsole.exe"
cp prebuilt-deps/ffmpeg-4.2.2-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.2.2-win64-shared/bin/swscale-5.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/swscale-5.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"

View File

@@ -1,4 +1,4 @@
# scrcpy (v1.14)
# scrcpy (v1.15.1)
This application provides display and control of Android devices connected on
USB (or [over TCP/IP][article-tcpip]). It does not require any _root_ access.
@@ -34,6 +34,7 @@ control it using keyboard and mouse.
## Get the app
<a href="https://repology.org/project/scrcpy/versions"><img src="https://repology.org/badge/vertical-allrepos/scrcpy.svg" alt="Packaging status" align="right"></a>
### Linux
@@ -49,6 +50,11 @@ A [Snap] package is available: [`scrcpy`][snap-link].
[snap]: https://en.wikipedia.org/wiki/Snappy_(package_manager)
For Fedora, a [COPR] package is available: [`scrcpy`][copr-link].
[COPR]: https://fedoraproject.org/wiki/Category:Copr
[copr-link]: https://copr.fedorainfracloud.org/coprs/zeno/scrcpy/
For Arch Linux, an [AUR] package is available: [`scrcpy`][aur-link].
[AUR]: https://wiki.archlinux.org/index.php/Arch_User_Repository
@@ -69,10 +75,10 @@ hard).
For Windows, for simplicity, a prebuilt archive with all the dependencies
(including `adb`) is available:
- [`scrcpy-win64-v1.14.zip`][direct-win64]
_(SHA-256: 2be9139e46e29cf2f5f695848bb2b75a543b8f38be1133257dc5068252abc25f)_
- [`scrcpy-win64-v1.15.1.zip`][direct-win64]
_(SHA-256: 78fba4caad6328016ea93219254b5df391f24224c519a2c8e3f070695b8b38ff)_
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.14/scrcpy-win64-v1.14.zip
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.15.1/scrcpy-win64-v1.15.1.zip
It is also available in [Chocolatey]:
@@ -301,7 +307,7 @@ ssh -CN -L5037:localhost:5037 -L27183:localhost:27183 your_remote_computer
From another terminal:
```bash
scrcpy --force-adb-forwrad
scrcpy --force-adb-forward
```
@@ -440,10 +446,14 @@ scrcpy -S
Or by pressing <kbd>MOD</kbd>+<kbd>o</kbd> at any time.
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd> (or
`POWER`, <kbd>MOD</kbd>+<kbd>p</kbd>).
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd>.
It can be useful to also prevent the device to sleep:
On Android, the `POWER` button always turns the screen on. For convenience, if
`POWER` is sent via scrcpy (via right-click or <kbd>MOD</kbd>+<kbd>p</kbd>), it
will force to turn the screen off after a small delay (on a best effort basis).
The physical `POWER` button will still cause the screen to be turned on.
It can also be useful to prevent the device from sleeping:
```bash
scrcpy --turn-screen-off --stay-awake
@@ -558,6 +568,18 @@ scrcpy --prefer-text
[prefertext]: https://github.com/Genymobile/scrcpy/issues/650#issuecomment-512945343
#### Key repeat
By default, holding a key down generates repeated key events. This can cause
performance problems in some games, where these events are useless anyway.
To avoid forwarding repeated key events:
```bash
scrcpy --no-key-repeat
```
### File drop
#### Install APK
@@ -584,11 +606,11 @@ scrcpy --push-target /sdcard/foo/bar/
### Audio forwarding
Audio is not forwarded by _scrcpy_. Use [USBaudio] (Linux-only).
Audio is not forwarded by _scrcpy_. Use [sndcpy].
Also see [issue #14].
[USBaudio]: https://github.com/rom1v/usbaudio
[sndcpy]: https://github.com/rom1v/sndcpy
[issue #14]: https://github.com/Genymobile/scrcpy/issues/14

View File

@@ -96,6 +96,10 @@ Do not display device (only when screen recording is enabled).
.B \-\-no\-mipmaps
If the renderer is OpenGL 3.0+ or OpenGL ES 2.0+, then mipmaps are automatically generated to improve downscaling quality. This option disables the generation of mipmaps.
.TP
.B \-\-no\-key\-repeat
Do not forward repeated key events when a key is held down.
.TP
.BI "\-p, \-\-port " port[:port]
Set the TCP port (range) used by the client to listen.

View File

@@ -92,6 +92,9 @@ scrcpy_print_usage(const char *arg0) {
" mipmaps are automatically generated to improve downscaling\n"
" quality. This option disables the generation of mipmaps.\n"
"\n"
" --no-key-repeat\n"
" Do not forward repeated key events when a key is held down.\n"
"\n"
" -p, --port port[:port]\n"
" Set the TCP port (range) used by the client to listen.\n"
" Default is %d:%d.\n"
@@ -642,6 +645,7 @@ guess_record_format(const char *filename) {
#define OPT_FORCE_ADB_FORWARD 1019
#define OPT_DISABLE_SCREENSAVER 1020
#define OPT_SHORTCUT_MOD 1021
#define OPT_NO_KEY_REPEAT 1022
bool
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
@@ -664,6 +668,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
{"no-control", no_argument, NULL, 'n'},
{"no-display", no_argument, NULL, 'N'},
{"no-mipmaps", no_argument, NULL, OPT_NO_MIPMAPS},
{"no-key-repeat", no_argument, NULL, OPT_NO_KEY_REPEAT},
{"port", required_argument, NULL, 'p'},
{"prefer-text", no_argument, NULL, OPT_PREFER_TEXT},
{"push-target", required_argument, NULL, OPT_PUSH_TARGET},
@@ -829,6 +834,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
case OPT_NO_MIPMAPS:
opts->mipmaps = false;
break;
case OPT_NO_KEY_REPEAT:
opts->forward_key_repeat = false;
break;
case OPT_CODEC_OPTIONS:
opts->codec_options = optarg;
break;

View File

@@ -17,6 +17,7 @@
#define CONTROL_MSG_CLIPBOARD_TEXT_MAX_LENGTH (CONTROL_MSG_MAX_SIZE - 6)
#define POINTER_ID_MOUSE UINT64_C(-1);
#define POINTER_ID_VIRTUAL_FINGER UINT64_C(-2);
enum control_msg_type {
CONTROL_MSG_TYPE_INJECT_KEYCODE,

View File

@@ -58,6 +58,7 @@ input_manager_init(struct input_manager *im,
const struct scrcpy_options *options)
{
im->control = options->control;
im->forward_key_repeat = options->forward_key_repeat;
im->prefer_text = options->prefer_text;
const struct sc_shortcut_mods *shortcut_mods = &options->shortcut_mods;
@@ -69,6 +70,8 @@ input_manager_init(struct input_manager *im,
im->sdl_shortcut_mods.data[i] = sdl_mod;
}
im->sdl_shortcut_mods.count = shortcut_mods->count;
im->vfinger_down = false;
}
static void
@@ -79,6 +82,7 @@ send_keycode(struct controller *controller, enum android_keycode keycode,
msg.type = CONTROL_MSG_TYPE_INJECT_KEYCODE;
msg.inject_keycode.keycode = keycode;
msg.inject_keycode.metastate = 0;
msg.inject_keycode.repeat = 0;
if (actions & ACTION_DOWN) {
msg.inject_keycode.action = AKEY_EVENT_ACTION_DOWN;
@@ -297,6 +301,36 @@ input_manager_process_text_input(struct input_manager *im,
}
}
static bool
simulate_virtual_finger(struct input_manager *im,
enum android_motionevent_action action,
struct point point) {
bool up = action == AMOTION_EVENT_ACTION_UP;
struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
msg.inject_touch_event.action = action;
msg.inject_touch_event.position.screen_size = im->screen->frame_size;
msg.inject_touch_event.position.point = point;
msg.inject_touch_event.pointer_id = POINTER_ID_VIRTUAL_FINGER;
msg.inject_touch_event.pressure = up ? 0.0f : 1.0f;
msg.inject_touch_event.buttons = 0;
if (!controller_push_msg(im->controller, &msg)) {
LOGW("Could not request 'inject virtual finger event'");
return false;
}
return true;
}
static struct point
inverse_point(struct point point, struct size size) {
point.x = size.width - point.x;
point.y = size.height - point.y;
return point;
}
static bool
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to,
bool prefer_text, uint32_t repeat) {
@@ -461,6 +495,9 @@ input_manager_process_key(struct input_manager *im,
}
if (event->repeat) {
if (!im->forward_key_repeat) {
return;
}
++im->repeat;
} else {
im->repeat = 0;
@@ -507,10 +544,20 @@ input_manager_process_mouse_motion(struct input_manager *im,
return;
}
struct control_msg msg;
if (convert_mouse_motion(event, im->screen, &msg)) {
if (!convert_mouse_motion(event, im->screen, &msg)) {
return;
}
if (!controller_push_msg(im->controller, &msg)) {
LOGW("Could not request 'inject mouse motion event'");
}
if (im->vfinger_down) {
struct point mouse = msg.inject_touch_event.position.point;
struct point vfinger = inverse_point(mouse, im->screen->frame_size);
if (!simulate_virtual_finger(im, AMOTION_EVENT_ACTION_MOVE, vfinger)) {
return;
}
}
}
@@ -582,7 +629,9 @@ input_manager_process_mouse_button(struct input_manager *im,
// simulated from touch events, so it's a duplicate
return;
}
if (event->type == SDL_MOUSEBUTTONDOWN) {
bool down = event->type == SDL_MOUSEBUTTONDOWN;
if (down) {
if (control && event->button == SDL_BUTTON_RIGHT) {
press_back_or_turn_screen_on(im->controller);
return;
@@ -613,10 +662,36 @@ input_manager_process_mouse_button(struct input_manager *im,
}
struct control_msg msg;
if (convert_mouse_button(event, im->screen, &msg)) {
if (!convert_mouse_button(event, im->screen, &msg)) {
return;
}
if (!controller_push_msg(im->controller, &msg)) {
LOGW("Could not request 'inject mouse button event'");
return;
}
// Pinch-to-zoom simulation.
//
// If Ctrl is hold when the left-click button is pressed, then
// pinch-to-zoom mode is enabled: on every mouse event until the left-click
// button is released, an additional "virtual finger" event is generated,
// having a position inversed with respect to the center of the screen.
//
// In other words, the center of the rotation/scaling is the center of the
// screen.
#define CTRL_PRESSED (SDL_GetModState() & (KMOD_LCTRL | KMOD_RCTRL))
if ((down && !im->vfinger_down && CTRL_PRESSED)
|| (!down && im->vfinger_down)) {
struct point mouse = msg.inject_touch_event.position.point;
struct point vfinger = inverse_point(mouse, im->screen->frame_size);
enum android_motionevent_action action = down
? AMOTION_EVENT_ACTION_DOWN
: AMOTION_EVENT_ACTION_UP;
if (!simulate_virtual_finger(im, action, vfinger)) {
return;
}
im->vfinger_down = down;
}
}

View File

@@ -23,12 +23,15 @@ struct input_manager {
unsigned repeat;
bool control;
bool forward_key_repeat;
bool prefer_text;
struct {
unsigned data[SC_MAX_SHORTCUT_MODS];
unsigned count;
} sdl_shortcut_mods;
bool vfinger_down;
};
void

View File

@@ -78,6 +78,7 @@ struct scrcpy_options {
bool stay_awake;
bool force_adb_forward;
bool disable_screensaver;
bool forward_key_repeat;
};
#define SCRCPY_OPTIONS_DEFAULT { \
@@ -121,6 +122,7 @@ struct scrcpy_options {
.stay_awake = false, \
.force_adb_forward = false, \
.disable_screensaver = false, \
.forward_key_repeat = true, \
}
bool

View File

@@ -15,6 +15,6 @@ cpu = 'i686'
endian = 'little'
[properties]
prebuilt_ffmpeg_shared = 'ffmpeg-4.2.2-win32-shared'
prebuilt_ffmpeg_dev = 'ffmpeg-4.2.2-win32-dev'
prebuilt_ffmpeg_shared = 'ffmpeg-4.3.1-win32-shared'
prebuilt_ffmpeg_dev = 'ffmpeg-4.3.1-win32-dev'
prebuilt_sdl2 = 'SDL2-2.0.12/i686-w64-mingw32'

View File

@@ -15,6 +15,6 @@ cpu = 'x86_64'
endian = 'little'
[properties]
prebuilt_ffmpeg_shared = 'ffmpeg-4.2.2-win64-shared'
prebuilt_ffmpeg_dev = 'ffmpeg-4.2.2-win64-dev'
prebuilt_ffmpeg_shared = 'ffmpeg-4.3.1-win64-shared'
prebuilt_ffmpeg_dev = 'ffmpeg-4.3.1-win64-dev'
prebuilt_sdl2 = 'SDL2-2.0.12/x86_64-w64-mingw32'

View File

@@ -1,5 +1,5 @@
project('scrcpy', 'c',
version: '1.14',
version: '1.15.1',
meson_version: '>= 0.48',
default_options: [
'c_std=c11',

View File

@@ -10,24 +10,24 @@ prepare-win32: prepare-sdl2 prepare-ffmpeg-shared-win32 prepare-ffmpeg-dev-win32
prepare-win64: prepare-sdl2 prepare-ffmpeg-shared-win64 prepare-ffmpeg-dev-win64 prepare-adb
prepare-ffmpeg-shared-win32:
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.2.2-win32-shared.zip \
ab5d603aaa54de360db2c2ffe378c82376b9343ea1175421dd644639aa07ee31 \
ffmpeg-4.2.2-win32-shared
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.3.1-win32-shared.zip \
357af9901a456f4dcbacd107e83a934d344c9cb07ddad8aaf80612eeab7d26d2 \
ffmpeg-4.3.1-win32-shared
prepare-ffmpeg-dev-win32:
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.2.2-win32-dev.zip \
8d224be567a2950cad4be86f4aabdd045bfa52ad758e87c72cedd278613bc6c8 \
ffmpeg-4.2.2-win32-dev
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.3.1-win32-dev.zip \
230efb08e9bcf225bd474da29676c70e591fc94d8790a740ca801408fddcb78b \
ffmpeg-4.3.1-win32-dev
prepare-ffmpeg-shared-win64:
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.2.2-win64-shared.zip \
5aedf268952b7d9f6541dbfcb47cd86a7e7881a3b7ba482fd3bc4ca33bda7bf5 \
ffmpeg-4.2.2-win64-shared
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.3.1-win64-shared.zip \
dd29b7f92f48dead4dd940492c7509138c0f99db445076d0a597007298a79940 \
ffmpeg-4.3.1-win64-shared
prepare-ffmpeg-dev-win64:
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.2.2-win64-dev.zip \
f4885f859c5b0d6663c2a0a4c1cf035b1c60b146402790b796bd3ad84f4f3ca2 \
ffmpeg-4.2.2-win64-dev
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.3.1-win64-dev.zip \
2e8038242cf8e1bd095c2978f196ff0462b122cc6ef7e74626a6af15459d8b81 \
ffmpeg-4.3.1-win64-dev
prepare-sdl2:
@./prepare-dep https://libsdl.org/release/SDL2-devel-2.0.12-mingw.tar.gz \
@@ -35,6 +35,6 @@ prepare-sdl2:
SDL2-2.0.12
prepare-adb:
@./prepare-dep https://dl.google.com/android/repository/platform-tools_r30.0.0-windows.zip \
854305f9a702f5ea2c3de73edde402bd26afa0ee944c9b0c4380420f5a862e0d \
@./prepare-dep https://dl.google.com/android/repository/platform-tools_r30.0.4-windows.zip \
413182fff6c5957911e231b9e97e6be4fc6a539035e3dfb580b5c54bd5950fee \
platform-tools

View File

@@ -6,8 +6,8 @@ android {
applicationId "com.genymobile.scrcpy"
minSdkVersion 21
targetSdkVersion 29
versionCode 16
versionName "1.14"
versionCode 18
versionName "1.15.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {

View File

@@ -12,7 +12,7 @@
set -e
SCRCPY_DEBUG=false
SCRCPY_VERSION_NAME=1.14
SCRCPY_VERSION_NAME=1.15.1
PLATFORM=${ANDROID_PLATFORM:-29}
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-29.0.2}
@@ -42,6 +42,8 @@ echo "Generating java from aidl..."
cd "$SERVER_DIR/src/main/aidl"
"$ANDROID_HOME/build-tools/$BUILD_TOOLS/aidl" -o"$CLASSES_DIR" \
android/view/IRotationWatcher.aidl
"$ANDROID_HOME/build-tools/$BUILD_TOOLS/aidl" -o"$CLASSES_DIR" \
android/content/IOnPrimaryClipChangedListener.aidl
echo "Compiling java sources..."
cd ../java
@@ -55,6 +57,7 @@ cd "$CLASSES_DIR"
"$ANDROID_HOME/build-tools/$BUILD_TOOLS/dx" --dex \
--output "$BUILD_DIR/classes.dex" \
android/view/*.class \
android/content/*.class \
com/genymobile/scrcpy/*.class \
com/genymobile/scrcpy/wrappers/*.class

View File

@@ -8,11 +8,16 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Controller {
private static final int DEVICE_ID_VIRTUAL = -1;
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
private final Device device;
private final DesktopConnection connection;
private final DeviceMessageSender sender;
@@ -24,6 +29,8 @@ public class Controller {
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
private final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[PointersState.MAX_POINTERS];
private boolean keepPowerModeOff;
public Controller(Device device, DesktopConnection connection) {
this.device = device;
this.connection = connection;
@@ -117,6 +124,7 @@ public class Controller {
int mode = msg.getAction();
boolean setPowerModeOk = Device.setScreenPowerMode(mode);
if (setPowerModeOk) {
keepPowerModeOff = mode == Device.POWER_MODE_OFF;
Ln.i("Device screen turned " + (mode == Device.POWER_MODE_OFF ? "off" : "on"));
}
}
@@ -130,6 +138,9 @@ public class Controller {
}
private boolean injectKeycode(int action, int keycode, int repeat, int metaState) {
if (keepPowerModeOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
schedulePowerModeOff();
}
return device.injectKeyEvent(action, keycode, repeat, metaState);
}
@@ -223,8 +234,24 @@ public class Controller {
return device.injectEvent(event);
}
/**
* Schedule a call to set power mode to off after a small delay.
*/
private static void schedulePowerModeOff() {
EXECUTOR.schedule(new Runnable() {
@Override
public void run() {
Ln.i("Forcing screen off");
Device.setScreenPowerMode(Device.POWER_MODE_OFF);
}
}, 200, TimeUnit.MILLISECONDS);
}
private boolean pressBackOrTurnScreenOn() {
int keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_WAKEUP;
if (keepPowerModeOff && keycode == KeyEvent.KEYCODE_WAKEUP) {
schedulePowerModeOff();
}
return device.injectKeycode(keycode);
}