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.
This commit is contained in:
committed by
Kristian Høgsberg
parent
4f238a590d
commit
8f37e0bc1e
+75
-2
@@ -53,13 +53,15 @@ enum output_config {
|
|||||||
OUTPUT_CONFIG_OFF,
|
OUTPUT_CONFIG_OFF,
|
||||||
OUTPUT_CONFIG_PREFERRED,
|
OUTPUT_CONFIG_PREFERRED,
|
||||||
OUTPUT_CONFIG_CURRENT,
|
OUTPUT_CONFIG_CURRENT,
|
||||||
OUTPUT_CONFIG_MODE
|
OUTPUT_CONFIG_MODE,
|
||||||
|
OUTPUT_CONFIG_MODELINE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drm_configured_output {
|
struct drm_configured_output {
|
||||||
char *name;
|
char *name;
|
||||||
char *mode;
|
char *mode;
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
|
drmModeModeInfo crtc_mode;
|
||||||
enum output_config config;
|
enum output_config config;
|
||||||
struct wl_list link;
|
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) {
|
wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
|
||||||
if (o && o->width == drm_mode->base.width &&
|
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;
|
configured = &drm_mode->base;
|
||||||
if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
|
if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
|
||||||
current = &drm_mode->base;
|
current = &drm_mode->base;
|
||||||
@@ -1405,6 +1408,15 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
preferred = &drm_mode->base;
|
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) {
|
if (current == NULL && crtc_mode.clock != 0) {
|
||||||
ret = drm_output_add_mode(output, &crtc_mode);
|
ret = drm_output_add_mode(output, &crtc_mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -2043,6 +2055,65 @@ err_base:
|
|||||||
return NULL;
|
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
|
static void
|
||||||
output_section_done(void *data)
|
output_section_done(void *data)
|
||||||
{
|
{
|
||||||
@@ -2070,6 +2141,8 @@ output_section_done(void *data)
|
|||||||
output->config = OUTPUT_CONFIG_CURRENT;
|
output->config = OUTPUT_CONFIG_CURRENT;
|
||||||
else if (sscanf(output_mode, "%dx%d", &output->width, &output->height) == 2)
|
else if (sscanf(output_mode, "%dx%d", &output->width, &output->height) == 2)
|
||||||
output->config = OUTPUT_CONFIG_MODE;
|
output->config = OUTPUT_CONFIG_MODE;
|
||||||
|
else if (check_for_modeline(output) == 0)
|
||||||
|
output->config = OUTPUT_CONFIG_MODELINE;
|
||||||
|
|
||||||
if (output->config != OUTPUT_CONFIG_INVALID)
|
if (output->config != OUTPUT_CONFIG_INVALID)
|
||||||
wl_list_insert(&configured_output_list, &output->link);
|
wl_list_insert(&configured_output_list, &output->link);
|
||||||
|
|||||||
+2
-2
@@ -36,8 +36,8 @@ duration=600
|
|||||||
|
|
||||||
#[output]
|
#[output]
|
||||||
#name=LVDS1
|
#name=LVDS1
|
||||||
#mode=off
|
#mode=1680x1050
|
||||||
|
|
||||||
#[output]
|
#[output]
|
||||||
#name=VGA1
|
#name=VGA1
|
||||||
#mode=1280x1024
|
#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
|
||||||
|
|||||||
Reference in New Issue
Block a user