From 068253a3a299a60d78c7c1b0e760f4bbe3b75bc1 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Sat, 4 May 2019 17:48:20 +0200 Subject: [PATCH 01/11] Fix mouse focus clickthrough Mouse focus clickthrough didn't work due to compat.h header not being included in scrcpy.c. Signed-off-by: Romain Vimont --- app/src/scrcpy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 61b3f8d9..ebcd81ba 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -9,6 +9,7 @@ #include "command.h" #include "common.h" +#include "compat.h" #include "controller.h" #include "decoder.h" #include "device.h" From b941854c7375a0c9a9f3ef957ccbf659e645490c Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Sat, 4 May 2019 17:48:20 +0200 Subject: [PATCH 02/11] Disable X11 compositor bypass Compositor bypass is meant for fullscreen games consuming lots of GPU resources. For a light app that will usually be windowed, this only causes unnecessary compositor suspends, especially visible (and annoying) with complying window manager like KWin. Signed-off-by: Romain Vimont --- app/src/compat.h | 5 +++++ app/src/scrcpy.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/app/src/compat.h b/app/src/compat.h index fd68d61a..de667bbf 100644 --- a/app/src/compat.h +++ b/app/src/compat.h @@ -43,4 +43,9 @@ # define SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP #endif +#if SDL_VERSION_ATLEAST(2, 0, 8) +// +# define SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR +#endif + #endif diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index ebcd81ba..b777b770 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -69,6 +69,13 @@ sdl_init_and_configure(bool display) { } #endif +#ifdef SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR + // Disable compositor bypassing on X11 + if (!SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")) { + LOGW("Could not disable X11 compositor bypass"); + } +#endif + // Do not disable the screensaver when scrcpy is running SDL_EnableScreenSaver(); From eeb8e8420fcca9aecaef3b15cee027cb7c03f325 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 12 May 2019 14:31:18 +0200 Subject: [PATCH 03/11] Use size_t for command length The size of an array should have type size_t. --- app/src/command.c | 2 +- app/src/command.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/command.c b/app/src/command.c index 2e116ac8..c30bebe0 100644 --- a/app/src/command.c +++ b/app/src/command.c @@ -37,7 +37,7 @@ show_adb_err_msg(enum process_result err) { } process_t -adb_execute(const char *serial, const char *const adb_cmd[], int len) { +adb_execute(const char *serial, const char *const adb_cmd[], size_t len) { const char *cmd[len + 4]; int i; process_t process; diff --git a/app/src/command.h b/app/src/command.h index 6681f5ea..90eb7cb2 100644 --- a/app/src/command.h +++ b/app/src/command.h @@ -49,7 +49,7 @@ bool cmd_simple_wait(process_t pid, exit_code_t *exit_code); process_t -adb_execute(const char *serial, const char *const adb_cmd[], int len); +adb_execute(const char *serial, const char *const adb_cmd[], size_t len); process_t adb_forward(const char *serial, uint16_t local_port, From e443518ed902b678ad33886a2e626bfb70f8cd45 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 12 May 2019 15:11:16 +0200 Subject: [PATCH 04/11] Print adb command on error When the execution of an adb command fails, print the command. This will help to understand what went wrong. See . --- app/src/command.c | 48 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/app/src/command.c b/app/src/command.c index c30bebe0..2c6d45aa 100644 --- a/app/src/command.c +++ b/app/src/command.c @@ -1,5 +1,6 @@ #include "command.h" +#include #include #include #include @@ -20,15 +21,52 @@ get_adb_command(void) { return adb_command; } +// serialize argv to string "[arg1], [arg2], [arg3]" +static size_t +argv_to_string(const char *const *argv, char *buf, size_t bufsize) { + size_t idx = 0; + bool first = true; + while (*argv) { + const char *arg = *argv; + size_t len = strlen(arg); + // count space for "[], ...\0" + if (idx + len + 8 >= bufsize) { + // not enough space, truncate + assert(idx < bufsize - 4); + memcpy(&buf[idx], "...", 3); + idx += 3; + break; + } + if (first) { + first = false; + } else { + buf[idx++] = ','; + buf[idx++] = ' '; + } + buf[idx++] = '['; + memcpy(&buf[idx], arg, len); + idx += len; + buf[idx++] = ']'; + argv++; + } + assert(idx < bufsize); + buf[idx] = '\0'; + return idx; +} + static void -show_adb_err_msg(enum process_result err) { +show_adb_err_msg(enum process_result err, const char *const argv[]) { + char buf[512]; switch (err) { case PROCESS_ERROR_GENERIC: - LOGE("Failed to execute adb"); + argv_to_string(argv, buf, sizeof(buf)); + LOGE("Failed to execute: %s", buf); break; case PROCESS_ERROR_MISSING_BINARY: - LOGE("'adb' command not found (make it accessible from your PATH " - "or define its full path in the ADB environment variable)"); + argv_to_string(argv, buf, sizeof(buf)); + LOGE("Command not found: %s", buf); + LOGE("(make 'adb' accessible from your PATH or define its full" + "path in the ADB environment variable)"); break; case PROCESS_SUCCESS: /* do nothing */ @@ -54,7 +92,7 @@ adb_execute(const char *serial, const char *const adb_cmd[], size_t len) { cmd[len + i] = NULL; enum process_result r = cmd_execute(cmd[0], cmd, &process); if (r != PROCESS_SUCCESS) { - show_adb_err_msg(r); + show_adb_err_msg(r, cmd); return PROCESS_NONE; } return process; From 2dc1a594714ddc688b7403b4ef96eb41301055ae Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Mon, 20 May 2019 09:44:45 +0200 Subject: [PATCH 05/11] Check surface returned for icon SDL_CreateRGBSurfaceFrom() may return NULL, causing a segfault. --- app/src/tiny_xpm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/tiny_xpm.c b/app/src/tiny_xpm.c index 01fd280f..0fb410f3 100644 --- a/app/src/tiny_xpm.c +++ b/app/src/tiny_xpm.c @@ -105,6 +105,10 @@ read_xpm(char *xpm[]) { width, height, 32, 4 * width, rmask, gmask, bmask, amask); + if (!surface) { + LOGE("Could not create icon surface"); + return NULL; + } // make the surface own the raw pixels surface->flags &= ~SDL_PREALLOC; return surface; From 3133d5d1c7a652a0227a979ddd6b021c4e7aa8c1 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 23 May 2019 20:58:08 +0200 Subject: [PATCH 06/11] Continue on icon loading failure If loading the icon from xpm fails, launch scrcpy without window icon. --- app/src/screen.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/screen.c b/app/src/screen.c index 8476e94f..67b268c5 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -177,13 +177,12 @@ screen_init_rendering(struct screen *screen, const char *device_name, } SDL_Surface *icon = read_xpm(icon_xpm); - if (!icon) { - LOGE("Could not load icon: %s", SDL_GetError()); - screen_destroy(screen); - return false; + if (icon) { + SDL_SetWindowIcon(screen->window, icon); + SDL_FreeSurface(icon); + } else { + LOGW("Could not load icon"); } - SDL_SetWindowIcon(screen->window, icon); - SDL_FreeSurface(icon); LOGI("Initial texture: %" PRIu16 "x%" PRIu16, frame_size.width, frame_size.height); From a920ba647140d29fedd2dc7bf167464ebc336d9e Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 24 May 2019 13:21:53 +0200 Subject: [PATCH 07/11] Explain how to customize path in README --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 7bf203ba..5daafb2e 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,19 @@ _¹Double-click on black borders to remove them._ _²Right-click turns the screen on if it was off, presses BACK otherwise._ +## Custom paths + +To use a specific _adb_ binary, configure its path in the environment variable +`ADB`: + + ADB=/path/to/adb scrcpy + +To override the path of the `scrcpy-server.jar` file (it can be [useful] on +Windows), configure its path in `SCRCPY_SERVER_PATH`. + +[useful]: https://github.com/Genymobile/scrcpy/issues/278#issuecomment-429330345 + + ## Why _scrcpy_? A colleague challenged me to find a name as unpronounceable as [gnirehtet]. From b3bd5f1b80ee0da8bd7eae7318cb1e7b164f46d2 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 24 May 2019 17:15:32 +0200 Subject: [PATCH 08/11] Remove useless casts to (void *) --- app/src/file_handler.c | 2 +- app/src/server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/file_handler.c b/app/src/file_handler.c index d3dedcd2..e9d5e02b 100644 --- a/app/src/file_handler.c +++ b/app/src/file_handler.c @@ -30,7 +30,7 @@ request_free(struct request *req) { return; } SDL_free((void *) req->file); - SDL_free((void *) req); + SDL_free(req); } static bool diff --git a/app/src/server.c b/app/src/server.c index 972fbbaa..c37e0070 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -210,7 +210,7 @@ server_start(struct server *server, const char *serial, close_socket(&server->server_socket); } disable_tunnel(server); - SDL_free((void *) server->serial); + SDL_free(server->serial); return false; } From c3779d8513dbb1d80d29132aaf1550080c07dda7 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 24 May 2019 17:24:17 +0200 Subject: [PATCH 09/11] Make owned serial a pointer-to-non-const The file handler owns the serial, so it needs to free it. Therefore, it should not be a pointer-to-const. --- app/src/file_handler.c | 2 +- app/src/file_handler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/file_handler.c b/app/src/file_handler.c index e9d5e02b..c4366691 100644 --- a/app/src/file_handler.c +++ b/app/src/file_handler.c @@ -121,7 +121,7 @@ file_handler_destroy(struct file_handler *file_handler) { SDL_DestroyCond(file_handler->event_cond); SDL_DestroyMutex(file_handler->mutex); request_queue_destroy(&file_handler->queue); - SDL_free((void *) file_handler->serial); + SDL_free(file_handler->serial); } static process_t diff --git a/app/src/file_handler.h b/app/src/file_handler.h index 111161dc..5d50289d 100644 --- a/app/src/file_handler.h +++ b/app/src/file_handler.h @@ -21,7 +21,7 @@ struct request_queue { }; struct file_handler { - const char *serial; + char *serial; SDL_Thread *thread; SDL_mutex *mutex; SDL_cond *event_cond; From a41dd6c79f542925c5db7f1ee51d27b65ba832ec Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 24 May 2019 17:25:31 +0200 Subject: [PATCH 10/11] Make owned filename a pointer-to-non-const The file handler owns the filename string, so it needs to free it. Therefore, it should not be a pointer-to-const. --- app/src/file_handler.c | 8 ++++---- app/src/file_handler.h | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/file_handler.c b/app/src/file_handler.c index c4366691..c72b598d 100644 --- a/app/src/file_handler.c +++ b/app/src/file_handler.c @@ -10,11 +10,11 @@ struct request { file_handler_action_t action; - const char *file; + char *file; }; static struct request * -request_new(file_handler_action_t action, const char *file) { +request_new(file_handler_action_t action, char *file) { struct request *req = SDL_malloc(sizeof(*req)); if (!req) { return NULL; @@ -29,7 +29,7 @@ request_free(struct request *req) { if (!req) { return; } - SDL_free((void *) req->file); + SDL_free(req->file); SDL_free(req); } @@ -137,7 +137,7 @@ push_file(const char *serial, const char *file) { bool file_handler_request(struct file_handler *file_handler, file_handler_action_t action, - const char *file) { + char *file) { bool res; // start file_handler if it's used for the first time diff --git a/app/src/file_handler.h b/app/src/file_handler.h index 5d50289d..382477d8 100644 --- a/app/src/file_handler.h +++ b/app/src/file_handler.h @@ -46,9 +46,10 @@ file_handler_stop(struct file_handler *file_handler); void file_handler_join(struct file_handler *file_handler); +// take ownership of file, and will SDL_free() it bool file_handler_request(struct file_handler *file_handler, file_handler_action_t action, - const char *file); + char *file); #endif From 5d473efeb5c4f42a75aad6ab5892e2813358c0c9 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Mon, 27 May 2019 10:19:03 +0200 Subject: [PATCH 11/11] Bind Home key to MOVE_HOME On pressing Home key on the computer, move the cursor to the beginning of the line instead of going back to the home screen. Fixes (part of) . --- app/src/convert.c | 2 +- app/src/main.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/convert.c b/app/src/convert.c index d20e255f..504befe0 100644 --- a/app/src/convert.c +++ b/app/src/convert.c @@ -81,9 +81,9 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod) { MAP(SDLK_ESCAPE, AKEYCODE_ESCAPE); MAP(SDLK_BACKSPACE, AKEYCODE_DEL); MAP(SDLK_TAB, AKEYCODE_TAB); - MAP(SDLK_HOME, AKEYCODE_HOME); MAP(SDLK_PAGEUP, AKEYCODE_PAGE_UP); MAP(SDLK_DELETE, AKEYCODE_FORWARD_DEL); + MAP(SDLK_HOME, AKEYCODE_MOVE_HOME); MAP(SDLK_END, AKEYCODE_MOVE_END); MAP(SDLK_PAGEDOWN, AKEYCODE_PAGE_DOWN); MAP(SDLK_RIGHT, AKEYCODE_DPAD_RIGHT); diff --git a/app/src/main.c b/app/src/main.c index c61db725..fe93673f 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -105,7 +105,6 @@ static void usage(const char *arg0) { " resize window to remove black borders\n" "\n" " Ctrl+h\n" - " Home\n" " Middle-click\n" " click on HOME\n" "\n"