Change chvidemode(1) to set requested mode instead of running command.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-04-09 00:47:03 +02:00
parent adcf11944f
commit c77745e447
2 changed files with 53 additions and 26 deletions

View File

@ -20,19 +20,21 @@
.Op Fl \-height Ns "=" Ns Ar height
.Op Fl \-min-height Ns "=" Ns Ar min-height
.Op Fl \-max-height Ns "=" Ns Ar max-height
.Op Ar command ...
.Op Ar videomode
.Sh DESCRIPTION
.Nm
changes the video mode by displaying an interactive menu containing a list of
available modes, with an additional entry for entering a custom mode (if
supported by the driver).
If the mode change succeeds and
.Ar command
is specified,
.Ar command
is executed.
If the mode change fails, the menu is redisplayed until cancellation or a
successful mode change.
If the
.Ar videomode
argument is specified in the
.Ar width Ns x Ns Ar height Ns x Ns Ar bits-per-pixel
format per
.Xr videomode 5 ,
then the video mode is immediately set non-interactively.
.Pp
By default,
.Nm
@ -142,17 +144,9 @@ inclusive.
.Nm
exits with an exit status of 10 if the menu is quit, 11 if no modes are
available, 12 if no modes are available after filtering, 13 if the terminal has
no associated video devices, 127 if
.Ar command
failed to run, or 1 on any other error.
If
no associated video devices, or 1 on any other error.
.Nm
changes the video mode successfully,
.Nm
exits with the exit status of
.Ar command
if specified,
or 0 otherwise.
exits 0 if the video mode is successfully changed.
.Sh SEE ALSO
.Xr chkblayout 1 ,
.Xr dispmsg_issue 2 ,

View File

@ -299,6 +299,17 @@ int main(int argc, char* argv[])
compact_arguments(&argc, &argv);
unsigned int xres = 0;
unsigned int yres = 0;
unsigned int bpp = 0;
if ( 2 <= argc )
{
if ( 2 < argc )
error(1, 0, "Unexpected extra operand");
if ( sscanf(argv[1], "%ux%ux%u", &xres, &yres, &bpp) != 3 )
error(1, 0, "Invalid video mode: %s", argv[1]);
}
int tty_fd = open("/dev/tty", O_RDWR);
if ( tty_fd < 0 )
error(1, errno, "/dev/tty");
@ -349,6 +360,34 @@ retry_pick_mode:
decided = false;
first_render = true;
memset(&render_at, 0, sizeof(render_at));
if ( 2 <= argc )
{
bool found_other = true;
size_t other_selection = 0;
for ( size_t i = 0; i < num_modes; i++ )
{
if ( modes[i].view_xres == xres &&
modes[i].view_yres == yres &&
modes[i].fb_format == bpp )
{
selection = i;
decided = true;
break;
}
if ( modes[i].control & DISPMSG_CONTROL_OTHER_RESOLUTIONS )
{
found_other = true;
other_selection = i;
}
}
if ( !decided )
{
if ( found_other )
selection = other_selection;
else
error(1, 0, "No such available resolution: %s", argv[1]);
}
}
while ( !decided )
{
fflush(stdout);
@ -495,10 +534,10 @@ retry_pick_mode:
struct dispmsg_crtc_mode mode = modes[selection];
if ( mode.control & DISPMSG_CONTROL_OTHER_RESOLUTIONS )
{
uintmax_t req_bpp;
uintmax_t req_width;
uintmax_t req_height;
while ( true )
uintmax_t req_bpp = bpp;
uintmax_t req_width = xres;
uintmax_t req_height = yres;
while ( argc < 2 )
{
printf("Enter video mode [BPP x WIDTH x HEIGHT]: ");
fflush(stdout);
@ -527,11 +566,5 @@ retry_pick_mode:
goto retry_pick_mode;
}
if ( 1 < argc )
{
execvp(argv[1], argv + 1);
error(127, errno, "`%s'", argv[1]);
}
return 0;
}