mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-03 14:49:29 +00:00
add display id param
This commit is contained in:
parent
a0af402d96
commit
ee810f653b
11 changed files with 52 additions and 7 deletions
|
@ -354,6 +354,18 @@ parse_port_range(const char *s, struct port_range *port_range) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_display_id(const char *s, uint16_t *display_id) {
|
||||||
|
long value;
|
||||||
|
bool ok = parse_integer_arg(s, &value, false, 0, 0xFFFF, "display id");
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*display_id = (uint16_t) value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_record_format(const char *optarg, enum recorder_format *format) {
|
parse_record_format(const char *optarg, enum recorder_format *format) {
|
||||||
if (!strcmp(optarg, "mp4")) {
|
if (!strcmp(optarg, "mp4")) {
|
||||||
|
@ -439,7 +451,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
optind = 0; // reset to start from the first argument in tests
|
optind = 0; // reset to start from the first argument in tests
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTv", long_options,
|
while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNpd:r:s:StTv", long_options,
|
||||||
NULL)) != -1) {
|
NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
|
@ -493,6 +505,11 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (!parse_display_id(optarg, &opts->display_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
opts->record_filename = optarg;
|
opts->record_filename = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -286,6 +286,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
.max_fps = options->max_fps,
|
.max_fps = options->max_fps,
|
||||||
.lock_video_orientation = options->lock_video_orientation,
|
.lock_video_orientation = options->lock_video_orientation,
|
||||||
.control = options->control,
|
.control = options->control,
|
||||||
|
.display_id = options->display_id,
|
||||||
};
|
};
|
||||||
if (!server_start(&server, options->serial, ¶ms)) {
|
if (!server_start(&server, options->serial, ¶ms)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct scrcpy_options {
|
||||||
int16_t window_y;
|
int16_t window_y;
|
||||||
uint16_t window_width;
|
uint16_t window_width;
|
||||||
uint16_t window_height;
|
uint16_t window_height;
|
||||||
|
uint16_t display_id;
|
||||||
bool show_touches;
|
bool show_touches;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool always_on_top;
|
bool always_on_top;
|
||||||
|
@ -55,6 +56,7 @@ struct scrcpy_options {
|
||||||
.window_y = -1, \
|
.window_y = -1, \
|
||||||
.window_width = 0, \
|
.window_width = 0, \
|
||||||
.window_height = 0, \
|
.window_height = 0, \
|
||||||
|
.display_id = 0, \
|
||||||
.show_touches = false, \
|
.show_touches = false, \
|
||||||
.fullscreen = false, \
|
.fullscreen = false, \
|
||||||
.always_on_top = false, \
|
.always_on_top = false, \
|
||||||
|
|
|
@ -234,10 +234,12 @@ execute_server(struct server *server, const struct server_params *params) {
|
||||||
char bit_rate_string[11];
|
char bit_rate_string[11];
|
||||||
char max_fps_string[6];
|
char max_fps_string[6];
|
||||||
char lock_video_orientation_string[3];
|
char lock_video_orientation_string[3];
|
||||||
|
char display_id_string[6];
|
||||||
sprintf(max_size_string, "%"PRIu16, params->max_size);
|
sprintf(max_size_string, "%"PRIu16, params->max_size);
|
||||||
sprintf(bit_rate_string, "%"PRIu32, params->bit_rate);
|
sprintf(bit_rate_string, "%"PRIu32, params->bit_rate);
|
||||||
sprintf(max_fps_string, "%"PRIu16, params->max_fps);
|
sprintf(max_fps_string, "%"PRIu16, params->max_fps);
|
||||||
sprintf(lock_video_orientation_string, "%"PRIi8, params->lock_video_orientation);
|
sprintf(lock_video_orientation_string, "%"PRIi8, params->lock_video_orientation);
|
||||||
|
sprintf(display_id_string, "%"PRIu16, params->display_id);
|
||||||
const char *const cmd[] = {
|
const char *const cmd[] = {
|
||||||
"shell",
|
"shell",
|
||||||
"CLASSPATH=" DEVICE_SERVER_PATH,
|
"CLASSPATH=" DEVICE_SERVER_PATH,
|
||||||
|
@ -264,6 +266,7 @@ execute_server(struct server *server, const struct server_params *params) {
|
||||||
params->crop ? params->crop : "-",
|
params->crop ? params->crop : "-",
|
||||||
"true", // always send frame meta (packet boundaries + timestamp)
|
"true", // always send frame meta (packet boundaries + timestamp)
|
||||||
params->control ? "true" : "false",
|
params->control ? "true" : "false",
|
||||||
|
display_id_string,
|
||||||
};
|
};
|
||||||
#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 "
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct server_params {
|
||||||
uint16_t max_fps;
|
uint16_t max_fps;
|
||||||
int8_t lock_video_orientation;
|
int8_t lock_video_orientation;
|
||||||
bool control;
|
bool control;
|
||||||
|
uint16_t display_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
// init default values
|
// init default values
|
||||||
|
|
|
@ -3,10 +3,12 @@ package com.genymobile.scrcpy;
|
||||||
public final class DisplayInfo {
|
public final class DisplayInfo {
|
||||||
private final Size size;
|
private final Size size;
|
||||||
private final int rotation;
|
private final int rotation;
|
||||||
|
private final int layerStack;
|
||||||
|
|
||||||
public DisplayInfo(Size size, int rotation) {
|
public DisplayInfo(Size size, int rotation, int layerStack) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
|
this.layerStack = layerStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Size getSize() {
|
public Size getSize() {
|
||||||
|
@ -16,5 +18,9 @@ public final class DisplayInfo {
|
||||||
public int getRotation() {
|
public int getRotation() {
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLayerStack() {
|
||||||
|
return layerStack;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ public class Options {
|
||||||
private Rect crop;
|
private Rect crop;
|
||||||
private boolean sendFrameMeta; // send PTS so that the client may record properly
|
private boolean sendFrameMeta; // send PTS so that the client may record properly
|
||||||
private boolean control;
|
private boolean control;
|
||||||
|
private int displayId;
|
||||||
|
|
||||||
public int getMaxSize() {
|
public int getMaxSize() {
|
||||||
return maxSize;
|
return maxSize;
|
||||||
|
@ -75,4 +76,12 @@ public class Options {
|
||||||
public void setControl(boolean control) {
|
public void setControl(boolean control) {
|
||||||
this.control = control;
|
this.control = control;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getDisplayId() {
|
||||||
|
return displayId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayId(int displayId) {
|
||||||
|
this.displayId = displayId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,12 +178,12 @@ public class ScreenEncoder implements Device.RotationListener {
|
||||||
format.setInteger(MediaFormat.KEY_HEIGHT, height);
|
format.setInteger(MediaFormat.KEY_HEIGHT, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setDisplaySurface(IBinder display, Surface surface, int orientation, Rect deviceRect, Rect displayRect) {
|
private static void setDisplaySurface(IBinder display, Surface surface, int orientation, Rect deviceRect, Rect displayRect, int layerStack) {
|
||||||
SurfaceControl.openTransaction();
|
SurfaceControl.openTransaction();
|
||||||
try {
|
try {
|
||||||
SurfaceControl.setDisplaySurface(display, surface);
|
SurfaceControl.setDisplaySurface(display, surface);
|
||||||
SurfaceControl.setDisplayProjection(display, orientation, deviceRect, displayRect);
|
SurfaceControl.setDisplayProjection(display, orientation, deviceRect, displayRect);
|
||||||
SurfaceControl.setDisplayLayerStack(display, 0);
|
SurfaceControl.setDisplayLayerStack(display, layerStack);
|
||||||
} finally {
|
} finally {
|
||||||
SurfaceControl.closeTransaction();
|
SurfaceControl.closeTransaction();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public final class ScreenInfo {
|
||||||
* However, it does not include the locked video orientation.
|
* However, it does not include the locked video orientation.
|
||||||
*/
|
*/
|
||||||
private final Size unlockedVideoSize;
|
private final Size unlockedVideoSize;
|
||||||
|
private final int layerStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device rotation, related to the natural device orientation (0, 1, 2 or 3)
|
* Device rotation, related to the natural device orientation (0, 1, 2 or 3)
|
||||||
|
@ -30,6 +31,7 @@ public final class ScreenInfo {
|
||||||
this.unlockedVideoSize = unlockedVideoSize;
|
this.unlockedVideoSize = unlockedVideoSize;
|
||||||
this.deviceRotation = deviceRotation;
|
this.deviceRotation = deviceRotation;
|
||||||
this.lockedVideoOrientation = lockedVideoOrientation;
|
this.lockedVideoOrientation = lockedVideoOrientation;
|
||||||
|
this.layerStack = layerStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rect getContentRect() {
|
public Rect getContentRect() {
|
||||||
|
|
|
@ -111,6 +111,9 @@ public final class Server {
|
||||||
boolean control = Boolean.parseBoolean(args[8]);
|
boolean control = Boolean.parseBoolean(args[8]);
|
||||||
options.setControl(control);
|
options.setControl(control);
|
||||||
|
|
||||||
|
int displayId = Integer.parseInt(args[8]);
|
||||||
|
options.setDisplayId(displayId);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,16 @@ public final class DisplayManager {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayInfo getDisplayInfo() {
|
public DisplayInfo getDisplayInfo(int displayId) {
|
||||||
try {
|
try {
|
||||||
Object displayInfo = manager.getClass().getMethod("getDisplayInfo", int.class).invoke(manager, 0);
|
Object displayInfo = manager.getClass().getMethod("getDisplayInfo", int.class).invoke(manager, displayId);
|
||||||
Class<?> cls = displayInfo.getClass();
|
Class<?> cls = displayInfo.getClass();
|
||||||
// width and height already take the rotation into account
|
// width and height already take the rotation into account
|
||||||
int width = cls.getDeclaredField("logicalWidth").getInt(displayInfo);
|
int width = cls.getDeclaredField("logicalWidth").getInt(displayInfo);
|
||||||
int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
|
int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
|
||||||
int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
|
int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
|
||||||
return new DisplayInfo(new Size(width, height), rotation);
|
int layerStack = cls.getDeclaredField("layerStack").getInt(displayInfo);
|
||||||
|
return new DisplayInfo(new Size(width, height), rotation, layerStack);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue