diff --git a/app/src/cli.c b/app/src/cli.c index 5dda86e5..703b519b 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -56,6 +56,7 @@ #define OPT_OTG 1036 #define OPT_NO_CLEANUP 1037 #define OPT_PRINT_FPS 1038 +#define OPT_HOOK_SCRIPT 1039 struct sc_option { char shortopt; @@ -206,6 +207,18 @@ static const struct sc_option options[] = { .longopt = "help", .text = "Print this help.", }, + { + .longopt_id = OPT_HOOK_SCRIPT, + .longopt = "hook-script", + .argdesc = "path", + .text = "The path to a linux shell script which is run on your device " + "when a meaningful event happens.\n" + "The script is run with multiple parameters. The ones actually " + "used will depend on the event and intended functionality.\n" + "In this version, only the events ('START', 'STOP') have been " + "implemented. Others may be implemented in the future.\n" + "For details on the parameters, check the README manual", + }, { .longopt_id = OPT_LEGACY_PASTE, .longopt = "legacy-paste", @@ -1326,6 +1339,47 @@ sc_parse_shortcut_mods(const char *s, struct sc_shortcut_mods *mods) { } #endif + +static bool +parse_hook_script(const char *hook_script_path, char **hook_script) { + const int MAX_ACCEPTABLE_SIZE = 1048576; // 1MB + if(!hook_script_path) { + return false; + } + + FILE *script_file = fopen(hook_script_path, "rb"); + if(script_file == NULL){ + perror("Cannot open script file\n"); + return false; + } + fseek(script_file, 0, SEEK_END); + long ssize = ftell(script_file); + fseek(script_file, 0, SEEK_SET); + + if(ssize > MAX_ACCEPTABLE_SIZE){ + LOGE("Script file too large. " + "Only up to 1MB (%d bytes) is accepted\n", MAX_ACCEPTABLE_SIZE); + return false; + } + + + *hook_script = malloc(ssize + 1); + if(*hook_script == NULL){ + LOG_OOM(); + return false; + } + if(!fread(*hook_script, ssize, 1, script_file)){ + perror("Cannot read script file"); + return false; + } + fclose(script_file); + + (*hook_script)[ssize] = '\0'; + + + return true; +} + static bool parse_record_format(const char *optarg, enum sc_record_format *format) { if (!strcmp(optarg, "mp4")) { @@ -1574,6 +1628,11 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], case OPT_FORWARD_ALL_CLICKS: opts->forward_all_clicks = true; break; + case OPT_HOOK_SCRIPT: + if (!parse_hook_script(optarg, &opts->hook_script)) { + return false; + } + break; case OPT_LEGACY_PASTE: opts->legacy_paste = true; break; diff --git a/app/src/options.h b/app/src/options.h index f63e5c42..ca88d0d7 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -129,6 +129,7 @@ struct scrcpy_options { bool disable_screensaver; bool forward_key_repeat; bool forward_all_clicks; + char * hook_script; bool legacy_paste; bool power_off_on_close; bool clipboard_autosync; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 8fbfe394..73fd1892 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -318,6 +318,7 @@ scrcpy(struct scrcpy_options *options) { .codec_options = options->codec_options, .encoder_name = options->encoder_name, .force_adb_forward = options->force_adb_forward, + .hook_script = options->hook_script, .power_off_on_close = options->power_off_on_close, .clipboard_autosync = options->clipboard_autosync, .downsize_on_error = options->downsize_on_error,