1
0
Fork 0

wayland/drm-lease: Advertize initial connectors

After sending the drm_fd event, send zero, one or more connector events.
After all currently available connectors have been sent, send a
wp_drm_lease_device_v1.done event.

Co-authored-by: José Expósito <jexposit@redhat.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3746>
This commit is contained in:
Jonas Ådahl 2024-04-23 17:55:55 +02:00 committed by Marge Bot
parent 145de4df8d
commit fb08a597e1

View file

@ -57,13 +57,29 @@ typedef struct _MetaWaylandDrmLeaseDevice
struct wl_global *global;
MetaKmsDevice *kms_device;
/* Key: MetaKmsConnector *kms_connector
* Value: MetaWaylandDrmLeaseConnector *lease_connector
*/
GHashTable *connectors;
GList *resources;
} MetaWaylandDrmLeaseDevice;
typedef struct _MetaWaylandDrmLeaseConnector
{
MetaWaylandDrmLeaseDevice *lease_device;
MetaKmsConnector *kms_connector;
char *description;
GList *resources;
} MetaWaylandDrmLeaseConnector;
static void
meta_wayland_drm_lease_device_free (MetaWaylandDrmLeaseDevice *lease_device)
{
g_object_unref (lease_device->kms_device);
g_clear_pointer (&lease_device->connectors, g_hash_table_unref);
}
static void
@ -76,6 +92,24 @@ meta_wayland_drm_lease_device_release (MetaWaylandDrmLeaseDevice *lease_device)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWaylandDrmLeaseDevice,
meta_wayland_drm_lease_device_release);
static void
meta_wayland_drm_lease_connector_free (MetaWaylandDrmLeaseConnector *lease_connector)
{
g_object_unref (lease_connector->kms_connector);
g_free (lease_connector->description);
meta_wayland_drm_lease_device_release (lease_connector->lease_device);
}
static void
meta_wayland_drm_lease_connector_release (MetaWaylandDrmLeaseConnector *lease_connector)
{
g_rc_box_release_full (lease_connector,
(GDestroyNotify) meta_wayland_drm_lease_connector_free);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWaylandDrmLeaseConnector,
meta_wayland_drm_lease_connector_release);
static void
wp_drm_lease_device_create_lease_request (struct wl_client *client,
struct wl_resource *resource,
@ -95,6 +129,129 @@ static const struct wp_drm_lease_device_v1_interface drm_lease_device_implementa
wp_drm_lease_device_release,
};
static char *
get_connector_description (MetaKmsConnector *kms_connector)
{
const MetaKmsConnectorState *connector_state;
gconstpointer edid_data;
g_autofree MetaEdidInfo *edid_info = NULL;
size_t edid_size;
g_autofree char *vendor = NULL;
g_autofree char *product = NULL;
GString *description;
connector_state = meta_kms_connector_get_current_state (kms_connector);
if (!connector_state || !connector_state->edid_data)
return g_strdup ("");
edid_data = g_bytes_get_data (connector_state->edid_data, &edid_size);
edid_info = meta_edid_info_new_parse (edid_data, edid_size);
description = g_string_new (NULL);
vendor = g_strndup (edid_info->manufacturer_code, 4);
if (vendor && g_utf8_validate (vendor, -1, NULL))
g_string_append_printf (description, "%s", vendor);
product = g_strndup (edid_info->dsc_product_name, 14);
if (product && g_utf8_validate (product, -1, NULL))
{
if (description->len > 0)
g_string_append_c (description, ' ');
g_string_append_printf (description, "%s", product);
}
if (description->len == 0)
{
g_string_append_printf (description, "%s",
meta_kms_connector_get_name (kms_connector));
}
return g_string_free_and_steal (description);
}
static MetaWaylandDrmLeaseConnector *
meta_wayland_drm_lease_connector_new (MetaWaylandDrmLeaseDevice *lease_device,
MetaKmsConnector *kms_connector)
{
MetaWaylandDrmLeaseConnector *lease_connector;
lease_connector = g_rc_box_new0 (MetaWaylandDrmLeaseConnector);
lease_connector->lease_device = g_rc_box_acquire (lease_device);
lease_connector->kms_connector = g_object_ref (kms_connector);
lease_connector->description = get_connector_description (kms_connector);
return lease_connector;
}
static void
drm_lease_connector_destroy (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}
static const struct wp_drm_lease_connector_v1_interface drm_lease_connector_implementation = {
drm_lease_connector_destroy,
};
static void
wp_drm_lease_connector_destructor (struct wl_resource *resource)
{
MetaWaylandDrmLeaseConnector *lease_connector =
wl_resource_get_user_data (resource);
lease_connector->resources = g_list_remove (lease_connector->resources,
resource);
meta_wayland_drm_lease_connector_release (lease_connector);
}
static void
send_new_connector_resource (MetaWaylandDrmLeaseDevice *lease_device,
struct wl_resource *device_resource,
MetaWaylandDrmLeaseConnector *lease_connector)
{
struct wl_resource *connector_resource;
const char *connector_name;
uint32_t connector_id;
connector_resource =
wl_resource_create (wl_resource_get_client (device_resource),
&wp_drm_lease_connector_v1_interface,
wl_resource_get_version (device_resource),
0);
wl_resource_set_implementation (connector_resource,
&drm_lease_connector_implementation,
g_rc_box_acquire (lease_connector),
wp_drm_lease_connector_destructor);
lease_connector->resources = g_list_append (lease_connector->resources,
connector_resource);
connector_name = meta_kms_connector_get_name (lease_connector->kms_connector);
connector_id = meta_kms_connector_get_id (lease_connector->kms_connector);
wp_drm_lease_device_v1_send_connector (device_resource, connector_resource);
wp_drm_lease_connector_v1_send_name (connector_resource, connector_name);
wp_drm_lease_connector_v1_send_description (connector_resource,
lease_connector->description);
wp_drm_lease_connector_v1_send_connector_id (connector_resource,
connector_id);
wp_drm_lease_connector_v1_send_done (connector_resource);
}
static void
send_connectors (MetaWaylandDrmLeaseDevice *lease_device,
struct wl_resource *device_resource)
{
GHashTableIter iter;
MetaWaylandDrmLeaseConnector *lease_connector;
g_hash_table_iter_init (&iter, lease_device->connectors);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &lease_connector))
send_new_connector_resource (lease_device, device_resource, lease_connector);
}
static void
send_drm_fd (struct wl_client *client,
MetaWaylandDrmLeaseDevice *lease_device,
@ -142,22 +299,50 @@ lease_device_bind (struct wl_client *client,
wp_drm_lease_device_destructor);
send_drm_fd (client, lease_device, resource);
send_connectors (lease_device, resource);
wp_drm_lease_device_v1_send_done (resource);
lease_device->resources = g_list_prepend (lease_device->resources, resource);
}
static void
meta_wayland_drm_lease_device_add_connector (MetaKmsConnector *kms_connector,
MetaWaylandDrmLeaseDevice *lease_device)
{
g_autoptr (MetaWaylandDrmLeaseConnector) lease_connector = NULL;
lease_connector = meta_wayland_drm_lease_connector_new (lease_device,
kms_connector);
g_hash_table_insert (lease_device->connectors,
kms_connector,
g_steal_pointer (&lease_connector));
}
static MetaWaylandDrmLeaseDevice *
meta_wayland_drm_lease_device_new (MetaWaylandDrmLeaseManager *lease_manager,
MetaKmsDevice *kms_device)
{
struct wl_display *wayland_display =
meta_wayland_compositor_get_wayland_display (lease_manager->compositor);
MetaDrmLeaseManager *drm_lease_manager = lease_manager->drm_lease_manager;
MetaWaylandDrmLeaseDevice *lease_device;
g_autoptr (GList) kms_connectors = NULL;
lease_device = g_rc_box_new0 (MetaWaylandDrmLeaseDevice);
lease_device->lease_manager = lease_manager;
lease_device->kms_device = g_object_ref (kms_device);
lease_device->connectors =
g_hash_table_new_full (NULL, NULL,
NULL,
(GDestroyNotify) meta_wayland_drm_lease_connector_release);
kms_connectors = meta_drm_lease_manager_get_connectors (drm_lease_manager,
kms_device);
g_list_foreach (kms_connectors,
(GFunc) meta_wayland_drm_lease_device_add_connector,
lease_device);
lease_device->global = wl_global_create (wayland_display,
&wp_drm_lease_device_v1_interface,
META_WP_DRM_LEASE_DEVICE_V1_VERSION,