Merge branch 'master' into dev

twosockets
Romain Vimont 5 years ago
commit b75f0e9427

@ -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._ _²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_? ## Why _scrcpy_?
A colleague challenged me to find a name as unpronounceable as [gnirehtet]. A colleague challenged me to find a name as unpronounceable as [gnirehtet].

@ -1,5 +1,6 @@
#include "command.h" #include "command.h"
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -20,15 +21,52 @@ get_adb_command(void) {
return adb_command; 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 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) { switch (err) {
case PROCESS_ERROR_GENERIC: case PROCESS_ERROR_GENERIC:
LOGE("Failed to execute adb"); argv_to_string(argv, buf, sizeof(buf));
LOGE("Failed to execute: %s", buf);
break; break;
case PROCESS_ERROR_MISSING_BINARY: case PROCESS_ERROR_MISSING_BINARY:
LOGE("'adb' command not found (make it accessible from your PATH " argv_to_string(argv, buf, sizeof(buf));
"or define its full path in the ADB environment variable)"); LOGE("Command not found: %s", buf);
LOGE("(make 'adb' accessible from your PATH or define its full"
"path in the ADB environment variable)");
break; break;
case PROCESS_SUCCESS: case PROCESS_SUCCESS:
/* do nothing */ /* do nothing */
@ -37,7 +75,7 @@ show_adb_err_msg(enum process_result err) {
} }
process_t 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]; const char *cmd[len + 4];
int i; int i;
process_t process; process_t process;
@ -54,7 +92,7 @@ adb_execute(const char *serial, const char *const adb_cmd[], int len) {
cmd[len + i] = NULL; cmd[len + i] = NULL;
enum process_result r = cmd_execute(cmd[0], cmd, &process); enum process_result r = cmd_execute(cmd[0], cmd, &process);
if (r != PROCESS_SUCCESS) { if (r != PROCESS_SUCCESS) {
show_adb_err_msg(r); show_adb_err_msg(r, cmd);
return PROCESS_NONE; return PROCESS_NONE;
} }
return process; return process;

@ -49,7 +49,7 @@ bool
cmd_simple_wait(process_t pid, exit_code_t *exit_code); cmd_simple_wait(process_t pid, exit_code_t *exit_code);
process_t 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 process_t
adb_forward(const char *serial, uint16_t local_port, adb_forward(const char *serial, uint16_t local_port,

@ -43,4 +43,9 @@
# define SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP # define SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
#endif #endif
#if SDL_VERSION_ATLEAST(2, 0, 8)
// <https://hg.libsdl.org/SDL/rev/dfde5d3f9781>
# define SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
#endif
#endif #endif

@ -81,9 +81,9 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod) {
MAP(SDLK_ESCAPE, AKEYCODE_ESCAPE); MAP(SDLK_ESCAPE, AKEYCODE_ESCAPE);
MAP(SDLK_BACKSPACE, AKEYCODE_DEL); MAP(SDLK_BACKSPACE, AKEYCODE_DEL);
MAP(SDLK_TAB, AKEYCODE_TAB); MAP(SDLK_TAB, AKEYCODE_TAB);
MAP(SDLK_HOME, AKEYCODE_HOME);
MAP(SDLK_PAGEUP, AKEYCODE_PAGE_UP); MAP(SDLK_PAGEUP, AKEYCODE_PAGE_UP);
MAP(SDLK_DELETE, AKEYCODE_FORWARD_DEL); MAP(SDLK_DELETE, AKEYCODE_FORWARD_DEL);
MAP(SDLK_HOME, AKEYCODE_MOVE_HOME);
MAP(SDLK_END, AKEYCODE_MOVE_END); MAP(SDLK_END, AKEYCODE_MOVE_END);
MAP(SDLK_PAGEDOWN, AKEYCODE_PAGE_DOWN); MAP(SDLK_PAGEDOWN, AKEYCODE_PAGE_DOWN);
MAP(SDLK_RIGHT, AKEYCODE_DPAD_RIGHT); MAP(SDLK_RIGHT, AKEYCODE_DPAD_RIGHT);

@ -10,11 +10,11 @@
struct request { struct request {
file_handler_action_t action; file_handler_action_t action;
const char *file; char *file;
}; };
static struct request * 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)); struct request *req = SDL_malloc(sizeof(*req));
if (!req) { if (!req) {
return NULL; return NULL;
@ -29,8 +29,8 @@ request_free(struct request *req) {
if (!req) { if (!req) {
return; return;
} }
SDL_free((void *) req->file); SDL_free(req->file);
SDL_free((void *) req); SDL_free(req);
} }
static bool static bool
@ -121,7 +121,7 @@ file_handler_destroy(struct file_handler *file_handler) {
SDL_DestroyCond(file_handler->event_cond); SDL_DestroyCond(file_handler->event_cond);
SDL_DestroyMutex(file_handler->mutex); SDL_DestroyMutex(file_handler->mutex);
request_queue_destroy(&file_handler->queue); request_queue_destroy(&file_handler->queue);
SDL_free((void *) file_handler->serial); SDL_free(file_handler->serial);
} }
static process_t static process_t
@ -137,7 +137,7 @@ push_file(const char *serial, const char *file) {
bool bool
file_handler_request(struct file_handler *file_handler, file_handler_request(struct file_handler *file_handler,
file_handler_action_t action, file_handler_action_t action,
const char *file) { char *file) {
bool res; bool res;
// start file_handler if it's used for the first time // start file_handler if it's used for the first time

@ -21,7 +21,7 @@ struct request_queue {
}; };
struct file_handler { struct file_handler {
const char *serial; char *serial;
SDL_Thread *thread; SDL_Thread *thread;
SDL_mutex *mutex; SDL_mutex *mutex;
SDL_cond *event_cond; SDL_cond *event_cond;
@ -46,9 +46,10 @@ file_handler_stop(struct file_handler *file_handler);
void void
file_handler_join(struct file_handler *file_handler); file_handler_join(struct file_handler *file_handler);
// take ownership of file, and will SDL_free() it
bool bool
file_handler_request(struct file_handler *file_handler, file_handler_request(struct file_handler *file_handler,
file_handler_action_t action, file_handler_action_t action,
const char *file); char *file);
#endif #endif

@ -105,7 +105,6 @@ static void usage(const char *arg0) {
" resize window to remove black borders\n" " resize window to remove black borders\n"
"\n" "\n"
" Ctrl+h\n" " Ctrl+h\n"
" Home\n"
" Middle-click\n" " Middle-click\n"
" click on HOME\n" " click on HOME\n"
"\n" "\n"

@ -9,6 +9,7 @@
#include "command.h" #include "command.h"
#include "common.h" #include "common.h"
#include "compat.h"
#include "controller.h" #include "controller.h"
#include "decoder.h" #include "decoder.h"
#include "device.h" #include "device.h"
@ -68,6 +69,13 @@ sdl_init_and_configure(bool display) {
} }
#endif #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 // Do not disable the screensaver when scrcpy is running
SDL_EnableScreenSaver(); SDL_EnableScreenSaver();

@ -177,13 +177,12 @@ screen_init_rendering(struct screen *screen, const char *device_name,
} }
SDL_Surface *icon = read_xpm(icon_xpm); SDL_Surface *icon = read_xpm(icon_xpm);
if (!icon) { if (icon) {
LOGE("Could not load icon: %s", SDL_GetError()); SDL_SetWindowIcon(screen->window, icon);
screen_destroy(screen); SDL_FreeSurface(icon);
return false; } else {
LOGW("Could not load icon");
} }
SDL_SetWindowIcon(screen->window, icon);
SDL_FreeSurface(icon);
LOGI("Initial texture: %" PRIu16 "x%" PRIu16, frame_size.width, LOGI("Initial texture: %" PRIu16 "x%" PRIu16, frame_size.width,
frame_size.height); frame_size.height);

@ -210,7 +210,7 @@ server_start(struct server *server, const char *serial,
close_socket(&server->server_socket); close_socket(&server->server_socket);
} }
disable_tunnel(server); disable_tunnel(server);
SDL_free((void *) server->serial); SDL_free(server->serial);
return false; return false;
} }

@ -105,6 +105,10 @@ read_xpm(char *xpm[]) {
width, height, width, height,
32, 4 * width, 32, 4 * width,
rmask, gmask, bmask, amask); rmask, gmask, bmask, amask);
if (!surface) {
LOGE("Could not create icon surface");
return NULL;
}
// make the surface own the raw pixels // make the surface own the raw pixels
surface->flags &= ~SDL_PREALLOC; surface->flags &= ~SDL_PREALLOC;
return surface; return surface;

Loading…
Cancel
Save