diff options
author | Jakob Bornecrantz <jakob@vmware.com> | 2010-04-25 16:49:03 +0100 |
---|---|---|
committer | Jakob Bornecrantz <jakob@vmware.com> | 2010-04-30 11:41:11 +0100 |
commit | 56892be8691b0fcf200fbf330d223d14ea0e951d (patch) | |
tree | bf241e477526be0f663ff0e84ec6f7bccdfba609 /vmwgfx_kms.c | |
parent | c77d43d797376bfc7daaaaf8929ba1b80ec0eeff (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.c | 44 |
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; +} |