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:
parent
145de4df8d
commit
fb08a597e1
1 changed files with 185 additions and 0 deletions
|
@ -57,13 +57,29 @@ typedef struct _MetaWaylandDrmLeaseDevice
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
MetaKmsDevice *kms_device;
|
MetaKmsDevice *kms_device;
|
||||||
|
|
||||||
|
/* Key: MetaKmsConnector *kms_connector
|
||||||
|
* Value: MetaWaylandDrmLeaseConnector *lease_connector
|
||||||
|
*/
|
||||||
|
GHashTable *connectors;
|
||||||
|
|
||||||
GList *resources;
|
GList *resources;
|
||||||
} MetaWaylandDrmLeaseDevice;
|
} MetaWaylandDrmLeaseDevice;
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDrmLeaseConnector
|
||||||
|
{
|
||||||
|
MetaWaylandDrmLeaseDevice *lease_device;
|
||||||
|
|
||||||
|
MetaKmsConnector *kms_connector;
|
||||||
|
char *description;
|
||||||
|
|
||||||
|
GList *resources;
|
||||||
|
} MetaWaylandDrmLeaseConnector;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_drm_lease_device_free (MetaWaylandDrmLeaseDevice *lease_device)
|
meta_wayland_drm_lease_device_free (MetaWaylandDrmLeaseDevice *lease_device)
|
||||||
{
|
{
|
||||||
g_object_unref (lease_device->kms_device);
|
g_object_unref (lease_device->kms_device);
|
||||||
|
g_clear_pointer (&lease_device->connectors, g_hash_table_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -76,6 +92,24 @@ meta_wayland_drm_lease_device_release (MetaWaylandDrmLeaseDevice *lease_device)
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWaylandDrmLeaseDevice,
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWaylandDrmLeaseDevice,
|
||||||
meta_wayland_drm_lease_device_release);
|
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
|
static void
|
||||||
wp_drm_lease_device_create_lease_request (struct wl_client *client,
|
wp_drm_lease_device_create_lease_request (struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
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,
|
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
|
static void
|
||||||
send_drm_fd (struct wl_client *client,
|
send_drm_fd (struct wl_client *client,
|
||||||
MetaWaylandDrmLeaseDevice *lease_device,
|
MetaWaylandDrmLeaseDevice *lease_device,
|
||||||
|
@ -142,22 +299,50 @@ lease_device_bind (struct wl_client *client,
|
||||||
wp_drm_lease_device_destructor);
|
wp_drm_lease_device_destructor);
|
||||||
|
|
||||||
send_drm_fd (client, lease_device, resource);
|
send_drm_fd (client, lease_device, resource);
|
||||||
|
send_connectors (lease_device, resource);
|
||||||
wp_drm_lease_device_v1_send_done (resource);
|
wp_drm_lease_device_v1_send_done (resource);
|
||||||
|
|
||||||
lease_device->resources = g_list_prepend (lease_device->resources, 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 *
|
static MetaWaylandDrmLeaseDevice *
|
||||||
meta_wayland_drm_lease_device_new (MetaWaylandDrmLeaseManager *lease_manager,
|
meta_wayland_drm_lease_device_new (MetaWaylandDrmLeaseManager *lease_manager,
|
||||||
MetaKmsDevice *kms_device)
|
MetaKmsDevice *kms_device)
|
||||||
{
|
{
|
||||||
struct wl_display *wayland_display =
|
struct wl_display *wayland_display =
|
||||||
meta_wayland_compositor_get_wayland_display (lease_manager->compositor);
|
meta_wayland_compositor_get_wayland_display (lease_manager->compositor);
|
||||||
|
MetaDrmLeaseManager *drm_lease_manager = lease_manager->drm_lease_manager;
|
||||||
MetaWaylandDrmLeaseDevice *lease_device;
|
MetaWaylandDrmLeaseDevice *lease_device;
|
||||||
|
g_autoptr (GList) kms_connectors = NULL;
|
||||||
|
|
||||||
lease_device = g_rc_box_new0 (MetaWaylandDrmLeaseDevice);
|
lease_device = g_rc_box_new0 (MetaWaylandDrmLeaseDevice);
|
||||||
lease_device->lease_manager = lease_manager;
|
lease_device->lease_manager = lease_manager;
|
||||||
lease_device->kms_device = g_object_ref (kms_device);
|
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,
|
lease_device->global = wl_global_create (wayland_display,
|
||||||
&wp_drm_lease_device_v1_interface,
|
&wp_drm_lease_device_v1_interface,
|
||||||
META_WP_DRM_LEASE_DEVICE_V1_VERSION,
|
META_WP_DRM_LEASE_DEVICE_V1_VERSION,
|
||||||
|
|
Loading…
Reference in a new issue