// SPDX-License-Identifier: GPL-2.0
/*
 * This module exports the functions:
 *
 *     'int set_selection_user(struct tiocl_selection __user *,
 *			       struct tty_struct *)'
 *     'int set_selection_kernel(struct tiocl_selection *, struct tty_struct *)'
 *     'void clear_selection(void)'
 *     'int paste_selection(struct tty_struct *)'
 *     'int sel_loadlut(char __user *)'
 *
 * Now that /dev/vcs exists, most of this can disappear again.
 */

#include <linux/module.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/types.h>

#include <linux/uaccess.h>

#include <linux/kbd_kern.h>
#include <linux/vt_kern.h>
#include <linux/consolemap.h>
#include <linux/selection.h>
#include <linux/tiocl.h>
#include <linux/console.h>
#include <linux/tty_flip.h>

#include <linux/sched/signal.h>

/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
#define is_space_on_vt(c)	((c) == ' ')

/* FIXME: all this needs locking */
static struct vc_selection {
	struct mutex lock;
	struct vc_data *cons;			/* must not be deallocated */
	char *buffer;
	unsigned int buf_len;
	volatile int start;			/* cleared by clear_selection */
	int end;
} vc_sel = {
	.lock = __MUTEX_INITIALIZER(vc_sel.lock),
	.start = -1,
};

/* clear_selection, highlight and highlight_pointer can be called
   from interrupt (via scrollback/front) */

/* set reverse video on characters s-e of console with selection. */
static inline void highlight(const int s, const int e)
{
	invert_screen(vc_sel.cons, s, e-s+2, true);
}

/* use complementary color to show the pointer */
static inline void highlight_pointer(const int where)
{
	complement_pos(vc_sel.cons, where);
}

static u32
sel_pos(int n, bool unicode)
{
	if (unicode)
		return screen_glyph_unicode(vc_sel.cons, n / 2);
	return inverse_translate(vc_sel.cons, screen_glyph(vc_sel.cons, n), 0);
}

/**
 *	clear_selection		-	remove current selection
 *
 *	Remove the current selection highlight, if any from the console
 *	holding the selection. The caller must hold the console lock.
 */
void clear_selection(void)
{
	highlight_pointer(-1); /* hide the pointer */
	if (vc_sel.start != -1) {
		highlight(vc_sel.start, vc_sel.end);
		vc_sel.start = -1;
	}
}
EXPORT_SYMBOL_GPL(clear_selection);

bool vc_is_sel(struct vc_data *vc)
{
	return vc == vc_sel.cons;
}

/*
 * User settable table: what characters are to be considered alphabetic?
 * 128 bits. Locked by the console lock.
 */
static u32 inwordLut[]={
  0x00000000, /* control chars     */
  0x03FFE000, /* digits and "-./"  */
  0x87FFFFFE, /* uppercase and '_' */
  0x07FFFFFE, /* lowercase         */
};

static inline int inword(const u32 c)
{
	return c > 0x7f || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
}

/**
 *	sel_loadlut()		-	load the LUT table
 *	@p: user table
 *
 *	Load the LUT table from user space. The caller must hold the console
 *	lock. Make a temporary copy so a partial update doesn't make a mess.
 */
int sel_loadlut(char __user *p)
{
	u32 tmplut[ARRAY_SIZE(inwordLut)];
	if (copy_from_user(tmplut, (u32 __user *)(p+4), sizeof(inwordLut)))
		return -EFAULT;
	memcpy(inwordLut, tmplut, sizeof(inwordLut));
	return 0;
}

/* does screen address p correspond to character at LH/RH edge of screen? */
static inline int atedge(const int p, int size_row)
{
	return (!(p % size_row)	|| !((p + 2) % size_row));
}

/* stores the char in UTF8 and returns the number of bytes used (1-4) */
static int store_utf8(u32 c, char *p)
{
	if (c < 0x80) {
		/*  0******* */
		p[0] = c;
		return 1;
	} else if (c < 0x800) {
		/* 110***** 10****** */
		p[0] = 0xc0 | (c >> 6);
		p[1] = 0x80 | (c & 0x3f);
		return 2;
	} else if (c < 0x10000) {
		/* 1110**** 10****** 10****** */
		p[0] = 0xe0 | (c >> 12);
		p[1] = 0x80 | ((c >> 6) & 0x3f);
		p[2] = 0x80 | (c & 0x3f);
		return 3;
	} else if (c < 0x110000) {
		/* 11110*** 10****** 10****** 10****** */
		p[0] = 0xf0 | (c >> 18);
		p[1] = 0x80 | ((c >> 12) & 0x3f);
		p[2] = 0x80 | ((c >> 6) & 0x3f);
		p[3] = 0x80 | (c & 0x3f);
		return 4;
	} else {
		/* outside Unicode, replace with U+FFFD */
		p[0] = 0xef;
		p[1] = 0xbf;
		p[2] = 0xbd;
		return 3;
	}
}

/**
 *	set_selection_user	-	set the current selection.
 *	@sel: user selection info
 *	@tty: the console tty
 *
 *	Invoked by the ioctl handle for the vt layer.
 *
 *	The entire selection process is managed under the console_lock. It's
 *	 a lot under the lock but its hardly a performance path
 */
int set_selection_user(const struct tiocl_selection __user *sel,
		       struct tty_struct *tty)
{
	struct tiocl_selection v;

	if (copy_from_user(&v, sel, sizeof(*sel)))
		return -EFAULT;

	return set_selection_kernel(&v, tty);
}

static int vc_selection_store_chars(struct vc_data *vc, bool unicode)
{
	char *bp, *obp;
	unsigned int i;

	/* Allocate a new buffer before freeing the old one ... */
	/* chars can take up to 4 bytes with unicode */
	bp = kmalloc_array((vc_sel.end - vc_sel.start) / 2 + 1, unicode ? 4 : 1,
			   GFP_KERNEL | __GFP_NOWARN);
	if (!bp) {
		printk(KERN_WARNING "selection: kmalloc() failed\n");
		clear_selection();
		return -ENOMEM;
	}
	kfree(vc_sel.buffer);
	vc_sel.buffer = bp;

	obp = bp;
	for (i = vc_sel.start; i <= vc_sel.end; i += 2) {
		u32 c = sel_pos(i, unicode);
		if (unicode)
			bp += store_utf8(c, bp);
		else
			*bp++ = c;
		if (!is_space_on_vt(c))
			obp = bp;
		if (!((i + 2) % vc->vc_size_row)) {
			/* strip trailing blanks from line and add newline,
			   unless non-space at end of line. */
			if (obp != bp) {
				bp = obp;
				*bp++ = '\r';
			}
			obp = bp;
		}
	}
	vc_sel.buf_len = bp - vc_sel.buffer;

	return 0;
}

static int vc_do_selection(struct vc_data *vc, unsigned short mode, int ps,
		int pe)
{
	int new_sel_start, new_sel_end, spc;
	bool unicode = vt_do_kdgkbmode(fg_console) == K_UNICODE;

	switch (mode) {
	case TIOCL_SELCHAR:	/* character-by-character selection */
		new_sel_start = ps;
		new_sel_end = pe;
		break;
	case TIOCL_SELWORD:	/* word-by-word selection */
		spc = is_space_on_vt(sel_pos(ps, unicode));
		for (new_sel_start = ps; ; ps -= 2) {
			if ((spc && !is_space_on_vt(sel_pos(ps, unicode))) ||
			    (!spc && !inword(sel_pos(ps, unicode))))
				break;
			new_sel_start = ps;
			if (!(ps % vc->vc_size_row))
				break;
		}

		spc = is_space_on_vt(sel_pos(pe, unicode));
		for (new_sel_end = pe; ; pe += 2) {
			if ((spc && !is_space_on_vt(sel_pos(pe, unicode))) ||
			    (!spc && !inword(sel_pos(pe, unicode))))
				break;
			new_sel_end = pe;
			if (!((pe + 2) % vc->vc_size_row))
				break;
		}
		break;
	case TIOCL_SELLINE:	/* line-by-line selection */
		new_sel_start = rounddown(ps, vc->vc_size_row);
		new_sel_end = rounddown(pe, vc->vc_size_row) +
			vc->vc_size_row - 2;
		break;
	case TIOCL_SELPOINTER:
		highlight_pointer(pe);
		return 0;
	default:
		return -EINVAL;
	}

	/* remove the pointer */
	highlight_pointer(-1);

	/* select to end of line if on trailing space */
	if (new_sel_end > new_sel_start &&
		!atedge(new_sel_end, vc->vc_size_row) &&
		is_space_on_vt(sel_pos(new_sel_end, unicode))) {
		for (pe = new_sel_end + 2; ; pe += 2)
			if (!is_space_on_vt(sel_pos(pe, unicode)) ||
			    atedge(pe, vc->vc_size_row))
				break;
		if (is_space_on_vt(sel_pos(pe, unicode)))
			new_sel_end = pe;
	}
	if (vc_sel.start == -1)	/* no current selection */
		highlight(new_sel_start, new_sel_end);
	else if (new_sel_start == vc_sel.start)
	{
		if (new_sel_end == vc_sel.end)	/* no action required */
			return 0;
		else if (new_sel_end > vc_sel.end)	/* extend to right */
			highlight(vc_sel.end + 2, new_sel_end);
		else				/* contract from right */
			highlight(new_sel_end + 2, vc_sel.end);
	}
	else if (new_sel_end == vc_sel.end)
	{
		if (new_sel_start < vc_sel.start) /* extend to left */
			highlight(new_sel_start, vc_sel.start - 2);
		else				/* contract from left */
			highlight(vc_sel.start, new_sel_start - 2);
	}
	else	/* some other case; start selection from scratch */
	{
		clear_selection();
		highlight(new_sel_start, new_sel_end);
	}
	vc_sel.start = new_sel_start;
	vc_sel.end = new_sel_end;

	return vc_selection_store_chars(vc, unicode);
}

static int vc_selection(struct vc_data *vc, struct tiocl_selection *v,
		struct tty_struct *tty)
{
	int ps, pe;

	poke_blanked_console();

	if (v->sel_mode == TIOCL_SELCLEAR) {
		/* useful for screendump without selection highlights */
		clear_selection();
		return 0;
	}

	v->xs = min_t(u16, v->xs - 1, vc->vc_cols - 1);
	v->ys = min_t(u16, v->ys - 1, vc->vc_rows - 1);
	v->xe = min_t(u16, v->xe - 1, vc->vc_cols - 1);
	v->ye = min_t(u16, v->ye - 1, vc->vc_rows - 1);

	if (mouse_reporting() && (v->sel_mode & TIOCL_SELMOUSEREPORT)) {
		mouse_report(tty, v->sel_mode & TIOCL_SELBUTTONMASK, v->xs,
			     v->ys);
		return 0;
	}

	ps = v->ys * vc->vc_size_row + (v->xs << 1);
	pe = v->ye * vc->vc_size_row + (v->xe << 1);
	if (ps > pe)	/* make vc_sel.start <= vc_sel.end */
		swap(ps, pe);

	if (vc_sel.cons != vc) {
		clear_selection();
		vc_sel.cons = vc;
	}

	return vc_do_selection(vc, v->sel_mode, ps, pe);
}

int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty)
{
	int ret;

	mutex_lock(&vc_sel.lock);
	console_lock();
	ret = vc_selection(vc_cons[fg_console].d, v, tty);
	console_unlock();
	mutex_unlock(&vc_sel.lock);

	return ret;
}
EXPORT_SYMBOL_GPL(set_selection_kernel);

/* Insert the contents of the selection buffer into the
 * queue of the tty associated with the current console.
 * Invoked by ioctl().
 *
 * Locking: called without locks. Calls the ldisc wrongly with
 * unsafe methods,
 */
int paste_selection(struct tty_struct *tty)
{
	struct vc_data *vc = tty->driver_data;
	int	pasted = 0;
	unsigned int count;
	struct  tty_ldisc *ld;
	DECLARE_WAITQUEUE(wait, current);
	int ret = 0;

	console_lock();
	poke_blanked_console();
	console_unlock();

	ld = tty_ldisc_ref_wait(tty);
	if (!ld)
		return -EIO;	/* ldisc was hung up */
	tty_buffer_lock_exclusive(&vc->port);

	add_wait_queue(&vc->paste_wait, &wait);
	mutex_lock(&vc_sel.lock);
	while (vc_sel.buffer && vc_sel.buf_len > pasted) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (signal_pending(current)) {
			ret = -EINTR;
			break;
		}
		if (tty_throttled(tty)) {
			mutex_unlock(&vc_sel.lock);
			schedule();
			mutex_lock(&vc_sel.lock);
			continue;
		}
		__set_current_state(TASK_RUNNING);
		count = vc_sel.buf_len - pasted;
		count = tty_ldisc_receive_buf(ld, vc_sel.buffer + pasted, NULL,
					      count);
		pasted += count;
	}
	mutex_unlock(&vc_sel.lock);
	remove_wait_queue(&vc->paste_wait, &wait);
	__set_current_state(TASK_RUNNING);

	tty_buffer_unlock_exclusive(&vc->port);
	tty_ldisc_deref(ld);
	return ret;
}
EXPORT_SYMBOL_GPL(paste_selection);
