Add --list-displays

Add an option to list the device displays properly.
This commit is contained in:
Romain Vimont 2023-02-23 23:10:15 +01:00
parent 2596ca02f0
commit b65301f672
14 changed files with 69 additions and 28 deletions

View file

@ -718,7 +718,7 @@ scrcpy --display=1
The list of display ids can be retrieved by:
```bash
adb shell dumpsys display # search "mDisplayId=" in the output
scrcpy --list-displays
```
The secondary display may only be controlled if the device runs at least Android

View file

@ -19,6 +19,7 @@ _scrcpy() {
-K --hid-keyboard
-h --help
--legacy-paste
--list-displays
--list-encoders
--lock-video-orientation
--lock-video-orientation=

View file

@ -26,6 +26,7 @@ arguments=(
{-K,--hid-keyboard}'[Simulate a physical keyboard by using HID over AOAv2]'
{-h,--help}'[Print the help]'
'--legacy-paste[Inject computer clipboard text as a sequence of key events on Ctrl+v]'
'--list-displays[List displays available on the device]'
'--list-encoders[List video and audio encoders available on the device]'
'--lock-video-orientation=[Lock video orientation]:orientation:(unlocked initial 0 1 2 3)'
'--max-fps=[Limit the frame rate of screen capture]'

View file

@ -73,10 +73,9 @@ Disable screensaver while scrcpy is running.
.TP
.BI "\-\-display " id
Specify the display id to mirror.
Specify the device display id to mirror.
The list of possible display ids can be listed by "adb shell dumpsys display"
(search "mDisplayId=" in the output).
The available display ids can be listed by \-\-list\-displays.
Default is 0.
@ -134,6 +133,10 @@ This is a workaround for some devices not behaving as expected when setting the
.B \-\-list\-encoders
List video and audio encoders available on the device.
.TP
.B \-\-list\-displays
List displays available on the device.
.TP
\fB\-\-lock\-video\-orientation\fR[=\fIvalue\fR]
Lock video orientation to \fIvalue\fR. Possible values are "unlocked", "initial" (locked to the initial orientation), 0, 1, 2 and 3. Natural device orientation is 0, and each increment adds a 90 degrees rotation counterclockwise.

View file

@ -69,6 +69,7 @@ enum {
OPT_AUDIO_CODEC_OPTIONS,
OPT_AUDIO_ENCODER,
OPT_LIST_ENCODERS,
OPT_LIST_DISPLAYS,
};
struct sc_option {
@ -198,10 +199,9 @@ static const struct sc_option options[] = {
.longopt_id = OPT_DISPLAY_ID,
.longopt = "display",
.argdesc = "id",
.text = "Specify the display id to mirror.\n"
"The list of possible display ids can be listed by:\n"
" adb shell dumpsys display\n"
"(search \"mDisplayId=\" in the output)\n"
.text = "Specify the device display id to mirror.\n"
"The available display ids can be listed by:\n"
" scrcpy --list-displays\n"
"Default is 0.",
},
{
@ -272,6 +272,11 @@ static const struct sc_option options[] = {
"This is a workaround for some devices not behaving as "
"expected when setting the device clipboard programmatically.",
},
{
.longopt_id = OPT_LIST_DISPLAYS,
.longopt = "list-displays",
.text = "List device displays.",
},
{
.longopt_id = OPT_LIST_ENCODERS,
.longopt = "list-encoders",
@ -1803,6 +1808,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
case OPT_LIST_ENCODERS:
opts->list_encoders = true;
break;
case OPT_LIST_DISPLAYS:
opts->list_displays = true;
break;
default:
// getopt prints the error message on stderr
return false;

View file

@ -73,4 +73,5 @@ const struct scrcpy_options scrcpy_options_default = {
.power_on = true,
.audio = true,
.list_encoders = false,
.list_displays = false,
};

View file

@ -155,6 +155,7 @@ struct scrcpy_options {
bool power_on;
bool audio;
bool list_encoders;
bool list_displays;
};
extern const struct scrcpy_options scrcpy_options_default;

View file

@ -353,6 +353,7 @@ scrcpy(struct scrcpy_options *options) {
.cleanup = options->cleanup,
.power_on = options->power_on,
.list_encoders = options->list_encoders,
.list_displays = options->list_displays,
};
static const struct sc_server_callbacks cbs = {
@ -370,7 +371,7 @@ scrcpy(struct scrcpy_options *options) {
server_started = true;
if (options->list_encoders) {
if (options->list_encoders || options->list_displays) {
bool ok = await_for_server(NULL);
ret = ok ? SCRCPY_EXIT_SUCCESS : SCRCPY_EXIT_FAILURE;
goto end;

View file

@ -303,6 +303,9 @@ execute_server(struct sc_server *server,
if (params->list_encoders) {
ADD_PARAM("list_encoders=true");
}
if (params->list_displays) {
ADD_PARAM("list_displays=true");
}
#undef ADD_PARAM
@ -856,9 +859,9 @@ run_server(void *data) {
goto error_connection_failed;
}
// If --list-encoders is passed, then the server just prints the encoders
// If --list-* is passed, then the server just prints the requested data
// then exits.
if (params->list_encoders) {
if (params->list_encoders || params->list_displays) {
sc_pid pid = execute_server(server, params);
if (pid == SC_PROCESS_NONE) {
goto error_connection_failed;

View file

@ -56,6 +56,7 @@ struct sc_server_params {
bool cleanup;
bool power_on;
bool list_encoders;
bool list_displays;
};
struct sc_server {

View file

@ -65,7 +65,7 @@ public final class Device {
displayId = options.getDisplayId();
DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId);
if (displayInfo == null) {
Ln.e(buildUnknownDisplayIdMessage(displayId));
Ln.e("Display " + displayId + " not found\n" + LogUtils.buildDisplayListMessage());
throw new ConfigurationException("Unknown display id: " + displayId);
}
@ -130,18 +130,6 @@ public final class Device {
}
}
private static String buildUnknownDisplayIdMessage(int displayId) {
StringBuilder msg = new StringBuilder("Display ").append(displayId).append(" not found");
int[] displayIds = ServiceManager.getDisplayManager().getDisplayIds();
if (displayIds != null && displayIds.length > 0) {
msg.append("\nTry to use one of the available display ids:");
for (int id : displayIds) {
msg.append("\n scrcpy --display=").append(id);
}
}
return msg.toString();
}
public synchronized void setMaxSize(int newMaxSize) {
maxSize = newMaxSize;
screenInfo = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation);

View file

@ -1,5 +1,7 @@
package com.genymobile.scrcpy;
import com.genymobile.scrcpy.wrappers.ServiceManager;
import java.util.List;
public final class LogUtils {
@ -35,4 +37,17 @@ public final class LogUtils {
}
return builder.toString();
}
public static String buildDisplayListMessage() {
StringBuilder builder = new StringBuilder("List of displays:");
int[] displayIds = ServiceManager.getDisplayManager().getDisplayIds();
if (displayIds == null || displayIds.length == 0) {
builder.append("\n (none)");
} else {
for (int id : displayIds) {
builder.append("\n --display=").append(id);
}
}
return builder.toString();
}
}

View file

@ -34,6 +34,7 @@ public class Options {
private boolean powerOn = true;
private boolean listEncoders;
private boolean listDisplays;
// Options not used by the scrcpy client, but useful to use scrcpy-server directly
private boolean sendDeviceMeta = true; // send device name and size
@ -249,6 +250,14 @@ public class Options {
this.listEncoders = listEncoders;
}
public boolean getListDisplays() {
return listDisplays;
}
public void setListDisplays(boolean listDisplays) {
this.listDisplays = listDisplays;
}
public boolean getSendDeviceMeta() {
return sendDeviceMeta;
}

View file

@ -295,6 +295,10 @@ public final class Server {
boolean listEncoders = Boolean.parseBoolean(value);
options.setListEncoders(listEncoders);
break;
case "list_displays":
boolean listDisplays = Boolean.parseBoolean(value);
options.setListDisplays(listDisplays);
break;
case "send_device_meta":
boolean sendDeviceMeta = Boolean.parseBoolean(value);
options.setSendDeviceMeta(sendDeviceMeta);
@ -354,14 +358,19 @@ public final class Server {
Ln.initLogLevel(options.getLogLevel());
if (options.getListEncoders()) {
if (options.getListEncoders() || options.getListDisplays()) {
if (options.getCleanup()) {
CleanUp.unlinkSelf();
}
Ln.i(LogUtils.buildVideoEncoderListMessage());
Ln.i(LogUtils.buildAudioEncoderListMessage());
// Just print the available encoders, do not mirror
if (options.getListEncoders()) {
Ln.i(LogUtils.buildVideoEncoderListMessage());
Ln.i(LogUtils.buildAudioEncoderListMessage());
}
if (options.getListDisplays()) {
Ln.i(LogUtils.buildDisplayListMessage());
}
// Just print the requested data, do not mirror
return;
}