From 50e86a0efa43fa72bd7d8c2dfc2d124052f74823 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 28 Oct 2017 15:32:08 -0400 Subject: [PATCH] Allow configuring output mode in rootston Fixes #336 --- include/rootston/config.h | 4 ++++ rootston/config.c | 16 ++++++++++++++++ rootston/output.c | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/include/rootston/config.h b/include/rootston/config.h index ecbdd88b..75c04619 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -9,6 +9,10 @@ struct output_config { enum wl_output_transform transform; int x, y; struct wl_list link; + struct { + int width, height; + float refresh_rate; + } mode; }; struct device_config { diff --git a/rootston/config.c b/rootston/config.c index 6f81170b..b3fd4f01 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -1,6 +1,7 @@ #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif +#include #include #include #include @@ -244,6 +245,21 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else { wlr_log(L_ERROR, "got unknown transform value: %s", value); } + } else if (strcmp(name, "mode") == 0) { + char *end; + oc->mode.width = strtol(value, &end, 10); + assert(*end == 'x'); + ++end; + oc->mode.height = strtol(end, &end, 10); + if (*end) { + assert(*end == '@'); + ++end; + oc->mode.refresh_rate = strtof(end, &end); + assert(strcmp("Hz", end) == 0); + } + wlr_log(L_DEBUG, "Configured output %s with mode %dx%d@%f", + oc->name, oc->mode.width, oc->mode.height, + oc->mode.refresh_rate); } } else if (strcmp(section, "cursor") == 0) { if (strcmp(name, "map-to-output") == 0) { diff --git a/rootston/output.c b/rootston/output.c index 5fcd02a2..6bc28996 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -165,6 +165,26 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { output->last_frame = desktop->last_frame = now; } +static void set_mode(struct wlr_output *output, struct output_config *oc) { + struct wlr_output_mode *mode, *best = NULL; + int mhz = (int)(oc->mode.refresh_rate * 1000); + wl_list_for_each(mode, &output->modes, link) { + if (mode->width == oc->mode.width && mode->height == oc->mode.height) { + if (mode->refresh == mhz) { + best = mode; + break; + } + best = mode; + } + } + if (!best) { + wlr_log(L_ERROR, "Configured mode for %s not available", output->name); + } else { + wlr_log(L_DEBUG, "Assigning configured mode to %s", output->name); + wlr_output_set_mode(output, best); + } +} + void output_add_notify(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = data; struct roots_desktop *desktop = wl_container_of(listener, desktop, output_add); @@ -191,6 +211,9 @@ void output_add_notify(struct wl_listener *listener, void *data) { struct output_config *output_config = config_get_output(config, wlr_output); if (output_config) { + if (output_config->mode.width) { + set_mode(wlr_output, output_config); + } wlr_output_transform(wlr_output, output_config->transform); wlr_output_layout_add(desktop->layout, wlr_output, output_config->x, output_config->y);