mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-02 22:29:25 +00:00
Merge f38dec516f
into 83082406d3
This commit is contained in:
commit
91cc10176b
8 changed files with 46 additions and 5 deletions
|
@ -26,6 +26,11 @@ scrcpy_print_usage(const char *arg0) {
|
||||||
" Unit suffixes are supported: 'K' (x1000) and 'M' (x1000000).\n"
|
" Unit suffixes are supported: 'K' (x1000) and 'M' (x1000000).\n"
|
||||||
" Default is %d.\n"
|
" Default is %d.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" --char-inject-fallback\n"
|
||||||
|
" Fallback to the clipboard (copy and paste) when non-supported\n"
|
||||||
|
" non-ASCII characters are typed.\n"
|
||||||
|
" Would override the device clipboard content when it happens.\n"
|
||||||
|
"\n"
|
||||||
" --codec-options key[:type]=value[,...]\n"
|
" --codec-options key[:type]=value[,...]\n"
|
||||||
" Set a list of comma-separated key:type=value options for the\n"
|
" Set a list of comma-separated key:type=value options for the\n"
|
||||||
" device encoder.\n"
|
" device encoder.\n"
|
||||||
|
@ -651,12 +656,15 @@ guess_record_format(const char *filename) {
|
||||||
#define OPT_DISABLE_SCREENSAVER 1020
|
#define OPT_DISABLE_SCREENSAVER 1020
|
||||||
#define OPT_SHORTCUT_MOD 1021
|
#define OPT_SHORTCUT_MOD 1021
|
||||||
#define OPT_NO_KEY_REPEAT 1022
|
#define OPT_NO_KEY_REPEAT 1022
|
||||||
|
#define OPT_CHAR_INJECT_FALLBACK 1023
|
||||||
|
|
||||||
bool
|
bool
|
||||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"always-on-top", no_argument, NULL, OPT_ALWAYS_ON_TOP},
|
{"always-on-top", no_argument, NULL, OPT_ALWAYS_ON_TOP},
|
||||||
{"bit-rate", required_argument, NULL, 'b'},
|
{"bit-rate", required_argument, NULL, 'b'},
|
||||||
|
{"char-inject-fallback", no_argument, NULL,
|
||||||
|
OPT_CHAR_INJECT_FALLBACK},
|
||||||
{"codec-options", required_argument, NULL, OPT_CODEC_OPTIONS},
|
{"codec-options", required_argument, NULL, OPT_CODEC_OPTIONS},
|
||||||
{"crop", required_argument, NULL, OPT_CROP},
|
{"crop", required_argument, NULL, OPT_CROP},
|
||||||
{"disable-screensaver", no_argument, NULL,
|
{"disable-screensaver", no_argument, NULL,
|
||||||
|
@ -719,6 +727,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
case OPT_CROP:
|
case OPT_CROP:
|
||||||
opts->crop = optarg;
|
opts->crop = optarg;
|
||||||
break;
|
break;
|
||||||
|
case OPT_CHAR_INJECT_FALLBACK:
|
||||||
|
opts->char_inject_fallback = true;
|
||||||
|
break;
|
||||||
case OPT_DISPLAY_ID:
|
case OPT_DISPLAY_ID:
|
||||||
if (!parse_display_id(optarg, &opts->display_id)) {
|
if (!parse_display_id(optarg, &opts->display_id)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -313,6 +313,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
.bit_rate = options->bit_rate,
|
.bit_rate = options->bit_rate,
|
||||||
.max_fps = options->max_fps,
|
.max_fps = options->max_fps,
|
||||||
.lock_video_orientation = options->lock_video_orientation,
|
.lock_video_orientation = options->lock_video_orientation,
|
||||||
|
.char_inject_fallback = options->char_inject_fallback,
|
||||||
.control = options->control,
|
.control = options->control,
|
||||||
.display_id = options->display_id,
|
.display_id = options->display_id,
|
||||||
.show_touches = options->show_touches,
|
.show_touches = options->show_touches,
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct scrcpy_options {
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool always_on_top;
|
bool always_on_top;
|
||||||
bool control;
|
bool control;
|
||||||
|
bool char_inject_fallback;
|
||||||
bool display;
|
bool display;
|
||||||
bool turn_screen_off;
|
bool turn_screen_off;
|
||||||
bool render_expired_frames;
|
bool render_expired_frames;
|
||||||
|
@ -112,6 +113,7 @@ struct scrcpy_options {
|
||||||
.show_touches = false, \
|
.show_touches = false, \
|
||||||
.fullscreen = false, \
|
.fullscreen = false, \
|
||||||
.always_on_top = false, \
|
.always_on_top = false, \
|
||||||
|
.char_inject_fallback = false, \
|
||||||
.control = true, \
|
.control = true, \
|
||||||
.display = true, \
|
.display = true, \
|
||||||
.turn_screen_off = false, \
|
.turn_screen_off = false, \
|
||||||
|
|
|
@ -294,6 +294,7 @@ execute_server(struct server *server, const struct server_params *params) {
|
||||||
params->show_touches ? "true" : "false",
|
params->show_touches ? "true" : "false",
|
||||||
params->stay_awake ? "true" : "false",
|
params->stay_awake ? "true" : "false",
|
||||||
params->codec_options ? params->codec_options : "-",
|
params->codec_options ? params->codec_options : "-",
|
||||||
|
params->char_inject_fallback ? "true" : "false",
|
||||||
};
|
};
|
||||||
#ifdef SERVER_DEBUGGER
|
#ifdef SERVER_DEBUGGER
|
||||||
LOGI("Server debugger waiting for a client on device port "
|
LOGI("Server debugger waiting for a client on device port "
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct server_params {
|
||||||
uint32_t bit_rate;
|
uint32_t bit_rate;
|
||||||
uint16_t max_fps;
|
uint16_t max_fps;
|
||||||
int8_t lock_video_orientation;
|
int8_t lock_video_orientation;
|
||||||
|
bool char_inject_fallback;
|
||||||
bool control;
|
bool control;
|
||||||
uint16_t display_id;
|
uint16_t display_id;
|
||||||
bool show_touches;
|
bool show_touches;
|
||||||
|
|
|
@ -21,6 +21,7 @@ public class Controller {
|
||||||
private final Device device;
|
private final Device device;
|
||||||
private final DesktopConnection connection;
|
private final DesktopConnection connection;
|
||||||
private final DeviceMessageSender sender;
|
private final DeviceMessageSender sender;
|
||||||
|
private final boolean charInjectFallback;
|
||||||
|
|
||||||
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||||
|
|
||||||
|
@ -31,9 +32,10 @@ public class Controller {
|
||||||
|
|
||||||
private boolean keepPowerModeOff;
|
private boolean keepPowerModeOff;
|
||||||
|
|
||||||
public Controller(Device device, DesktopConnection connection) {
|
public Controller(Device device, DesktopConnection connection, boolean charInjectFallback) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
this.charInjectFallback = charInjectFallback;
|
||||||
initPointers();
|
initPointers();
|
||||||
sender = new DeviceMessageSender(connection);
|
sender = new DeviceMessageSender(connection);
|
||||||
}
|
}
|
||||||
|
@ -163,8 +165,19 @@ public class Controller {
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
for (char c : text.toCharArray()) {
|
for (char c : text.toCharArray()) {
|
||||||
if (!injectChar(c)) {
|
if (!injectChar(c)) {
|
||||||
Ln.w("Could not inject char u+" + String.format("%04x", (int) c));
|
if (this.charInjectFallback) {
|
||||||
continue;
|
// Needs to handle the full remaining substring than only the failed character,
|
||||||
|
// since the events may happen too fast. E.g. if we are to do it per character,
|
||||||
|
// the expected input "ABCD" may lead to the actual value of "DDDD".
|
||||||
|
String remaining = text.substring(successCount);
|
||||||
|
setClipboard(remaining, true);
|
||||||
|
successCount = text.length();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Ln.w("Could not inject char u+" + String.format("%04x", (int) c));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
successCount++;
|
successCount++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ public class Options {
|
||||||
private boolean showTouches;
|
private boolean showTouches;
|
||||||
private boolean stayAwake;
|
private boolean stayAwake;
|
||||||
private String codecOptions;
|
private String codecOptions;
|
||||||
|
private boolean charInjectFallback;
|
||||||
|
|
||||||
public Ln.Level getLogLevel() {
|
public Ln.Level getLogLevel() {
|
||||||
return logLevel;
|
return logLevel;
|
||||||
|
@ -120,4 +121,12 @@ public class Options {
|
||||||
public void setCodecOptions(String codecOptions) {
|
public void setCodecOptions(String codecOptions) {
|
||||||
this.codecOptions = codecOptions;
|
this.codecOptions = codecOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getCharInjectFallback() {
|
||||||
|
return charInjectFallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharInjectFallback(boolean charInjectFallback) {
|
||||||
|
this.charInjectFallback = charInjectFallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public final class Server {
|
||||||
ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), codecOptions);
|
ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), codecOptions);
|
||||||
|
|
||||||
if (options.getControl()) {
|
if (options.getControl()) {
|
||||||
final Controller controller = new Controller(device, connection);
|
final Controller controller = new Controller(device, connection, options.getCharInjectFallback());
|
||||||
|
|
||||||
// asynchronous
|
// asynchronous
|
||||||
startController(controller);
|
startController(controller);
|
||||||
|
@ -120,7 +120,7 @@ public final class Server {
|
||||||
"The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
|
"The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
final int expectedParameters = 14;
|
final int expectedParameters = 15;
|
||||||
if (args.length != expectedParameters) {
|
if (args.length != expectedParameters) {
|
||||||
throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters");
|
throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters");
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,9 @@ public final class Server {
|
||||||
String codecOptions = args[13];
|
String codecOptions = args[13];
|
||||||
options.setCodecOptions(codecOptions);
|
options.setCodecOptions(codecOptions);
|
||||||
|
|
||||||
|
boolean charInjectFallback = Boolean.parseBoolean(args[14]);
|
||||||
|
options.setCharInjectFallback(charInjectFallback);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue