diff --git a/app/scrcpy.1 b/app/scrcpy.1 index fb39189b..bde58d65 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -125,6 +125,17 @@ Set the initial window vertical position. Default is -1 (automatic).\n +.TP +.BI \-\-window\-width " value +Set the initial window width. + +Default is 0 (automatic).\n + +.TP +.BI \-\-window\-height " value +Set the initial window height. + +Default is 0 (automatic).\n .SH SHORTCUTS diff --git a/app/src/main.c b/app/src/main.c index 348c3df0..0046a12d 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -118,6 +118,14 @@ static void usage(const char *arg0) { " Set the initial window vertical position.\n" " Default is -1 (automatic).\n" "\n" + " --window-width value\n" + " Set the initial window width.\n" + " Default is -1 (automatic).\n" + "\n" + " --window-height value\n" + " Set the initial window width.\n" + " Default is -1 (automatic).\n" + "\n" "Shortcuts:\n" "\n" " " CTRL_OR_CMD "+f\n" @@ -279,6 +287,27 @@ parse_window_position(char *optarg, int16_t *position) { return true; } +static bool +parse_window_dimension(char *optarg, uint16_t *dimension) { + char *endptr; + if (*optarg == '\0') { + LOGE("Window dimension parameter is empty"); + return false; + } + long value = strtol(optarg, &endptr, 0); + if (*endptr != '\0') { + LOGE("Invalid window dimension: %s", optarg); + return false; + } + if (value & ~0xffff) { + LOGE("Window position must be between 0 and 65535: %ld", value); + return false; + } + + *dimension = (uint16_t) value; + return true; +} + static bool parse_port(char *optarg, uint16_t *port) { char *endptr; @@ -339,6 +368,8 @@ guess_record_format(const char *filename) { #define OPT_PREFER_TEXT 1006 #define OPT_WINDOW_X 1007 #define OPT_WINDOW_Y 1008 +#define OPT_WINDOW_WIDTH 1009 +#define OPT_WINDOW_HEIGHT 1010 static bool parse_args(struct args *args, int argc, char *argv[]) { @@ -365,6 +396,8 @@ parse_args(struct args *args, int argc, char *argv[]) { {"window-title", required_argument, NULL, OPT_WINDOW_TITLE}, {"window-x", required_argument, NULL, OPT_WINDOW_X}, {"window-y", required_argument, NULL, OPT_WINDOW_Y}, + {"window-width", required_argument, NULL, OPT_WINDOW_WIDTH}, + {"window-height", required_argument, NULL, OPT_WINDOW_HEIGHT}, {NULL, 0, NULL, 0 }, }; @@ -452,6 +485,16 @@ parse_args(struct args *args, int argc, char *argv[]) { return false; } break; + case OPT_WINDOW_WIDTH: + if (!parse_window_dimension(optarg, &opts->window_width)) { + return false; + } + break; + case OPT_WINDOW_HEIGHT: + if (!parse_window_dimension(optarg, &opts->window_height)) { + return false; + } + break; case OPT_PUSH_TARGET: opts->push_target = optarg; break; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index d9f0e308..5213d779 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -388,7 +388,8 @@ scrcpy(const struct scrcpy_options *options) { if (!screen_init_rendering(&screen, window_title, frame_size, options->always_on_top, options->window_x, - options->window_y)) { + options->window_y, options->window_width, + options->window_height)) { goto end; } diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index d0ef2392..d0612172 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -20,6 +20,8 @@ struct scrcpy_options { uint32_t bit_rate; int16_t window_x; int16_t window_y; + uint16_t window_width; + uint16_t window_height; bool show_touches; bool fullscreen; bool always_on_top; @@ -42,6 +44,8 @@ struct scrcpy_options { .bit_rate = DEFAULT_BIT_RATE, \ .window_x = -1, \ .window_y = -1, \ + .window_width = 0, \ + .window_height = 0, \ .show_touches = false, \ .fullscreen = false, \ .always_on_top = false, \ diff --git a/app/src/screen.c b/app/src/screen.c index 4543fab3..3d021e01 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -122,9 +122,30 @@ get_optimal_window_size(const struct screen *screen, struct size frame_size) { } // initially, there is no current size, so use the frame size as current size +// req_width and req_height, if not 0, are the sizes requested by the user static inline struct size -get_initial_optimal_size(struct size frame_size) { - return get_optimal_size(frame_size, frame_size); +get_initial_optimal_size(struct size frame_size, uint16_t req_width, + uint16_t req_height) { + struct size window_size; + if (!req_width && !req_height) { + window_size = get_optimal_size(frame_size, frame_size); + } else { + if (req_width) { + window_size.width = req_width; + } else { + // compute from the requested height + window_size.width = (uint32_t) req_height * frame_size.width + / frame_size.height; + } + if (req_height) { + window_size.height = req_height; + } else { + // compute from the requested width + window_size.height = (uint32_t) req_width * frame_size.height + / frame_size.width; + } + } + return window_size; } void @@ -142,10 +163,12 @@ create_texture(SDL_Renderer *renderer, struct size frame_size) { bool screen_init_rendering(struct screen *screen, const char *window_title, struct size frame_size, bool always_on_top, - int16_t window_x, int16_t window_y) { + int16_t window_x, int16_t window_y, uint16_t window_width, + uint16_t window_height) { screen->frame_size = frame_size; - struct size window_size = get_initial_optimal_size(frame_size); + struct size window_size = + get_initial_optimal_size(frame_size, window_width, window_height); uint32_t window_flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE; #ifdef HIDPI_SUPPORT window_flags |= SDL_WINDOW_ALLOW_HIGHDPI; diff --git a/app/src/screen.h b/app/src/screen.h index 204e3226..eaa46850 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -56,7 +56,8 @@ screen_init(struct screen *screen); bool screen_init_rendering(struct screen *screen, const char *window_title, struct size frame_size, bool always_on_top, - int16_t window_x, int16_t window_y); + int16_t window_x, int16_t window_y, uint16_t window_width, + uint16_t window_height); // show the window void