Skip to content

Commit

Permalink
Add --pause-on-exit
Browse files Browse the repository at this point in the history
Add an option to make scrcpy pause on exit.

Three behaviors are possible:
 - always pause on exit:
    --pause-on-exit
    --pause-on-exit=true
 - never pause on exit:
    (no option)
    --pause-on-exit=false
 - pause when scrcpy returns with an error (a non-zero exit code):
    --pause-on-exit=if-error

This is useful to prevent the terminal window from automatically
closing, so that error messages can be read.

Refs #3817 <#3817>
Refs #3822 <#3822>
PR #4130 <#4130>
  • Loading branch information
rom1v committed Oct 11, 2023
1 parent a7c3c9a commit 1650b7c
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 7 deletions.
6 changes: 6 additions & 0 deletions app/data/bash-completion/scrcpy
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ _scrcpy() {
--no-video-playback
--otg
-p --port=
--pause-on-exit
--pause-on-exit=
--power-off-on-close
--prefer-text
--print-fps
Expand Down Expand Up @@ -97,6 +99,10 @@ _scrcpy() {
COMPREPLY=($(compgen -W 'unlocked initial 0 1 2 3' -- "$cur"))
return
;;
--pause-on-exit)
COMPREPLY=($(compgen -W 'true false if-error' -- "$cur"))
return
;;
-r|--record)
COMPREPLY=($(compgen -f -- "$cur"))
return
Expand Down
1 change: 1 addition & 0 deletions app/data/zsh-completion/_scrcpy
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ arguments=(
'--no-video-playback[Disable video playback]'
'--otg[Run in OTG mode \(simulating physical keyboard and mouse\)]'
{-p,--port=}'[\[port\[\:port\]\] Set the TCP port \(range\) used by the client to listen]'
'--pause-on-exit=[Make scrcpy pause before exiting]:mode:(true false if-error)'
'--power-off-on-close[Turn the device screen off when closing scrcpy]'
'--prefer-text[Inject alpha characters and space as text events instead of key events]'
'--print-fps[Start FPS counter, to print frame logs to the console]'
Expand Down
10 changes: 10 additions & 0 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ Set the TCP port (range) used by the client to listen.

Default is 27183:27199.

.TP
\fB\-\-pause\-on\-exit\fR[=\fImode\fR]
Configure pause on exit. Possible values are "true" (always pause on exit), "false" (never pause on exit) and "if-error" (pause only if an error occured).

This is useful to prevent the terminal window from automatically closing, so that error messages can be read.

Default is "false".

Passing the option without argument is equivalent to passing "true".

.TP
.B \-\-power\-off\-on\-close
Turn the device screen off when closing scrcpy.
Expand Down
80 changes: 80 additions & 0 deletions app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ enum {
OPT_AUDIO_SOURCE,
OPT_KILL_ADB_ON_CLOSE,
OPT_TIME_LIMIT,
OPT_PAUSE_ON_EXIT,
};

struct sc_option {
Expand Down Expand Up @@ -463,6 +464,20 @@ static const struct sc_option options[] = {
"Default is " STR(DEFAULT_LOCAL_PORT_RANGE_FIRST) ":"
STR(DEFAULT_LOCAL_PORT_RANGE_LAST) ".",
},
{
.longopt_id = OPT_PAUSE_ON_EXIT,
.longopt = "pause-on-exit",
.argdesc = "mode",
.optional_arg = true,
.text = "Configure pause on exit. Possible values are \"true\" (always "
"pause on exit), \"false\" (never pause on exit) and "
"\"if-error\" (pause only if an error occured).\n"
"This is useful to prevent the terminal window from "
"automatically closing, so that error messages can be read.\n"
"Default is \"false\".\n"
"Passing the option without argument is equivalent to passing "
"\"true\".",
},
{
.longopt_id = OPT_POWER_OFF_ON_CLOSE,
.longopt = "power-off-on-close",
Expand Down Expand Up @@ -1637,6 +1652,29 @@ parse_time_limit(const char *s, sc_tick *tick) {
return true;
}

static bool
parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {
if (!s || !strcmp(s, "true")) {
*pause_on_exit = SC_PAUSE_ON_EXIT_TRUE;
return true;
}

if (!strcmp(s, "false")) {
*pause_on_exit = SC_PAUSE_ON_EXIT_FALSE;
return true;
}

if (!strcmp(s, "if-error")) {
*pause_on_exit = SC_PAUSE_ON_EXIT_IF_ERROR;
return true;
}

LOGE("Unsupported pause on exit mode: %s "
"(expected true, false or if-error)", optarg);
return false;

}

static bool
parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
const char *optstring, const struct option *longopts) {
Expand Down Expand Up @@ -1977,6 +2015,11 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false;
}
break;
case OPT_PAUSE_ON_EXIT:
if (!parse_pause_on_exit(optarg, &args->pause_on_exit)) {
return false;
}
break;
default:
// getopt prints the error message on stderr
return false;
Expand Down Expand Up @@ -2190,6 +2233,37 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return true;
}

static enum sc_pause_on_exit
sc_get_pause_on_exit(int argc, char *argv[]) {
// Read arguments backwards so that the last --pause-on-exit is considered
// (same behavior as getopt())
for (int i = argc - 1; i >= 1; --i) {
const char *arg = argv[i];
// Starts with "--pause-on-exit"
if (!strncmp("--pause-on-exit", arg, 15)) {
if (arg[15] == '\0') {
// No argument
return SC_PAUSE_ON_EXIT_TRUE;
}
if (arg[15] != '=') {
// Invalid parameter, ignore
return SC_PAUSE_ON_EXIT_FALSE;
}
const char *value = &arg[16];
if (!strcmp(value, "true")) {
return SC_PAUSE_ON_EXIT_TRUE;
}
if (!strcmp(value, "if-error")) {
return SC_PAUSE_ON_EXIT_IF_ERROR;
}
// Set to false, inclusing when the value is invalid
return SC_PAUSE_ON_EXIT_FALSE;
}
}

return false;
}

bool
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
struct sc_getopt_adapter adapter;
Expand All @@ -2203,5 +2277,11 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {

sc_getopt_adapter_destroy(&adapter);

if (!ret && args->pause_on_exit == SC_PAUSE_ON_EXIT_FALSE) {
// Check if "--pause-on-exit" is present in the arguments list, because
// it must be taken into account even if command line parsing failed
args->pause_on_exit = sc_get_pause_on_exit(argc, argv);
}

return ret;
}
7 changes: 7 additions & 0 deletions app/src/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@

#include "options.h"

enum sc_pause_on_exit {
SC_PAUSE_ON_EXIT_TRUE,
SC_PAUSE_ON_EXIT_FALSE,
SC_PAUSE_ON_EXIT_IF_ERROR,
};

struct scrcpy_cli_args {
struct scrcpy_options opts;
bool help;
bool version;
enum sc_pause_on_exit pause_on_exit;
};

void
Expand Down
28 changes: 21 additions & 7 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,32 @@ main_scrcpy(int argc, char *argv[]) {
.opts = scrcpy_options_default,
.help = false,
.version = false,
.pause_on_exit = SC_PAUSE_ON_EXIT_FALSE,
};

#ifndef NDEBUG
args.opts.log_level = SC_LOG_LEVEL_DEBUG;
#endif

enum scrcpy_exit_code ret;

if (!scrcpy_parse_args(&args, argc, argv)) {
return SCRCPY_EXIT_FAILURE;
ret = SCRCPY_EXIT_FAILURE;
goto end;
}

sc_set_log_level(args.opts.log_level);

if (args.help) {
scrcpy_print_usage(argv[0]);
return SCRCPY_EXIT_SUCCESS;
ret = SCRCPY_EXIT_SUCCESS;
goto end;
}

if (args.version) {
scrcpy_print_version();
return SCRCPY_EXIT_SUCCESS;
ret = SCRCPY_EXIT_SUCCESS;
goto end;
}

#ifdef SCRCPY_LAVF_REQUIRES_REGISTER_ALL
Expand All @@ -72,18 +78,26 @@ main_scrcpy(int argc, char *argv[]) {
#endif

if (!net_init()) {
return SCRCPY_EXIT_FAILURE;
ret = SCRCPY_EXIT_FAILURE;
goto end;
}

sc_log_configure();

#ifdef HAVE_USB
enum scrcpy_exit_code ret = args.opts.otg ? scrcpy_otg(&args.opts)
: scrcpy(&args.opts);
ret = args.opts.otg ? scrcpy_otg(&args.opts) : scrcpy(&args.opts);
#else
enum scrcpy_exit_code ret = scrcpy(&args.opts);
ret = scrcpy(&args.opts);
#endif

end:
if (args.pause_on_exit == SC_PAUSE_ON_EXIT_TRUE ||
(args.pause_on_exit == SC_PAUSE_ON_EXIT_IF_ERROR &&
ret != SCRCPY_EXIT_SUCCESS)) {
printf("Press Enter to continue...\n");
getchar();
}

return ret;
}

Expand Down

0 comments on commit 1650b7c

Please sign in to comment.