aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-10-28 15:32:08 -0400
committerDrew DeVault <sir@cmpwn.com>2017-10-28 15:32:08 -0400
commit50e86a0efa43fa72bd7d8c2dfc2d124052f74823 (patch)
tree8453bac10381a680ae1d12ca84f9dee11d1fa72f
parentfa9c6ecc53355a53d442036b0a6e98588d2abed7 (diff)
Allow configuring output mode in rootston
Fixes #336
-rw-r--r--include/rootston/config.h4
-rw-r--r--rootston/config.c16
-rw-r--r--rootston/output.c23
3 files changed, 43 insertions, 0 deletions
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 <assert.h>
#include <stdlib.h>
#include <limits.h>
#include <getopt.h>
@@ -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);