|
|
81f5f8b |
From f2a2b3496b6024a5df546f0aedd60705b896a464 Mon Sep 17 00:00:00 2001
|
|
|
81f5f8b |
From: Dave Airlie <airlied@redhat.com>
|
|
|
81f5f8b |
Date: Thu, 20 Jun 2013 11:48:52 +1000
|
|
|
81f5f8b |
Subject: [PATCH 2/5] drm: add hotspot support for cursors.
|
|
|
81f5f8b |
|
|
|
81f5f8b |
So it looks like for virtual hw cursors on QXL we need to inform
|
|
|
81f5f8b |
the "hw" device what the cursor hotspot parameters are. This
|
|
|
81f5f8b |
makes sense if you think the host has to draw the cursor and interpret
|
|
|
81f5f8b |
clicks from it. However the current modesetting interface doesn't support
|
|
|
81f5f8b |
passing the hotspot information from userspace.
|
|
|
81f5f8b |
|
|
|
81f5f8b |
This implements a new cursor ioctl, that takes the hotspot info as well,
|
|
|
81f5f8b |
userspace can try calling the new interface and if it gets -ENOSYS it means
|
|
|
81f5f8b |
its on an older kernel and can just fallback.
|
|
|
81f5f8b |
|
|
|
81f5f8b |
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
|
81f5f8b |
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
81f5f8b |
---
|
|
|
81f5f8b |
drivers/gpu/drm/drm_crtc.c | 35 +++++++++++++++++++++++++++++------
|
|
|
81f5f8b |
drivers/gpu/drm/drm_drv.c | 1 +
|
|
|
81f5f8b |
include/drm/drm_crtc.h | 5 +++++
|
|
|
81f5f8b |
include/uapi/drm/drm.h | 1 +
|
|
|
81f5f8b |
include/uapi/drm/drm_mode.h | 13 +++++++++++++
|
|
|
81f5f8b |
5 files changed, 49 insertions(+), 6 deletions(-)
|
|
|
81f5f8b |
|
|
|
81f5f8b |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
|
|
|
81f5f8b |
index dd64a06..21e71a8 100644
|
|
|
81f5f8b |
--- a/drivers/gpu/drm/drm_crtc.c
|
|
|
81f5f8b |
+++ b/drivers/gpu/drm/drm_crtc.c
|
|
|
81f5f8b |
@@ -2202,10 +2202,10 @@ out:
|
|
|
81f5f8b |
return ret;
|
|
|
81f5f8b |
}
|
|
|
81f5f8b |
|
|
|
81f5f8b |
-int drm_mode_cursor_ioctl(struct drm_device *dev,
|
|
|
81f5f8b |
- void *data, struct drm_file *file_priv)
|
|
|
81f5f8b |
+static int drm_mode_cursor_common(struct drm_device *dev,
|
|
|
81f5f8b |
+ struct drm_mode_cursor2 *req,
|
|
|
81f5f8b |
+ struct drm_file *file_priv)
|
|
|
81f5f8b |
{
|
|
|
81f5f8b |
- struct drm_mode_cursor *req = data;
|
|
|
81f5f8b |
struct drm_mode_object *obj;
|
|
|
81f5f8b |
struct drm_crtc *crtc;
|
|
|
81f5f8b |
int ret = 0;
|
|
|
81f5f8b |
@@ -2225,13 +2225,17 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
|
|
|
81f5f8b |
|
|
|
81f5f8b |
mutex_lock(&crtc->mutex);
|
|
|
81f5f8b |
if (req->flags & DRM_MODE_CURSOR_BO) {
|
|
|
81f5f8b |
- if (!crtc->funcs->cursor_set) {
|
|
|
81f5f8b |
+ if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
|
|
|
81f5f8b |
ret = -ENXIO;
|
|
|
81f5f8b |
goto out;
|
|
|
81f5f8b |
}
|
|
|
81f5f8b |
/* Turns off the cursor if handle is 0 */
|
|
|
81f5f8b |
- ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
|
|
|
81f5f8b |
- req->width, req->height);
|
|
|
81f5f8b |
+ if (crtc->funcs->cursor_set2)
|
|
|
81f5f8b |
+ ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
|
|
|
81f5f8b |
+ req->width, req->height, req->hot_x, req->hot_y);
|
|
|
81f5f8b |
+ else
|
|
|
81f5f8b |
+ ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
|
|
|
81f5f8b |
+ req->width, req->height);
|
|
|
81f5f8b |
}
|
|
|
81f5f8b |
|
|
|
81f5f8b |
if (req->flags & DRM_MODE_CURSOR_MOVE) {
|
|
|
81f5f8b |
@@ -2246,6 +2250,25 @@ out:
|
|
|
81f5f8b |
mutex_unlock(&crtc->mutex);
|
|
|
81f5f8b |
|
|
|
81f5f8b |
return ret;
|
|
|
81f5f8b |
+
|
|
|
81f5f8b |
+}
|
|
|
81f5f8b |
+int drm_mode_cursor_ioctl(struct drm_device *dev,
|
|
|
81f5f8b |
+ void *data, struct drm_file *file_priv)
|
|
|
81f5f8b |
+{
|
|
|
81f5f8b |
+ struct drm_mode_cursor *req = data;
|
|
|
81f5f8b |
+ struct drm_mode_cursor2 new_req;
|
|
|
81f5f8b |
+
|
|
|
81f5f8b |
+ memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
|
|
|
81f5f8b |
+ new_req.hot_x = new_req.hot_y = 0;
|
|
|
81f5f8b |
+
|
|
|
81f5f8b |
+ return drm_mode_cursor_common(dev, &new_req, file_priv);
|
|
|
81f5f8b |
+}
|
|
|
81f5f8b |
+
|
|
|
81f5f8b |
+int drm_mode_cursor2_ioctl(struct drm_device *dev,
|
|
|
81f5f8b |
+ void *data, struct drm_file *file_priv)
|
|
|
81f5f8b |
+{
|
|
|
81f5f8b |
+ struct drm_mode_cursor2 *req = data;
|
|
|
81f5f8b |
+ return drm_mode_cursor_common(dev, req, file_priv);
|
|
|
81f5f8b |
}
|
|
|
81f5f8b |
|
|
|
81f5f8b |
/* Original addfb only supported RGB formats, so figure out which one */
|
|
|
81f5f8b |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
|
|
|
81f5f8b |
index 25f91cd..cb4470b 100644
|
|
|
81f5f8b |
--- a/drivers/gpu/drm/drm_drv.c
|
|
|
81f5f8b |
+++ b/drivers/gpu/drm/drm_drv.c
|
|
|
81f5f8b |
@@ -166,6 +166,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
|
|
|
81f5f8b |
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
|
|
|
81f5f8b |
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
|
|
|
81f5f8b |
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
|
|
|
81f5f8b |
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
|
|
|
81f5f8b |
};
|
|
|
81f5f8b |
|
|
|
81f5f8b |
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
|
|
|
81f5f8b |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
|
|
|
81f5f8b |
index e3e0d65..eba931b 100644
|
|
|
81f5f8b |
--- a/include/drm/drm_crtc.h
|
|
|
81f5f8b |
+++ b/include/drm/drm_crtc.h
|
|
|
81f5f8b |
@@ -339,6 +339,9 @@ struct drm_crtc_funcs {
|
|
|
81f5f8b |
/* cursor controls */
|
|
|
81f5f8b |
int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,
|
|
|
81f5f8b |
uint32_t handle, uint32_t width, uint32_t height);
|
|
|
81f5f8b |
+ int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv,
|
|
|
81f5f8b |
+ uint32_t handle, uint32_t width, uint32_t height,
|
|
|
81f5f8b |
+ int32_t hot_x, int32_t hot_y);
|
|
|
81f5f8b |
int (*cursor_move)(struct drm_crtc *crtc, int x, int y);
|
|
|
81f5f8b |
|
|
|
81f5f8b |
/* Set gamma on the CRTC */
|
|
|
81f5f8b |
@@ -1025,6 +1028,8 @@ extern int drm_mode_setplane(struct drm_device *dev,
|
|
|
81f5f8b |
void *data, struct drm_file *file_priv);
|
|
|
81f5f8b |
extern int drm_mode_cursor_ioctl(struct drm_device *dev,
|
|
|
81f5f8b |
void *data, struct drm_file *file_priv);
|
|
|
81f5f8b |
+extern int drm_mode_cursor2_ioctl(struct drm_device *dev,
|
|
|
81f5f8b |
+ void *data, struct drm_file *file_priv);
|
|
|
81f5f8b |
extern int drm_mode_addfb(struct drm_device *dev,
|
|
|
81f5f8b |
void *data, struct drm_file *file_priv);
|
|
|
81f5f8b |
extern int drm_mode_addfb2(struct drm_device *dev,
|
|
|
81f5f8b |
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
|
|
|
81f5f8b |
index 8d1e2bb..5182a2d 100644
|
|
|
81f5f8b |
--- a/include/uapi/drm/drm.h
|
|
|
81f5f8b |
+++ b/include/uapi/drm/drm.h
|
|
|
81f5f8b |
@@ -732,6 +732,7 @@ struct drm_prime_handle {
|
|
|
81f5f8b |
#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
|
|
|
81f5f8b |
#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
|
|
|
81f5f8b |
#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
|
|
|
81f5f8b |
+#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
|
|
|
81f5f8b |
|
|
|
81f5f8b |
/**
|
|
|
81f5f8b |
* Device specific ioctls should only be in their respective headers
|
|
|
81f5f8b |
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
|
|
|
81f5f8b |
index 3d6301b..ecde539 100644
|
|
|
81f5f8b |
--- a/include/uapi/drm/drm_mode.h
|
|
|
81f5f8b |
+++ b/include/uapi/drm/drm_mode.h
|
|
|
81f5f8b |
@@ -388,6 +388,19 @@ struct drm_mode_cursor {
|
|
|
81f5f8b |
__u32 handle;
|
|
|
81f5f8b |
};
|
|
|
81f5f8b |
|
|
|
81f5f8b |
+struct drm_mode_cursor2 {
|
|
|
81f5f8b |
+ __u32 flags;
|
|
|
81f5f8b |
+ __u32 crtc_id;
|
|
|
81f5f8b |
+ __s32 x;
|
|
|
81f5f8b |
+ __s32 y;
|
|
|
81f5f8b |
+ __u32 width;
|
|
|
81f5f8b |
+ __u32 height;
|
|
|
81f5f8b |
+ /* driver specific handle */
|
|
|
81f5f8b |
+ __u32 handle;
|
|
|
81f5f8b |
+ __s32 hot_x;
|
|
|
81f5f8b |
+ __s32 hot_y;
|
|
|
81f5f8b |
+};
|
|
|
81f5f8b |
+
|
|
|
81f5f8b |
struct drm_mode_crtc_lut {
|
|
|
81f5f8b |
__u32 crtc_id;
|
|
|
81f5f8b |
__u32 gamma_size;
|
|
|
81f5f8b |
--
|
|
|
81f5f8b |
1.8.3.1
|
|
|
81f5f8b |
|