commit 44e0afa78373bb0991703b0fdc2ad1d5ba1cc812 Author: Gregory M. Turner Date: Mon Jun 9 03:09:35 2014 -0700 Churn output names (second try) If a non-primary card (from BIOS's/vgaswitcheroo perspective) was made the xorg primary Driver, the "UMS naming compatibilty" code in drmmode_output_init never ran, because the associated connector_type value was not 1. On my workstation that was resulting in an output name conflict (and painful consequent woes in randr). While keeping the legacy output naming hacks exactly as they were, this patch gambles on the hypothesis that the tuple will always be unique on a per-provider basis, by introducing explicit, unique per-connector-type names: DVI-{I,D,A} and (somewhat awkwardly) HDMI{,-B}. This will churn the output names in certain obscure multi-gpu setups, but the vast majority will not see any difference. Meanwhile, it fixes all the corner cases I could imagine resulting in output-name collisions, even for "Unknown" connector_types. The legacy compatibility code has only been tested in wetware but seemed to do the right thing on that platform :) v1: dropped the legacy output naming entirely v2: revived the legacy output naming as it purportedly still matters Signed-off-by: Gregory M. Turner diff --git a/src/drmmode_display.c b/src/drmmode_display.c index bd8e701..2e83ccb 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "micmap.h" #include "xf86cmap.h" #include "radeon.h" @@ -1167,9 +1168,9 @@ static int subpixel_conv_table[7] = { 0, SubPixelUnknown, const char *output_names[] = { "None", "VGA", - "DVI", - "DVI", - "DVI", + "DVI-I", + "DVI-D", + "DVI-A", "Composite", "S-video", "LVDS", @@ -1177,7 +1178,7 @@ const char *output_names[] = { "None", "DIN", "DisplayPort", "HDMI", - "HDMI", + "HDMI-B", "TV", "eDP" }; @@ -1193,7 +1194,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, int *num_dv drmModeEncoderPtr *kencoders = NULL; drmmode_output_private_ptr drmmode_output; drmModePropertyPtr props; - char name[32]; + char prefix[32], name[32]; int i; const char *s; @@ -1213,42 +1214,65 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, int *num_dv } } - if (koutput->connector_type >= NUM_OUTPUT_NAMES) - snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, - koutput->connector_type_id - 1); + if (koutput->connector_type >= NUM_OUTPUT_NAMES) { #ifdef RADEON_PIXMAP_SHARING - else if (pScrn->is_gpu) - snprintf(name, 32, "%s-%d-%d", - output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, + if (pScrn->is_gpu) + snprintf(prefix, 32, "Unknown-%d", pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1); + else +#endif + strncpy(prefix, "Unknown", 32); + snprintf(name, 32, "%s-%d-%d", prefix, koutput->connector_type, koutput->connector_type_id - 1); + } else { + /* override_output_number is for special-case output name hacks. + * If set to a nonnegative value, override_output_number will be used + * to choose the numeric output suffix instead of connector_type_id. + * If set to -2, no numeric suffix will be appended at all. */ + int override_output_number = -1; +#ifdef RADEON_PIXMAP_SHARING + if (pScrn->is_gpu) + snprintf(prefix, 32, "%s-%d", output_names[koutput->connector_type], + pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1); + else #endif - else { - /* need to do smart conversion here for compat with non-kms ATI driver */ - if (koutput->connector_type_id == 1) { - switch(koutput->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_DVIA: - snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_dvi); - (*num_dvi)++; - break; - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_HDMIB: - snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_hdmi); - (*num_hdmi)++; - break; - case DRM_MODE_CONNECTOR_VGA: - case DRM_MODE_CONNECTOR_DisplayPort: - snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], - koutput->connector_type_id - 1); - break; - default: - snprintf(name, 32, "%s", output_names[koutput->connector_type]); - break; + if (koutput->connector_type_id == 1) { + /* This legacy naming convention has become so widely relied + * upon that, without some automagic migration mechanism, + * changing it would cause too much breakage */ + switch(koutput->connector_type) { + case DRM_MODE_CONNECTOR_DVII: + case DRM_MODE_CONNECTOR_DVID: + case DRM_MODE_CONNECTOR_DVIA: + strncpy(prefix, "DVI", 32); + override_output_number = (*num_dvi)++; + break; + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + strncpy(prefix, "HDMI", 32); + override_output_number = (*num_hdmi)++; + break; + case DRM_MODE_CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_DisplayPort: + strncpy(prefix, output_names[koutput->connector_type], 32); + break; + default: + strncpy(prefix, output_names[koutput->connector_type], 32); + override_output_number = -2; + break; + } + } else { + strncpy(prefix, output_names[koutput->connector_type], 32); } - } else { - snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], - koutput->connector_type_id - 1); + switch(override_output_number) { + case -2: + strncpy(name, prefix, 32); + break; + case -1: + snprintf(name, 32, "%s-%d", prefix, koutput->connector_type_id - 1); + break; + default: + snprintf(name, 32, "%s-%d", prefix, override_output_number); + break; } }