drm: allow selecting a connector via -O

References: https://github.com/Plagman/gamescope/issues/211
This commit is contained in:
Simon Ser 2021-07-22 16:50:16 +02:00
parent 52063b3858
commit e5e0ebf5a4
4 changed files with 72 additions and 8 deletions

View file

@ -34,9 +34,36 @@ bool g_bRotated = false;
bool g_bUseLayers = true;
bool g_bDebugLayers = false;
const char *g_sOutputName = nullptr;
static int s_drm_log = 0;
static std::map< uint32_t, const char * > connector_types = {
{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
{ DRM_MODE_CONNECTOR_VGA, "VGA" },
{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
{ DRM_MODE_CONNECTOR_Composite, "Composite" },
{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
{ DRM_MODE_CONNECTOR_Component, "Component" },
{ DRM_MODE_CONNECTOR_9PinDIN, "DIN" },
{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort" },
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
{ DRM_MODE_CONNECTOR_TV, "TV" },
{ DRM_MODE_CONNECTOR_eDP, "eDP" },
{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
{ DRM_MODE_CONNECTOR_DSI, "DSI" },
{ DRM_MODE_CONNECTOR_DPI, "DPI" },
{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
{ DRM_MODE_CONNECTOR_SPI, "SPI" },
#ifdef DRM_MODE_CONNECTOR_USB
{ DRM_MODE_CONNECTOR_USB, "USB" },
#endif
};
static struct crtc *find_crtc_for_encoder(struct drm_t *drm, const drmModeEncoder *encoder) {
for (size_t i = 0; i < drm->crtcs.size(); i++) {
/* possible_crtcs is a bitmask as described here:
@ -314,6 +341,15 @@ static bool get_resources(struct drm_t *drm)
return false;
}
const char *type_str = "Unknown";
if ( connector_types.count( conn.connector->connector_type ) > 0 )
type_str = connector_types[ conn.connector->connector_type ];
char name[128] = {};
snprintf(name, sizeof(name), "%s-%d", type_str, conn.connector->connector_type_id);
conn.name = strdup(name);
drm->connectors.push_back(conn);
}
@ -362,6 +398,23 @@ static bool get_resources(struct drm_t *drm)
return true;
}
static struct connector *find_connector( drm_t *drm, const char *name )
{
for (size_t i = 0; i < drm->connectors.size(); i++) {
struct connector *conn = &drm->connectors[i];
if (conn->connector->connection != DRM_MODE_CONNECTED)
continue;
if ( name != nullptr && strcmp( conn->name, name ) != 0 )
continue;
return conn;
}
return nullptr;
}
static const drmModeModeInfo *get_matching_mode( const drmModeConnector *connector, int hdisplay, int vdisplay, uint32_t vrefresh )
{
for (int i = 0; i < connector->count_modes; i++) {
@ -436,20 +489,26 @@ int init_drm(struct drm_t *drm, const char *device)
return -1;
}
/* find a connected connector */
fprintf( stderr, "Connectors:\n" );
for (size_t i = 0; i < drm->connectors.size(); i++) {
if (drm->connectors[i].connector->connection == DRM_MODE_CONNECTED) {
drm->connector = &drm->connectors[i];
connector = drm->connector->connector;
break;
}
struct connector *conn = &drm->connectors[i];
const char *status_str = "disconnected";
if ( conn->connector->connection == DRM_MODE_CONNECTED )
status_str = "connected";
fprintf( stderr, " %s (%s)\n", conn->name, status_str );
}
drm->connector = find_connector( drm, g_sOutputName );
if (!drm->connector) {
/* we could be fancy and listen for hotplug events and wait for
* a connector..
*/
fprintf(stderr, "no connected connector!\n");
if ( g_sOutputName != nullptr )
fprintf( stderr, "Cannot find connector '%s'\n", g_sOutputName );
else
fprintf( stderr, "Cannot find any connector!\n" );
return -1;
}

View file

@ -39,6 +39,7 @@ struct crtc {
struct connector {
uint32_t id;
char *name;
drmModeConnector *connector;
std::map<std::string, drmModePropertyRes *> props;
std::map<std::string, uint64_t> initial_prop_values;
@ -112,6 +113,7 @@ extern uint32_t g_nDRMFormat;
extern bool g_bUseLayers;
extern bool g_bRotated;
extern bool g_bDebugLayers;
extern const char *g_sOutputName;
int init_drm(struct drm_t *drm, const char *device);
int drm_atomic_commit(struct drm_t *drm, struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline );

View file

@ -97,6 +97,9 @@ int main(int argc, char **argv)
case 'f':
g_bFullscreen = true;
break;
case 'O':
g_sOutputName = optarg;
break;
default:
break;
}

View file

@ -1,6 +1,6 @@
#pragma once
#define GAMESCOPE_OPTIONS ":R:T:C:w:h:W:H:r:o:NFSvVecsdLnbfx"
#define GAMESCOPE_OPTIONS ":R:T:C:w:h:W:H:r:o:NFSvVecsdLnbfxO:"
int initOutput(void);