kms/plane-assignment: Add API to set cursor hotspot metadata

The transactional KMS API has been modelled after atomic KMS. Atomic KMS
currently doesn't support forwarding cursor hotspot metadata, thus it
was left out of the transactional KMS API having the user set the simply
create a plane assigment with the cursor sprite assigned to a cursor
plane using regular coordinates.

This, however, proved to be inadequate for virtual machines using
"seamless mouse mode" where they rely on the cursor position to
correspond to the actual cursor position of the virtual machine, not the
cursor plane. In effect, this caused cursor positions to look "shifted".

Fix this by adding back the hotspot metadata, right now as a optional
field to the plane assignment. In the legacy KMS implementation, this is
translated into drmModeSetCursor2() just as before, while still falling
back to drmModeSetCursor() with the plane coordinates, if either there
was no hotspot set, or if drmModeSetCursor2() failed.

Eventually, the atomic KMS API will learn about hotspots, but when
adding our own atomic KMS backend to the transacitonal KMS API, we must
until then still fall back to legacy KMS for virtual machines.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
This commit is contained in:
Jonas Ådahl 2020-03-19 09:01:03 +01:00 committed by Carlos Garnacho
parent 343de21af5
commit 55cf1c1496
4 changed files with 37 additions and 4 deletions

View File

@ -771,14 +771,27 @@ process_cursor_plane_assignment (MetaKmsImpl *impl,
if (!(plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED)) if (!(plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED))
{ {
int width, height; int width, height;
int ret; int ret = -1;
width = meta_fixed_16_to_int (plane_assignment->dst_rect.width); width = meta_fixed_16_to_int (plane_assignment->dst_rect.width);
height = meta_fixed_16_to_int (plane_assignment->dst_rect.height); height = meta_fixed_16_to_int (plane_assignment->dst_rect.height);
ret = drmModeSetCursor (fd, meta_kms_crtc_get_id (plane_assignment->crtc), if (plane_assignment->cursor_hotspot.is_valid)
plane_assignment->fb_id, {
width, height); ret = drmModeSetCursor2 (fd, meta_kms_crtc_get_id (plane_assignment->crtc),
plane_assignment->fb_id,
width, height,
plane_assignment->cursor_hotspot.x,
plane_assignment->cursor_hotspot.y);
}
if (ret != 0)
{
ret = drmModeSetCursor (fd, meta_kms_crtc_get_id (plane_assignment->crtc),
plane_assignment->fb_id,
width, height);
}
if (ret != 0) if (ret != 0)
{ {
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),

View File

@ -51,6 +51,12 @@ typedef struct _MetaKmsPlaneAssignment
MetaKmsAssignPlaneFlag flags; MetaKmsAssignPlaneFlag flags;
GList *plane_properties; GList *plane_properties;
struct {
gboolean is_valid;
int x;
int y;
} cursor_hotspot;
} MetaKmsPlaneAssignment; } MetaKmsPlaneAssignment;
typedef struct _MetaKmsModeSet typedef struct _MetaKmsModeSet

View File

@ -340,6 +340,16 @@ meta_kms_plane_assignment_set_plane_property (MetaKmsPlaneAssignment *plane_assi
g_list_prepend (plane_assignment->plane_properties, plane_prop); g_list_prepend (plane_assignment->plane_properties, plane_prop);
} }
void
meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment,
int x,
int y)
{
plane_assignment->cursor_hotspot.is_valid = TRUE;
plane_assignment->cursor_hotspot.x = x;
plane_assignment->cursor_hotspot.y = y;
}
MetaKmsPlaneAssignment * MetaKmsPlaneAssignment *
meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update, meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update,
MetaKmsCrtc *crtc) MetaKmsCrtc *crtc)

View File

@ -108,6 +108,10 @@ void meta_kms_update_custom_page_flip (MetaKmsUpdate *update,
MetaKmsCustomPageFlipFunc custom_page_flip_func, MetaKmsCustomPageFlipFunc custom_page_flip_func,
gpointer custom_page_flip_user_data); gpointer custom_page_flip_user_data);
void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment,
int x,
int y);
static inline MetaFixed16 static inline MetaFixed16
meta_fixed_16_from_int (int16_t d) meta_fixed_16_from_int (int16_t d)
{ {