summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@armlinux.org.uk>2018-06-27 20:51:17 +0100
committerRussell King <rmk@armlinux.org.uk>2018-07-13 16:58:52 +0100
commit1ba4f3f91696f0fec8430faf80dc6eb8bc19ed1d (patch)
treeeadaf26ae12c8b10ed0a131621707eebf5d642b3
parentcd705855b4e02b398e7284df2c0de03092ca27e0 (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.c45
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 */