xf86drmMode: introduce drmModeConnectorGetPossibleCrtcs

Nowadays, users don't really care about encoders except for retrieving
the list of CRTCs compatible with a connector. Introduce a new function
so that users no longer need to deal with encoders.

This is a re-do of [1], but with a slightly different API.

Signed-off-by: Simon Ser <contact@emersion.fr>

[1]: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/102
diff --git a/core-symbols.txt b/core-symbols.txt
index dcf9001..da98a6a 100644
--- a/core-symbols.txt
+++ b/core-symbols.txt
@@ -103,6 +103,7 @@
 drmModeAtomicMerge
 drmModeAtomicSetCursor
 drmModeAttachMode
+drmModeConnectorGetPossibleCrtcs
 drmModeConnectorSetProperty
 drmModeCreateLease
 drmModeCreatePropertyBlob
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 6d636dc..9dc4245 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -610,6 +610,29 @@
 	return _drmModeGetConnector(fd, connector_id, 0);
 }
 
+drm_public uint32_t drmModeConnectorGetPossibleCrtcs(int fd,
+                                                     const drmModeConnector *connector)
+{
+	drmModeEncoder *encoder;
+	int i;
+	uint32_t possible_crtcs;
+
+	possible_crtcs = 0;
+	for (i = 0; i < connector->count_encoders; i++) {
+		encoder = drmModeGetEncoder(fd, connector->encoders[i]);
+		if (!encoder) {
+			return 0;
+		}
+
+		possible_crtcs |= encoder->possible_crtcs;
+		drmModeFreeEncoder(encoder);
+	}
+
+	if (possible_crtcs == 0)
+		errno = ENOENT;
+	return possible_crtcs;
+}
+
 drm_public int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
 {
 	struct drm_mode_mode_cmd res;
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 46dc80a..4617d1e 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -381,6 +381,19 @@
 						      uint32_t connector_id);
 
 /**
+ * Get a bitmask of CRTCs a connector is compatible with.
+ *
+ * The bits reference CRTC indices. If the n-th CRTC is compatible with the
+ * connector, the n-th bit will be set. The indices are taken from the array
+ * returned by drmModeGetResources(). The indices are different from the object
+ * IDs.
+ *
+ * Zero is returned on error.
+ */
+extern uint32_t drmModeConnectorGetPossibleCrtcs(int fd,
+                                                 const drmModeConnector *connector);
+
+/**
  * Attaches the given mode to an connector.
  */
 extern int drmModeAttachMode(int fd, uint32_t connectorId, drmModeModeInfoPtr mode_info);