diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-07 08:58:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-07 08:58:17 -0700 |
commit | be54278207f5099b77a538e3043758aa59e5c998 (patch) | |
tree | 8e322b1c600afa6fd56a325d20e00d0ec054e85b /rootston | |
parent | 7c6588d7ae0b260aedc61da58eb6bf153b35ca94 (diff) | |
parent | 60a83e99f4dc930d7d4ed5999f49967a72b7df32 (diff) |
Merge pull request #1095 from agx/output-add-mode
Allow to add additional modes to outputs
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/config.c | 59 | ||||
-rw-r--r-- | rootston/output.c | 14 | ||||
-rw-r--r-- | rootston/rootston.ini.example | 7 |
3 files changed, 79 insertions, 1 deletions
diff --git a/rootston/config.c b/rootston/config.c index 9a4d77fd..7ef5e629 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -116,6 +116,51 @@ static uint32_t parse_modifier(const char *symname) { } } +static bool parse_modeline(const char *s, drmModeModeInfo *mode) { + char hsync[16]; + char vsync[16]; + float fclock; + + mode->type = DRM_MODE_TYPE_USERDEF; + + if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s", + &fclock, + &mode->hdisplay, + &mode->hsync_start, + &mode->hsync_end, + &mode->htotal, + &mode->vdisplay, + &mode->vsync_start, + &mode->vsync_end, + &mode->vtotal, hsync, vsync) != 11) { + return false; + } + + mode->clock = fclock * 1000; + mode->vrefresh = mode->clock * 1000.0 * 1000.0 + / mode->htotal / mode->vtotal; + if (strcasecmp(hsync, "+hsync") == 0) { + mode->flags |= DRM_MODE_FLAG_PHSYNC; + } else if (strcasecmp(hsync, "-hsync") == 0) { + mode->flags |= DRM_MODE_FLAG_NHSYNC; + } else { + return false; + } + + if (strcasecmp(vsync, "+vsync") == 0) { + mode->flags |= DRM_MODE_FLAG_PVSYNC; + } else if (strcasecmp(vsync, "-vsync") == 0) { + mode->flags |= DRM_MODE_FLAG_NVSYNC; + } else { + return false; + } + + snprintf(mode->name, sizeof(mode->name), "%dx%d@%d", + mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000); + + return true; +} + void add_binding_config(struct wl_list *bindings, const char* combination, const char* command) { struct roots_binding_config *bc = @@ -269,6 +314,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; oc->scale = 1; oc->enable = true; + wl_list_init(&oc->modes); wl_list_insert(&config->outputs, &oc->link); } @@ -322,6 +368,15 @@ static int config_ini_handler(void *user, const char *section, const char *name, 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(name, "modeline") == 0) { + struct roots_output_mode_config *mode = calloc(1, sizeof(*mode)); + + if (parse_modeline(value, &mode->info)) { + wl_list_insert(&oc->modes, &mode->link); + } else { + free(mode); + wlr_log(L_ERROR, "Invalid modeline: %s", value); + } } } else if (strncmp(cursor_prefix, section, strlen(cursor_prefix)) == 0) { const char *seat_name = section + strlen(cursor_prefix); @@ -459,6 +514,10 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { void roots_config_destroy(struct roots_config *config) { struct roots_output_config *oc, *otmp = NULL; wl_list_for_each_safe(oc, otmp, &config->outputs, link) { + struct roots_output_mode_config *omc, *omctmp = NULL; + wl_list_for_each_safe(omc, omctmp, &oc->modes, link) { + free(omc); + } free(oc->name); free(oc); } diff --git a/rootston/output.c b/rootston/output.c index fd7df99c..e3b03984 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -16,6 +16,7 @@ #include "rootston/layers.h" #include "rootston/output.h" #include "rootston/server.h" +#include "backend/drm/drm.h" /** * Rotate a child's position relative to a parent. The parent size is (pw, ph), @@ -821,7 +822,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { wlr_output->model, wlr_output->serial, wlr_output->phys_width, wlr_output->phys_height); - if (wl_list_length(&wlr_output->modes) > 0) { + if (!wl_list_empty(&wlr_output->modes)) { struct wlr_output_mode *mode = wl_container_of((&wlr_output->modes)->prev, mode, link); wlr_output_set_mode(wlr_output, mode); @@ -857,6 +858,17 @@ void handle_new_output(struct wl_listener *listener, void *data) { roots_config_get_output(config, wlr_output); if (output_config) { if (output_config->enable) { + struct roots_output_mode_config *mode_config; + + if (wlr_output_is_drm(wlr_output)) { + wl_list_for_each(mode_config, &output_config->modes, link) { + wlr_drm_connector_add_mode(wlr_output, &mode_config->info); + } + } else { + if (!wl_list_empty(&output_config->modes)) { + wlr_log(L_ERROR, "Can only add modes for DRM backend"); + } + } if (output_config->mode.width) { set_mode(wlr_output, output_config); } diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index 556cbefb..bb0efa44 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -19,6 +19,13 @@ y = 0 # and rotate by specified angle rotate = 90 +# Additional video mode to add +# Format is generated by cvt and is documented in x.org.conf(5) +modeline = 87.25 720 776 848 976 1440 1443 1453 1493 -hsync +vsync +modeline = 65.13 768 816 896 1024 1024 1025 1028 1060 -HSync +VSync +# Select one of the above modes +mode = 768x1024 + [cursor] # Restrict cursor movements to single output map-to-output = VGA-1 |