summaryrefslogtreecommitdiff
path: root/vmwgfx_kms.c
diff options
context:
space:
mode:
authorJakob Bornecrantz <jakob@vmware.com>2010-04-25 16:49:03 +0100
committerJakob Bornecrantz <jakob@vmware.com>2010-04-30 11:41:11 +0100
commit56892be8691b0fcf200fbf330d223d14ea0e951d (patch)
treebf241e477526be0f663ff0e84ec6f7bccdfba609 /vmwgfx_kms.c
parentc77d43d797376bfc7daaaaf8929ba1b80ec0eeff (diff)
vmwgfx: Allow userspace to change default layout
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Diffstat (limited to 'vmwgfx_kms.c')
-rw-r--r--vmwgfx_kms.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/vmwgfx_kms.c b/vmwgfx_kms.c
index 9c8ae15..b7606ff 100644
--- a/vmwgfx_kms.c
+++ b/vmwgfx_kms.c
@@ -904,3 +904,47 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
return 0;
}
+
+int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct vmw_private *dev_priv = vmw_priv(dev);
+ struct drm_vmw_update_layout_arg *arg = (struct drm_vmw_update_layout_arg *)data;
+ struct vmw_master *vmaster = vmw_master(file_priv->master);
+ void __user *user_rects;
+ struct drm_vmw_rect *rects;
+ unsigned rects_size;
+ int ret;
+
+ ret = ttm_read_lock(&vmaster->lock, true);
+ if (unlikely(ret != 0))
+ return ret;
+
+ if (!arg->num_outputs) {
+ struct drm_vmw_rect def_rect = {0, 0, 800, 600};
+ vmw_kms_ldu_update_layout(dev_priv, 1, &def_rect);
+ goto out_unlock;
+ }
+
+ rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
+ rects = kzalloc(rects_size, GFP_KERNEL);
+ if (unlikely(!rects)) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+
+ user_rects = (void __user *)(unsigned long)arg->rects;
+ ret = copy_from_user(rects, user_rects, rects_size);
+ if (unlikely(ret != 0)) {
+ DRM_ERROR("Failed to get rects.\n");
+ goto out_free;
+ }
+
+ vmw_kms_ldu_update_layout(dev_priv, arg->num_outputs, rects);
+
+out_free:
+ kfree(rects);
+out_unlock:
+ ttm_read_unlock(&vmaster->lock);
+ return ret;
+}