diff mbox

[1/2] drm: add hotspot support for cursors.

Message ID 1371692933-7379-1-git-send-email-airlied@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Airlie June 20, 2013, 1:48 a.m. UTC
From: Dave Airlie <airlied@redhat.com>

So it looks like for virtual hw cursors on QXL we need to inform
the "hw" device what the cursor hotspot parameters are. This
makes sense if you think the host has to draw the cursor and interpret
clicks from it. However the current modesetting interface doesn't support
passing the hotspot information from userspace.

This implements a new cursor ioctl, that takes the hotspot info as well,
userspace can try calling the new interface and if it -ENOSYS, can just
fallback to the old non-hotspot interface.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/drm_crtc.c  | 35 +++++++++++++++++++++++++++++------
 drivers/gpu/drm/drm_drv.c   |  1 +
 include/drm/drm_crtc.h      |  5 +++++
 include/uapi/drm/drm.h      |  1 +
 include/uapi/drm/drm_mode.h | 13 +++++++++++++
 5 files changed, 49 insertions(+), 6 deletions(-)

Comments

Daniel Vetter June 24, 2013, 7:22 a.m. UTC | #1
On Thu, Jun 20, 2013 at 11:48:52AM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied@redhat.com>
> 
> So it looks like for virtual hw cursors on QXL we need to inform
> the "hw" device what the cursor hotspot parameters are. This
> makes sense if you think the host has to draw the cursor and interpret
> clicks from it. However the current modesetting interface doesn't support
> passing the hotspot information from userspace.
> 
> This implements a new cursor ioctl, that takes the hotspot info as well,
> userspace can try calling the new interface and if it -ENOSYS, can just
> fallback to the old non-hotspot interface.

This needs to be updated since your patch implements the fallback to the
old interface transparently already. Otherwise looks sane.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> 
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
>  drivers/gpu/drm/drm_crtc.c  | 35 +++++++++++++++++++++++++++++------
>  drivers/gpu/drm/drm_drv.c   |  1 +
>  include/drm/drm_crtc.h      |  5 +++++
>  include/uapi/drm/drm.h      |  1 +
>  include/uapi/drm/drm_mode.h | 13 +++++++++++++
>  5 files changed, 49 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index e7e9242..cc9eada 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -2099,10 +2099,10 @@ out:
>  	return ret;
>  }
>  
> -int drm_mode_cursor_ioctl(struct drm_device *dev,
> -			void *data, struct drm_file *file_priv)
> +static int drm_mode_cursor_common(struct drm_device *dev,
> +				  struct drm_mode_cursor2 *req,
> +				  struct drm_file *file_priv)
>  {
> -	struct drm_mode_cursor *req = data;
>  	struct drm_mode_object *obj;
>  	struct drm_crtc *crtc;
>  	int ret = 0;
> @@ -2122,13 +2122,17 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
>  
>  	mutex_lock(&crtc->mutex);
>  	if (req->flags & DRM_MODE_CURSOR_BO) {
> -		if (!crtc->funcs->cursor_set) {
> +		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
>  			ret = -ENXIO;
>  			goto out;
>  		}
>  		/* Turns off the cursor if handle is 0 */
> -		ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
> -					      req->width, req->height);
> +		if (crtc->funcs->cursor_set2)
> +			ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
> +						      req->width, req->height, req->hot_x, req->hot_y);
> +		else
> +			ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
> +						      req->width, req->height);
>  	}
>  
>  	if (req->flags & DRM_MODE_CURSOR_MOVE) {
> @@ -2143,6 +2147,25 @@ out:
>  	mutex_unlock(&crtc->mutex);
>  
>  	return ret;
> +
> +}
> +int drm_mode_cursor_ioctl(struct drm_device *dev,
> +			void *data, struct drm_file *file_priv)
> +{
> +	struct drm_mode_cursor *req = data;
> +	struct drm_mode_cursor2 new_req;
> +
> +	memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
> +	new_req.hot_x = new_req.hot_y = 0;
> +
> +	return drm_mode_cursor_common(dev, &new_req, file_priv);
> +}
> +
> +int drm_mode_cursor2_ioctl(struct drm_device *dev,
> +			   void *data, struct drm_file *file_priv)
> +{
> +	struct drm_mode_cursor2 *req = data;
> +	return drm_mode_cursor_common(dev, req, file_priv);
>  }
>  
>  /* Original addfb only supported RGB formats, so figure out which one */
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 9cc247f..99fcd7c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -166,6 +166,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> +	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>  };
>  
>  #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index adb3f9b..093c030 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -339,6 +339,9 @@ struct drm_crtc_funcs {
>  	/* cursor controls */
>  	int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,
>  			  uint32_t handle, uint32_t width, uint32_t height);
> +	int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv,
> +			   uint32_t handle, uint32_t width, uint32_t height,
> +			   int32_t hot_x, int32_t hot_y);
>  	int (*cursor_move)(struct drm_crtc *crtc, int x, int y);
>  
>  	/* Set gamma on the CRTC */
> @@ -1022,6 +1025,8 @@ extern int drm_mode_setplane(struct drm_device *dev,
>  			       void *data, struct drm_file *file_priv);
>  extern int drm_mode_cursor_ioctl(struct drm_device *dev,
>  				void *data, struct drm_file *file_priv);
> +extern int drm_mode_cursor2_ioctl(struct drm_device *dev,
> +				void *data, struct drm_file *file_priv);
>  extern int drm_mode_addfb(struct drm_device *dev,
>  			  void *data, struct drm_file *file_priv);
>  extern int drm_mode_addfb2(struct drm_device *dev,
> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> index 5a57be6..238a166 100644
> --- a/include/uapi/drm/drm.h
> +++ b/include/uapi/drm/drm.h
> @@ -732,6 +732,7 @@ struct drm_prime_handle {
>  #define DRM_IOCTL_MODE_ADDFB2		DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
>  #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES	DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
>  #define DRM_IOCTL_MODE_OBJ_SETPROPERTY	DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
> +#define DRM_IOCTL_MODE_CURSOR2		DRM_IOWR(0xBB, struct drm_mode_cursor2)
>  
>  /**
>   * Device specific ioctls should only be in their respective headers
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 090e533..53db7ce 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -388,6 +388,19 @@ struct drm_mode_cursor {
>  	__u32 handle;
>  };
>  
> +struct drm_mode_cursor2 {
> +	__u32 flags;
> +	__u32 crtc_id;
> +	__s32 x;
> +	__s32 y;
> +	__u32 width;
> +	__u32 height;
> +	/* driver specific handle */
> +	__u32 handle;
> +	__s32 hot_x;
> +	__s32 hot_y;
> +};
> +
>  struct drm_mode_crtc_lut {
>  	__u32 crtc_id;
>  	__u32 gamma_size;
> -- 
> 1.8.2.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e7e9242..cc9eada 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2099,10 +2099,10 @@  out:
 	return ret;
 }
 
-int drm_mode_cursor_ioctl(struct drm_device *dev,
-			void *data, struct drm_file *file_priv)
+static int drm_mode_cursor_common(struct drm_device *dev,
+				  struct drm_mode_cursor2 *req,
+				  struct drm_file *file_priv)
 {
-	struct drm_mode_cursor *req = data;
 	struct drm_mode_object *obj;
 	struct drm_crtc *crtc;
 	int ret = 0;
@@ -2122,13 +2122,17 @@  int drm_mode_cursor_ioctl(struct drm_device *dev,
 
 	mutex_lock(&crtc->mutex);
 	if (req->flags & DRM_MODE_CURSOR_BO) {
-		if (!crtc->funcs->cursor_set) {
+		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
 			ret = -ENXIO;
 			goto out;
 		}
 		/* Turns off the cursor if handle is 0 */
-		ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
-					      req->width, req->height);
+		if (crtc->funcs->cursor_set2)
+			ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
+						      req->width, req->height, req->hot_x, req->hot_y);
+		else
+			ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
+						      req->width, req->height);
 	}
 
 	if (req->flags & DRM_MODE_CURSOR_MOVE) {
@@ -2143,6 +2147,25 @@  out:
 	mutex_unlock(&crtc->mutex);
 
 	return ret;
+
+}
+int drm_mode_cursor_ioctl(struct drm_device *dev,
+			void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_cursor *req = data;
+	struct drm_mode_cursor2 new_req;
+
+	memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
+	new_req.hot_x = new_req.hot_y = 0;
+
+	return drm_mode_cursor_common(dev, &new_req, file_priv);
+}
+
+int drm_mode_cursor2_ioctl(struct drm_device *dev,
+			   void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_cursor2 *req = data;
+	return drm_mode_cursor_common(dev, req, file_priv);
 }
 
 /* Original addfb only supported RGB formats, so figure out which one */
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9cc247f..99fcd7c 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -166,6 +166,7 @@  static const struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index adb3f9b..093c030 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -339,6 +339,9 @@  struct drm_crtc_funcs {
 	/* cursor controls */
 	int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,
 			  uint32_t handle, uint32_t width, uint32_t height);
+	int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv,
+			   uint32_t handle, uint32_t width, uint32_t height,
+			   int32_t hot_x, int32_t hot_y);
 	int (*cursor_move)(struct drm_crtc *crtc, int x, int y);
 
 	/* Set gamma on the CRTC */
@@ -1022,6 +1025,8 @@  extern int drm_mode_setplane(struct drm_device *dev,
 			       void *data, struct drm_file *file_priv);
 extern int drm_mode_cursor_ioctl(struct drm_device *dev,
 				void *data, struct drm_file *file_priv);
+extern int drm_mode_cursor2_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *file_priv);
 extern int drm_mode_addfb(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv);
 extern int drm_mode_addfb2(struct drm_device *dev,
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 5a57be6..238a166 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -732,6 +732,7 @@  struct drm_prime_handle {
 #define DRM_IOCTL_MODE_ADDFB2		DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
 #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES	DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
 #define DRM_IOCTL_MODE_OBJ_SETPROPERTY	DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
+#define DRM_IOCTL_MODE_CURSOR2		DRM_IOWR(0xBB, struct drm_mode_cursor2)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 090e533..53db7ce 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -388,6 +388,19 @@  struct drm_mode_cursor {
 	__u32 handle;
 };
 
+struct drm_mode_cursor2 {
+	__u32 flags;
+	__u32 crtc_id;
+	__s32 x;
+	__s32 y;
+	__u32 width;
+	__u32 height;
+	/* driver specific handle */
+	__u32 handle;
+	__s32 hot_x;
+	__s32 hot_y;
+};
+
 struct drm_mode_crtc_lut {
 	__u32 crtc_id;
 	__u32 gamma_size;