Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,14 +621,20 @@ static const struct sc_option options[] = {
{
.longopt_id = OPT_NEW_DISPLAY,
.longopt = "new-display",
.argdesc = "[<width>x<height>][/<dpi>]",
.argdesc = "[<width>x<height>][/<dpi>][:r[<factor>]]",
.optional_arg = true,
.text = "Create a new display with the specified resolution and "
"density. If not provided, they default to the main display "
"dimensions and DPI.\n"
"dimensions and DPI. Add ':r' to make the display resizable. "
"Optionally add a resolution factor after ':r' to scale the "
"display size (between 0.1 and 10.0).\n"
"Examples:\n"
" --new-display=1920x1080\n"
" --new-display=1920x1080/420 # force 420 dpi\n"
" --new-display=1920x1080/420:r # resizable display\n"
" --new-display=1920x1080/420:r2.0 # resizable with 2x factor\n"
" --new-display=:r0.5 # resizable with main display size and 0.5x factor\n"
" --new-display=/420:r1.5 # resizable with main display size, 420 dpi and 1.5x factor\n"
" --new-display # main display size and density\n"
" --new-display=/240 # main display size and 240 dpi",
},
Expand Down
7 changes: 7 additions & 0 deletions app/src/control_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ sc_control_msg_serialize(const struct sc_control_msg *msg, uint8_t *buf) {
size_t len = write_string_tiny(&buf[1], msg->start_app.name, 255);
return 1 + len;
}
case SC_CONTROL_MSG_TYPE_RESIZE_DISPLAY:
sc_write16be(&buf[1], msg->resize_display.width);
sc_write16be(&buf[3], msg->resize_display.height);
return 5;
case SC_CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL:
case SC_CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL:
case SC_CONTROL_MSG_TYPE_COLLAPSE_PANELS:
Expand Down Expand Up @@ -318,6 +322,9 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
case SC_CONTROL_MSG_TYPE_RESET_VIDEO:
LOG_CMSG("reset video");
break;
case SC_CONTROL_MSG_TYPE_RESIZE_DISPLAY:
LOG_CMSG("resize display to %dx%d", msg->resize_display.width, msg->resize_display.height);
break;
default:
LOG_CMSG("unknown type: %u", (unsigned) msg->type);
break;
Expand Down
5 changes: 5 additions & 0 deletions app/src/control_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum sc_control_msg_type {
SC_CONTROL_MSG_TYPE_OPEN_HARD_KEYBOARD_SETTINGS,
SC_CONTROL_MSG_TYPE_START_APP,
SC_CONTROL_MSG_TYPE_RESET_VIDEO,
SC_CONTROL_MSG_TYPE_RESIZE_DISPLAY,
};

enum sc_copy_key {
Expand Down Expand Up @@ -111,6 +112,10 @@ struct sc_control_msg {
struct {
char *name;
} start_app;
struct {
uint16_t width;
uint16_t height;
} resize_display;
};
};

Expand Down
5 changes: 5 additions & 0 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,11 @@ sc_input_manager_process_key(struct sc_input_manager *im,
if (shift) {
reset_video(im);
} else {
// Disable MOD+R rotation in resizable virtual display mode
if (im->screen->resizable_new_display) {
LOGI("MOD+R rotation disabled in resizable virtual display mode");
return;
}
rotate_device(im);
}
}
Expand Down
58 changes: 58 additions & 0 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,62 @@ scrcpy(struct scrcpy_options *options) {
const char *window_title =
options->window_title ? options->window_title : info->device_name;

// Check if new_display is resizable (contains :r)
bool resizable_new_display = false;
float resolution_factor = 1.0f;
bool auto_resolution_factor = false;

if (options->new_display) {
const char *r_pos = strstr(options->new_display, ":r");
if (r_pos) {
resizable_new_display = true;
// Check if there's a resolution factor after ":r"
const char *factor_start = r_pos + 2; // Skip ":r"
if (*factor_start && (*factor_start >= '0' && *factor_start <= '9')) {
// Parse the resolution factor
char *end;
resolution_factor = strtof(factor_start, &end);
if (resolution_factor <= 0.1f) {
// Prevent too small factors
resolution_factor = 0.1f;
} else if (resolution_factor > 10.0f) {
// Prevent too large factors
resolution_factor = 10.0f;
}
} else {
// No explicit resolution factor provided, will calculate automatically
auto_resolution_factor = true;
LOGI("No resolution factor specified, will calculate automatically");
}
}
}

// If automatic resolution factor calculation was requested, calculate it based on the main display size
if (auto_resolution_factor && resizable_new_display) {
// Get the main display size
SDL_Rect display_bounds;
if (SDL_GetDisplayUsableBounds(0, &display_bounds) == 0) {
// Calculate the resolution factor based on the ratio between the display size and the requested window size
int display_width = display_bounds.w;
int display_height = display_bounds.h;
int window_width = options->window_width ? options->window_width : display_width / 2;
int window_height = options->window_height ? options->window_height : display_height / 2;
float width_factor = (float)display_width / window_width;
float height_factor = (float)display_height / window_height;
resolution_factor = width_factor < height_factor ? width_factor : height_factor;
if (resolution_factor < 0.1f) {
resolution_factor = 0.1f;
} else if (resolution_factor > 10.0f) {
resolution_factor = 10.0f;
}
LOGI("Calculated automatic resolution factor: %.2f (display: %dx%d, window: %dx%d)",
resolution_factor, display_width, display_height, window_width, window_height);
} else {
LOGW("Could not get display bounds, using default resolution factor: 1.0");
resolution_factor = 1.0f;
}
}

struct sc_screen_params screen_params = {
.video = options->video_playback,
.controller = controller,
Expand All @@ -824,6 +880,8 @@ scrcpy(struct scrcpy_options *options) {
.mipmaps = options->mipmaps,
.fullscreen = options->fullscreen,
.start_fps_counter = options->start_fps_counter,
.resizable_new_display = resizable_new_display,
.resolution_factor = resolution_factor,
};

if (!sc_screen_init(&s->screen, &screen_params)) {
Expand Down
Loading