Commit 94d705bb authored by Siarhei Siamashka's avatar Siarhei Siamashka Committed by popcornmix
Browse files

fbdev: add FBIOCOPYAREA ioctl

Based on the patch authored by Ali Gholami Rudi at
    https://lkml.org/lkml/2009/7/13/153



Provide an ioctl for userspace applications, but only if this operation
is hardware accelerated (otherwide it does not make any sense).

Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
parent 403914d8
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -1083,6 +1083,25 @@ fb_blank(struct fb_info *info, int blank)
}
EXPORT_SYMBOL(fb_blank);

static int fb_copyarea_user(struct fb_info *info,
			    struct fb_copyarea *copy)
{
	int ret = 0;
	if (!lock_fb_info(info))
		return -ENODEV;
	if (copy->dx + copy->width > info->var.xres ||
	    copy->sx + copy->width > info->var.xres ||
	    copy->dy + copy->height > info->var.yres ||
	    copy->sy + copy->height > info->var.yres) {
		ret = -EINVAL;
		goto out;
	}
	info->fbops->fb_copyarea(info, copy);
out:
	unlock_fb_info(info);
	return ret;
}

static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
			unsigned long arg)
{
@@ -1093,6 +1112,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
	struct fb_cmap cmap_from;
	struct fb_cmap_user cmap;
	struct fb_event event;
	struct fb_copyarea copy;
	void __user *argp = (void __user *)arg;
	long ret = 0;

@@ -1210,6 +1230,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
		unlock_fb_info(info);
		console_unlock();
		break;
	case FBIOCOPYAREA:
		if (info->flags & FBINFO_HWACCEL_COPYAREA) {
			/* only provide this ioctl if it is accelerated */
			if (copy_from_user(&copy, argp, sizeof(copy)))
				return -EFAULT;
			ret = fb_copyarea_user(info, &copy);
			break;
		}
		/* fall through */
	default:
		if (!lock_fb_info(info))
			return -ENODEV;
@@ -1364,6 +1393,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
	case FBIOPAN_DISPLAY:
	case FBIOGET_CON2FBMAP:
	case FBIOPUT_CON2FBMAP:
	case FBIOCOPYAREA:
		arg = (unsigned long) compat_ptr(arg);
	case FBIOBLANK:
		ret = do_fb_ioctl(info, cmd, arg);
+5 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@
#define FBIOPUT_MODEINFO        0x4617
#define FBIOGET_DISPINFO        0x4618
#define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
/*
 * HACK: use 'z' in order not to clash with any other ioctl numbers which might
 * be concurrently added to the mainline kernel
 */
#define FBIOCOPYAREA		_IOW('z', 0x21, struct fb_copyarea)

#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
#define FB_TYPE_PLANES			1	/* Non interleaved planes */