diff options
author | Russell King <rmk@armlinux.org.uk> | 2018-06-27 20:51:17 +0100 |
---|---|---|
committer | Russell King <rmk@armlinux.org.uk> | 2018-07-13 16:58:52 +0100 |
commit | 1ba4f3f91696f0fec8430faf80dc6eb8bc19ed1d (patch) | |
tree | eadaf26ae12c8b10ed0a131621707eebf5d642b3 | |
parent | cd705855b4e02b398e7284df2c0de03092ca27e0 (diff) |
src: improve robustness converting from kernel enums
Improve the robustness of our conversion from kernel enums,
specifically the subpixel order and the connector type. Recent
kernels have more connector types, which will cause us to overflow
the array of names should we encounter a KMS driver with such a
connector.
Signed-off-by: Russell King <rmk@armlinux.org.uk>
-rw-r--r-- | src/common_drm.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/src/common_drm.c b/src/common_drm.c index 0db9e43..fc1f648 100644 --- a/src/common_drm.c +++ b/src/common_drm.c @@ -445,16 +445,49 @@ static const xf86OutputFuncsRec drm_output_funcs = { .destroy = common_drm_conn_destroy, }; +/* Convert libdrm's connector type to Xorg name */ static const char *const output_names[] = { - "None", "VGA", "DVI", "DVI", "DVI", "Composite", "TV", - "LVDS", "CTV", "DIN", "DP", "HDMI", "HDMI", + [DRM_MODE_CONNECTOR_Unknown] = "None", + [DRM_MODE_CONNECTOR_VGA] = "VGA", + [DRM_MODE_CONNECTOR_DVII] = "DVI", + [DRM_MODE_CONNECTOR_DVID] = "DVI", + [DRM_MODE_CONNECTOR_DVIA] = "DVI", + [DRM_MODE_CONNECTOR_Composite] = "Composite", + [DRM_MODE_CONNECTOR_SVIDEO] = "TV", + [DRM_MODE_CONNECTOR_LVDS] = "LVDS", + [DRM_MODE_CONNECTOR_Component] = "CTV", + [DRM_MODE_CONNECTOR_9PinDIN] = "DIN", + [DRM_MODE_CONNECTOR_DisplayPort] = "DP", + [DRM_MODE_CONNECTOR_HDMIA] = "HDMI", + [DRM_MODE_CONNECTOR_HDMIB] = "HDMI", }; +static const char *common_drm_output_name(uint32_t type) +{ + if (type >= ARRAY_SIZE(output_names)) + type = DRM_MODE_CONNECTOR_Unknown; + + return output_names[type]; +} + +/* Convert libdrm's subpixel order to Xorg subpixel */ static const int subpixel_conv_table[] = { - 0, SubPixelUnknown, SubPixelHorizontalRGB, SubPixelHorizontalBGR, - SubPixelVerticalRGB, SubPixelVerticalBGR, SubPixelNone + [DRM_MODE_SUBPIXEL_UNKNOWN] = SubPixelUnknown, + [DRM_MODE_SUBPIXEL_HORIZONTAL_RGB] = SubPixelHorizontalRGB, + [DRM_MODE_SUBPIXEL_HORIZONTAL_BGR] = SubPixelHorizontalBGR, + [DRM_MODE_SUBPIXEL_VERTICAL_RGB] = SubPixelVerticalRGB, + [DRM_MODE_SUBPIXEL_VERTICAL_BGR] = SubPixelVerticalBGR, + [DRM_MODE_SUBPIXEL_NONE] = SubPixelNone, }; +static int common_drm_subpixel(drmModeSubPixel k) +{ + if (k >= ARRAY_SIZE(subpixel_conv_table)) + k = DRM_MODE_SUBPIXEL_UNKNOWN; + + return subpixel_conv_table[k]; +} + static void common_drm_conn_init(ScrnInfoPtr pScrn, uint32_t id) { struct common_drm_info *drm = GET_DRM_INFO(pScrn); @@ -475,7 +508,7 @@ static void common_drm_conn_init(ScrnInfoPtr pScrn, uint32_t id) } snprintf(name, sizeof(name), "%s%d", - output_names[koutput->connector_type], + common_drm_output_name(koutput->connector_type), koutput->connector_type_id); output = xf86OutputCreate(pScrn, &drm_output_funcs, name); @@ -501,7 +534,7 @@ static void common_drm_conn_init(ScrnInfoPtr pScrn, uint32_t id) output->driver_private = conn; output->mm_width = koutput->mmWidth; output->mm_height = koutput->mmHeight; - output->subpixel_order = subpixel_conv_table[koutput->subpixel]; + output->subpixel_order = common_drm_subpixel(koutput->subpixel); output->possible_crtcs = kencoder->possible_crtcs; output->possible_clones = kencoder->possible_clones; output->interlaceAllowed = 1; /* wish there was a way to read that */ |