kms/impl-device/atomic: Implement mouse cursor hotspots
DRM's kms atomic code was updated to include an API to set the mouse cursor hotspot. This has historically been missing in the atomic kms which meant that the virtualized drivers which require mouse cursor hotspot info to properly render had to be put on a deny list and had to fallback to the legacy DRM kms code. Implement the new hotspot API by checking whether the device supports hotspot properties and if it does set them on the cursor plane. This enables atomic kms on all virtualized drivers for kernels where mouse cursor hotspots are in drm core. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3337>
This commit is contained in:
parent
3885d2b3f6
commit
27f798b6d0
1 changed files with 63 additions and 4 deletions
|
@ -48,6 +48,16 @@ static GInitableIface *initable_parent_iface;
|
|||
static void
|
||||
initable_iface_init (GInitableIface *iface);
|
||||
|
||||
/*
|
||||
* Fallback while the patch updating the uAPI header has not landed.
|
||||
* Should be removed afterward.
|
||||
* Clients which do set cursor hotspot and treat the cursor plane
|
||||
* like a mouse cursor should set this property.
|
||||
*/
|
||||
#ifndef DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT
|
||||
#define DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT 6
|
||||
#endif
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceAtomic, meta_kms_impl_device_atomic,
|
||||
META_TYPE_KMS_IMPL_DEVICE,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
|
@ -1234,6 +1244,20 @@ meta_kms_impl_device_atomic_finalize (GObject *object)
|
|||
G_OBJECT_CLASS (meta_kms_impl_device_atomic_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
requires_hotspots (const char *driver_name)
|
||||
{
|
||||
const char *atomic_driver_hotspots[] = {
|
||||
"qxl",
|
||||
"vboxvideo",
|
||||
"virtio_gpu",
|
||||
"vmwgfx",
|
||||
NULL,
|
||||
};
|
||||
|
||||
return g_strv_contains (atomic_driver_hotspots, driver_name);
|
||||
}
|
||||
|
||||
static MetaDeviceFile *
|
||||
meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
|
||||
const char *path,
|
||||
|
@ -1284,14 +1308,30 @@ meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
|
|||
return g_steal_pointer (&device_file);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_cursor_hotspot_properties (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
GList *planes;
|
||||
GList *l;
|
||||
|
||||
planes = meta_kms_impl_device_peek_planes (impl_device);
|
||||
for (l = planes; l; l = l->next)
|
||||
{
|
||||
MetaKmsPlane *plane = l->data;
|
||||
|
||||
if (meta_kms_plane_get_plane_type (plane) != META_KMS_PLANE_TYPE_CURSOR)
|
||||
continue;
|
||||
|
||||
return meta_kms_plane_supports_cursor_hotspot (plane);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_atomic_allowed (const char *driver_name)
|
||||
{
|
||||
const char *atomic_driver_deny_list[] = {
|
||||
"qxl",
|
||||
"vmwgfx",
|
||||
"vboxvideo",
|
||||
"virtio_gpu",
|
||||
"xlnx",
|
||||
NULL,
|
||||
};
|
||||
|
@ -1319,6 +1359,25 @@ meta_kms_impl_device_atomic_initable_init (GInitable *initable,
|
|||
if (!meta_kms_impl_device_init_mode_setting (impl_device, error))
|
||||
return FALSE;
|
||||
|
||||
if (requires_hotspots (meta_kms_impl_device_get_driver_name (impl_device)))
|
||||
{
|
||||
if (drmSetClientCap (meta_kms_impl_device_get_fd (impl_device),
|
||||
DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, 1) != 0)
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
|
||||
"Kernel has no support for virtual cursor plane on %s",
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
return FALSE;
|
||||
}
|
||||
if (!has_cursor_hotspot_properties (impl_device))
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
|
||||
"Plane cursor with hotspot properties is missing on %s",
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_message ("Added device '%s' (%s) using atomic mode setting.",
|
||||
meta_kms_impl_device_get_path (impl_device),
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
|
|
Loading…
Reference in a new issue