Add --list-displays
Add an option to list the device displays properly.
This commit is contained in:
parent
2596ca02f0
commit
b65301f672
14 changed files with 69 additions and 28 deletions
|
@ -718,7 +718,7 @@ scrcpy --display=1
|
||||||
The list of display ids can be retrieved by:
|
The list of display ids can be retrieved by:
|
||||||
|
|
||||||
```bash
|
```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
|
The secondary display may only be controlled if the device runs at least Android
|
||||||
|
|
|
@ -19,6 +19,7 @@ _scrcpy() {
|
||||||
-K --hid-keyboard
|
-K --hid-keyboard
|
||||||
-h --help
|
-h --help
|
||||||
--legacy-paste
|
--legacy-paste
|
||||||
|
--list-displays
|
||||||
--list-encoders
|
--list-encoders
|
||||||
--lock-video-orientation
|
--lock-video-orientation
|
||||||
--lock-video-orientation=
|
--lock-video-orientation=
|
||||||
|
|
|
@ -26,6 +26,7 @@ arguments=(
|
||||||
{-K,--hid-keyboard}'[Simulate a physical keyboard by using HID over AOAv2]'
|
{-K,--hid-keyboard}'[Simulate a physical keyboard by using HID over AOAv2]'
|
||||||
{-h,--help}'[Print the help]'
|
{-h,--help}'[Print the help]'
|
||||||
'--legacy-paste[Inject computer clipboard text as a sequence of key events on Ctrl+v]'
|
'--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]'
|
'--list-encoders[List video and audio encoders available on the device]'
|
||||||
'--lock-video-orientation=[Lock video orientation]:orientation:(unlocked initial 0 1 2 3)'
|
'--lock-video-orientation=[Lock video orientation]:orientation:(unlocked initial 0 1 2 3)'
|
||||||
'--max-fps=[Limit the frame rate of screen capture]'
|
'--max-fps=[Limit the frame rate of screen capture]'
|
||||||
|
|
|
@ -73,10 +73,9 @@ Disable screensaver while scrcpy is running.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-display " id
|
.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"
|
The available display ids can be listed by \-\-list\-displays.
|
||||||
(search "mDisplayId=" in the output).
|
|
||||||
|
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
|
||||||
|
@ -134,6 +133,10 @@ This is a workaround for some devices not behaving as expected when setting the
|
||||||
.B \-\-list\-encoders
|
.B \-\-list\-encoders
|
||||||
List video and audio encoders available on the device.
|
List video and audio encoders available on the device.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-list\-displays
|
||||||
|
List displays available on the device.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-lock\-video\-orientation\fR[=\fIvalue\fR]
|
\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.
|
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.
|
||||||
|
|
|
@ -69,6 +69,7 @@ enum {
|
||||||
OPT_AUDIO_CODEC_OPTIONS,
|
OPT_AUDIO_CODEC_OPTIONS,
|
||||||
OPT_AUDIO_ENCODER,
|
OPT_AUDIO_ENCODER,
|
||||||
OPT_LIST_ENCODERS,
|
OPT_LIST_ENCODERS,
|
||||||
|
OPT_LIST_DISPLAYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
|
@ -198,10 +199,9 @@ static const struct sc_option options[] = {
|
||||||
.longopt_id = OPT_DISPLAY_ID,
|
.longopt_id = OPT_DISPLAY_ID,
|
||||||
.longopt = "display",
|
.longopt = "display",
|
||||||
.argdesc = "id",
|
.argdesc = "id",
|
||||||
.text = "Specify the display id to mirror.\n"
|
.text = "Specify the device display id to mirror.\n"
|
||||||
"The list of possible display ids can be listed by:\n"
|
"The available display ids can be listed by:\n"
|
||||||
" adb shell dumpsys display\n"
|
" scrcpy --list-displays\n"
|
||||||
"(search \"mDisplayId=\" in the output)\n"
|
|
||||||
"Default is 0.",
|
"Default is 0.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -272,6 +272,11 @@ static const struct sc_option options[] = {
|
||||||
"This is a workaround for some devices not behaving as "
|
"This is a workaround for some devices not behaving as "
|
||||||
"expected when setting the device clipboard programmatically.",
|
"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_id = OPT_LIST_ENCODERS,
|
||||||
.longopt = "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:
|
case OPT_LIST_ENCODERS:
|
||||||
opts->list_encoders = true;
|
opts->list_encoders = true;
|
||||||
break;
|
break;
|
||||||
|
case OPT_LIST_DISPLAYS:
|
||||||
|
opts->list_displays = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -73,4 +73,5 @@ const struct scrcpy_options scrcpy_options_default = {
|
||||||
.power_on = true,
|
.power_on = true,
|
||||||
.audio = true,
|
.audio = true,
|
||||||
.list_encoders = false,
|
.list_encoders = false,
|
||||||
|
.list_displays = false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -155,6 +155,7 @@ struct scrcpy_options {
|
||||||
bool power_on;
|
bool power_on;
|
||||||
bool audio;
|
bool audio;
|
||||||
bool list_encoders;
|
bool list_encoders;
|
||||||
|
bool list_displays;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct scrcpy_options scrcpy_options_default;
|
extern const struct scrcpy_options scrcpy_options_default;
|
||||||
|
|
|
@ -353,6 +353,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
.cleanup = options->cleanup,
|
.cleanup = options->cleanup,
|
||||||
.power_on = options->power_on,
|
.power_on = options->power_on,
|
||||||
.list_encoders = options->list_encoders,
|
.list_encoders = options->list_encoders,
|
||||||
|
.list_displays = options->list_displays,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sc_server_callbacks cbs = {
|
static const struct sc_server_callbacks cbs = {
|
||||||
|
@ -370,7 +371,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
|
|
||||||
server_started = true;
|
server_started = true;
|
||||||
|
|
||||||
if (options->list_encoders) {
|
if (options->list_encoders || options->list_displays) {
|
||||||
bool ok = await_for_server(NULL);
|
bool ok = await_for_server(NULL);
|
||||||
ret = ok ? SCRCPY_EXIT_SUCCESS : SCRCPY_EXIT_FAILURE;
|
ret = ok ? SCRCPY_EXIT_SUCCESS : SCRCPY_EXIT_FAILURE;
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -303,6 +303,9 @@ execute_server(struct sc_server *server,
|
||||||
if (params->list_encoders) {
|
if (params->list_encoders) {
|
||||||
ADD_PARAM("list_encoders=true");
|
ADD_PARAM("list_encoders=true");
|
||||||
}
|
}
|
||||||
|
if (params->list_displays) {
|
||||||
|
ADD_PARAM("list_displays=true");
|
||||||
|
}
|
||||||
|
|
||||||
#undef ADD_PARAM
|
#undef ADD_PARAM
|
||||||
|
|
||||||
|
@ -856,9 +859,9 @@ run_server(void *data) {
|
||||||
goto error_connection_failed;
|
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.
|
// then exits.
|
||||||
if (params->list_encoders) {
|
if (params->list_encoders || params->list_displays) {
|
||||||
sc_pid pid = execute_server(server, params);
|
sc_pid pid = execute_server(server, params);
|
||||||
if (pid == SC_PROCESS_NONE) {
|
if (pid == SC_PROCESS_NONE) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct sc_server_params {
|
||||||
bool cleanup;
|
bool cleanup;
|
||||||
bool power_on;
|
bool power_on;
|
||||||
bool list_encoders;
|
bool list_encoders;
|
||||||
|
bool list_displays;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_server {
|
struct sc_server {
|
||||||
|
|
|
@ -65,7 +65,7 @@ public final class Device {
|
||||||
displayId = options.getDisplayId();
|
displayId = options.getDisplayId();
|
||||||
DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId);
|
DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId);
|
||||||
if (displayInfo == null) {
|
if (displayInfo == null) {
|
||||||
Ln.e(buildUnknownDisplayIdMessage(displayId));
|
Ln.e("Display " + displayId + " not found\n" + LogUtils.buildDisplayListMessage());
|
||||||
throw new ConfigurationException("Unknown display id: " + displayId);
|
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) {
|
public synchronized void setMaxSize(int newMaxSize) {
|
||||||
maxSize = newMaxSize;
|
maxSize = newMaxSize;
|
||||||
screenInfo = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation);
|
screenInfo = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.genymobile.scrcpy;
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class LogUtils {
|
public final class LogUtils {
|
||||||
|
@ -35,4 +37,17 @@ public final class LogUtils {
|
||||||
}
|
}
|
||||||
return builder.toString();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class Options {
|
||||||
private boolean powerOn = true;
|
private boolean powerOn = true;
|
||||||
|
|
||||||
private boolean listEncoders;
|
private boolean listEncoders;
|
||||||
|
private boolean listDisplays;
|
||||||
|
|
||||||
// Options not used by the scrcpy client, but useful to use scrcpy-server directly
|
// Options not used by the scrcpy client, but useful to use scrcpy-server directly
|
||||||
private boolean sendDeviceMeta = true; // send device name and size
|
private boolean sendDeviceMeta = true; // send device name and size
|
||||||
|
@ -249,6 +250,14 @@ public class Options {
|
||||||
this.listEncoders = listEncoders;
|
this.listEncoders = listEncoders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getListDisplays() {
|
||||||
|
return listDisplays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListDisplays(boolean listDisplays) {
|
||||||
|
this.listDisplays = listDisplays;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getSendDeviceMeta() {
|
public boolean getSendDeviceMeta() {
|
||||||
return sendDeviceMeta;
|
return sendDeviceMeta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,6 +295,10 @@ public final class Server {
|
||||||
boolean listEncoders = Boolean.parseBoolean(value);
|
boolean listEncoders = Boolean.parseBoolean(value);
|
||||||
options.setListEncoders(listEncoders);
|
options.setListEncoders(listEncoders);
|
||||||
break;
|
break;
|
||||||
|
case "list_displays":
|
||||||
|
boolean listDisplays = Boolean.parseBoolean(value);
|
||||||
|
options.setListDisplays(listDisplays);
|
||||||
|
break;
|
||||||
case "send_device_meta":
|
case "send_device_meta":
|
||||||
boolean sendDeviceMeta = Boolean.parseBoolean(value);
|
boolean sendDeviceMeta = Boolean.parseBoolean(value);
|
||||||
options.setSendDeviceMeta(sendDeviceMeta);
|
options.setSendDeviceMeta(sendDeviceMeta);
|
||||||
|
@ -354,14 +358,19 @@ public final class Server {
|
||||||
|
|
||||||
Ln.initLogLevel(options.getLogLevel());
|
Ln.initLogLevel(options.getLogLevel());
|
||||||
|
|
||||||
if (options.getListEncoders()) {
|
if (options.getListEncoders() || options.getListDisplays()) {
|
||||||
if (options.getCleanup()) {
|
if (options.getCleanup()) {
|
||||||
CleanUp.unlinkSelf();
|
CleanUp.unlinkSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.getListEncoders()) {
|
||||||
Ln.i(LogUtils.buildVideoEncoderListMessage());
|
Ln.i(LogUtils.buildVideoEncoderListMessage());
|
||||||
Ln.i(LogUtils.buildAudioEncoderListMessage());
|
Ln.i(LogUtils.buildAudioEncoderListMessage());
|
||||||
// Just print the available encoders, do not mirror
|
}
|
||||||
|
if (options.getListDisplays()) {
|
||||||
|
Ln.i(LogUtils.buildDisplayListMessage());
|
||||||
|
}
|
||||||
|
// Just print the requested data, do not mirror
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue