From 8f37e0bc1ec545c8d0837607a783c86aaed97f6a Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Tue, 31 Jul 2012 15:30:41 -0600 Subject: [PATCH] Add raw modeline support. This allows specifying a modeline in the config for the 'mode' key in the output section, such as one you would get from cvt. --- src/compositor-drm.c | 77 ++++++++++++++++++++++++++++++++++++++++++-- weston.ini | 4 +-- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 24e454c8..2075a993 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -53,13 +53,15 @@ enum output_config { OUTPUT_CONFIG_OFF, OUTPUT_CONFIG_PREFERRED, OUTPUT_CONFIG_CURRENT, - OUTPUT_CONFIG_MODE + OUTPUT_CONFIG_MODE, + OUTPUT_CONFIG_MODELINE }; struct drm_configured_output { char *name; char *mode; int32_t width, height; + drmModeModeInfo crtc_mode; enum output_config config; struct wl_list link; }; @@ -1397,7 +1399,8 @@ create_output_for_connector(struct drm_compositor *ec, wl_list_for_each(drm_mode, &output->base.mode_list, base.link) { if (o && o->width == drm_mode->base.width && - o->height == drm_mode->base.height) + o->height == drm_mode->base.height && + o->config == OUTPUT_CONFIG_MODE) configured = &drm_mode->base; if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode)) current = &drm_mode->base; @@ -1405,6 +1408,15 @@ create_output_for_connector(struct drm_compositor *ec, preferred = &drm_mode->base; } + if (o && o->config == OUTPUT_CONFIG_MODELINE) { + ret = drm_output_add_mode(output, &o->crtc_mode); + if (ret) + goto err_free; + configured = container_of(output->base.mode_list.prev, + struct weston_mode, link); + current = configured; + } + if (current == NULL && crtc_mode.clock != 0) { ret = drm_output_add_mode(output, &crtc_mode); if (ret) @@ -2043,6 +2055,65 @@ err_base: return NULL; } +static int +set_sync_flags(drmModeModeInfo *mode, char *hsync, char *vsync) +{ + mode->flags = 0; + + if (strcmp(hsync, "+hsync") == 0) + mode->flags |= DRM_MODE_FLAG_PHSYNC; + else if (strcmp(hsync, "-hsync") == 0) + mode->flags |= DRM_MODE_FLAG_NHSYNC; + else + return -1; + + if (strcmp(vsync, "+vsync") == 0) + mode->flags |= DRM_MODE_FLAG_PVSYNC; + else if (strcmp(vsync, "-vsync") == 0) + mode->flags |= DRM_MODE_FLAG_NVSYNC; + else + return -1; + + return 0; +} + +static int +check_for_modeline(struct drm_configured_output *output) +{ + drmModeModeInfo mode; + char hsync[16]; + char vsync[16]; + char mode_name[16]; + float fclock; + + mode.type = DRM_MODE_TYPE_USERDEF; + mode.hskew = 0; + mode.vscan = 0; + mode.vrefresh = 0; + + if (sscanf(output_mode, "%f %hd %hd %hd %hd %hd %hd %hd %hd %s %s", + &fclock, &mode.hdisplay, + &mode.hsync_start, + &mode.hsync_end, &mode.htotal, + &mode.vdisplay, + &mode.vsync_start, + &mode.vsync_end, &mode.vtotal, + hsync, vsync) == 11) { + if (set_sync_flags(&mode, hsync, vsync)) + return -1; + + sprintf(mode_name, "%dx%d", mode.hdisplay, mode.vdisplay); + strcpy(mode.name, mode_name); + + mode.clock = fclock * 1000; + } else + return -1; + + output->crtc_mode = mode; + + return 0; +} + static void output_section_done(void *data) { @@ -2070,6 +2141,8 @@ output_section_done(void *data) output->config = OUTPUT_CONFIG_CURRENT; else if (sscanf(output_mode, "%dx%d", &output->width, &output->height) == 2) output->config = OUTPUT_CONFIG_MODE; + else if (check_for_modeline(output) == 0) + output->config = OUTPUT_CONFIG_MODELINE; if (output->config != OUTPUT_CONFIG_INVALID) wl_list_insert(&configured_output_list, &output->link); diff --git a/weston.ini b/weston.ini index 375f4ee1..c2d63696 100644 --- a/weston.ini +++ b/weston.ini @@ -36,8 +36,8 @@ duration=600 #[output] #name=LVDS1 -#mode=off +#mode=1680x1050 #[output] #name=VGA1 -#mode=1280x1024 +#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync