// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Minimalistic braille device kernel support.
 *
 * By default, shows console messages on the braille device.
 * Pressing Insert switches to VC browsing.
 *
 *  Copyright (C) Samuel Thibault <samuel.thibault@ens-lyon.org>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/console.h>
#include <linux/notifier.h>

#include <linux/selection.h>
#include <linux/vt_kern.h>
#include <linux/consolemap.h>

#include <linux/keyboard.h>
#include <linux/kbd_kern.h>
#include <linux/input.h>

MODULE_AUTHOR("samuel.thibault@ens-lyon.org");
MODULE_DESCRIPTION("braille device");
MODULE_LICENSE("GPL");

/*
 * Braille device support part.
 */

/* Emit various sounds */
static bool sound;
module_param(sound, bool, 0);
MODULE_PARM_DESC(sound, "emit sounds");

static void beep(unsigned int freq)
{
	if (sound)
		kd_mksound(freq, HZ/10);
}

/* mini console */
#define WIDTH 40
#define BRAILLE_KEY KEY_INSERT
static u16 console_buf[WIDTH];
static int console_cursor;

/* mini view of VC */
static int vc_x, vc_y, lastvc_x, lastvc_y;

/* show console ? (or show VC) */
static int console_show = 1;
/* pending newline ? */
static int console_newline = 1;
static int lastVC = -1;

static struct console *braille_co;

/* Very VisioBraille-specific */
static void braille_write(u16 *buf)
{
	static u16 lastwrite[WIDTH];
	unsigned char data[1 + 1 + 2*WIDTH + 2 + 1], csum = 0, *c;
	u16 out;
	int i;

	if (!braille_co)
		return;

	if (!memcmp(lastwrite, buf, WIDTH * sizeof(*buf)))
		return;
	memcpy(lastwrite, buf, WIDTH * sizeof(*buf));

#define SOH 1
#define STX 2
#define ETX 2
#define EOT 4
#define ENQ 5
	data[0] = STX;
	data[1] = '>';
	csum ^= '>';
	c = &data[2];
	for (i = 0; i < WIDTH; i++) {
		out = buf[i];
		if (out >= 0x100)
			out = '?';
		else if (out == 0x00)
			out = ' ';
		csum ^= out;
		if (out <= 0x05) {
			*c++ = SOH;
			out |= 0x40;
		}
		*c++ = out;
	}

	if (csum <= 0x05) {
		*c++ = SOH;
		csum |= 0x40;
	}
	*c++ = csum;
	*c++ = ETX;

	braille_co->write(braille_co, data, c - data);
}

/* Follow the VC cursor*/
static void vc_follow_cursor(struct vc_data *vc)
{
	vc_x = vc->state.x - (vc->state.x % WIDTH);
	vc_y = vc->state.y;
	lastvc_x = vc->state.x;
	lastvc_y = vc->state.y;
}

/* Maybe the VC cursor moved, if so follow it */
static void vc_maybe_cursor_moved(struct vc_data *vc)
{
	if (vc->state.x != lastvc_x || vc->state.y != lastvc_y)
		vc_follow_cursor(vc);
}

/* Show portion of VC at vc_x, vc_y */
static void vc_refresh(struct vc_data *vc)
{
	u16 buf[WIDTH];
	int i;

	for (i = 0; i < WIDTH; i++) {
		u16 glyph = screen_glyph(vc,
				2 * (vc_x + i) + vc_y * vc->vc_size_row);
		buf[i] = inverse_translate(vc, glyph, 1);
	}
	braille_write(buf);
}

/*
 * Link to keyboard
 */

static int keyboard_notifier_call(struct notifier_block *blk,
				  unsigned long code, void *_param)
{
	struct keyboard_notifier_param *param = _param;
	struct vc_data *vc = param->vc;
	int ret = NOTIFY_OK;

	if (!param->down)
		return ret;

	switch (code) {
	case KBD_KEYCODE:
		if (console_show) {
			if (param->value == BRAILLE_KEY) {
				console_show = 0;
				beep(880);
				vc_maybe_cursor_moved(vc);
				vc_refresh(vc);
				ret = NOTIFY_STOP;
			}
		} else {
			ret = NOTIFY_STOP;
			switch (param->value) {
			case KEY_INSERT:
				beep(440);
				console_show = 1;
				lastVC = -1;
				braille_write(console_buf);
				break;
			case KEY_LEFT:
				if (vc_x > 0) {
					vc_x -= WIDTH;
					if (vc_x < 0)
						vc_x = 0;
				} else if (vc_y >= 1) {
					beep(880);
					vc_y--;
					vc_x = vc->vc_cols-WIDTH;
				} else
					beep(220);
				break;
			case KEY_RIGHT:
				if (vc_x + WIDTH < vc->vc_cols) {
					vc_x += WIDTH;
				} else if (vc_y + 1 < vc->vc_rows) {
					beep(880);
					vc_y++;
					vc_x = 0;
				} else
					beep(220);
				break;
			case KEY_DOWN:
				if (vc_y + 1 < vc->vc_rows)
					vc_y++;
				else
					beep(220);
				break;
			case KEY_UP:
				if (vc_y >= 1)
					vc_y--;
				else
					beep(220);
				break;
			case KEY_HOME:
				vc_follow_cursor(vc);
				break;
			case KEY_PAGEUP:
				vc_x = 0;
				vc_y = 0;
				break;
			case KEY_PAGEDOWN:
				vc_x = 0;
				vc_y = vc->vc_rows-1;
				break;
			default:
				ret = NOTIFY_OK;
				break;
			}
			if (ret == NOTIFY_STOP)
				vc_refresh(vc);
		}
		break;
	case KBD_POST_KEYSYM:
	{
		unsigned char type = KTYP(param->value) - 0xf0;

		if (type == KT_SPEC) {
			unsigned char val = KVAL(param->value);
			int on_off = -1;

			switch (val) {
			case KVAL(K_CAPS):
				on_off = vt_get_leds(fg_console, VC_CAPSLOCK);
				break;
			case KVAL(K_NUM):
				on_off = vt_get_leds(fg_console, VC_NUMLOCK);
				break;
			case KVAL(K_HOLD):
				on_off = vt_get_leds(fg_console, VC_SCROLLOCK);
				break;
			}
			if (on_off == 1)
				beep(880);
			else if (on_off == 0)
				beep(440);
		}
	}
		break;
	case KBD_UNBOUND_KEYCODE:
	case KBD_UNICODE:
	case KBD_KEYSYM:
		/* Unused */
		break;
	}
	return ret;
}

static struct notifier_block keyboard_notifier_block = {
	.notifier_call = keyboard_notifier_call,
};

static int vt_notifier_call(struct notifier_block *blk,
			    unsigned long code, void *_param)
{
	struct vt_notifier_param *param = _param;
	struct vc_data *vc = param->vc;

	switch (code) {
	case VT_ALLOCATE:
		break;
	case VT_DEALLOCATE:
		break;
	case VT_WRITE:
	{
		unsigned char c = param->c;

		if (vc->vc_num != fg_console)
			break;
		switch (c) {
		case '\b':
		case 127:
			if (console_cursor > 0) {
				console_cursor--;
				console_buf[console_cursor] = ' ';
			}
			break;
		case '\n':
		case '\v':
		case '\f':
		case '\r':
			console_newline = 1;
			break;
		case '\t':
			c = ' ';
			fallthrough;
		default:
			if (c < 32)
				/* Ignore other control sequences */
				break;
			if (console_newline) {
				memset(console_buf, 0, sizeof(console_buf));
				console_cursor = 0;
				console_newline = 0;
			}
			if (console_cursor == WIDTH)
				memmove(console_buf, &console_buf[1],
					(WIDTH-1) * sizeof(*console_buf));
			else
				console_cursor++;
			console_buf[console_cursor-1] = c;
			break;
		}
		if (console_show)
			braille_write(console_buf);
		else {
			vc_maybe_cursor_moved(vc);
			vc_refresh(vc);
		}
		break;
	}
	case VT_UPDATE:
		/* Maybe a VT switch, flush */
		if (console_show) {
			if (vc->vc_num != lastVC) {
				lastVC = vc->vc_num;
				memset(console_buf, 0, sizeof(console_buf));
				console_cursor = 0;
				braille_write(console_buf);
			}
		} else {
			vc_maybe_cursor_moved(vc);
			vc_refresh(vc);
		}
		break;
	}
	return NOTIFY_OK;
}

static struct notifier_block vt_notifier_block = {
	.notifier_call = vt_notifier_call,
};

/*
 * Called from printk.c when console=brl is given
 */

int braille_register_console(struct console *console, int index,
		char *console_options, char *braille_options)
{
	int ret;

	if (!console_options)
		/* Only support VisioBraille for now */
		console_options = "57600o8";
	if (braille_co)
		return -ENODEV;
	if (console->setup) {
		ret = console->setup(console, console_options);
		if (ret != 0)
			return ret;
	}
	console->flags |= CON_ENABLED;
	console->index = index;
	braille_co = console;
	register_keyboard_notifier(&keyboard_notifier_block);
	register_vt_notifier(&vt_notifier_block);
	return 1;
}

int braille_unregister_console(struct console *console)
{
	if (braille_co != console)
		return -EINVAL;
	unregister_keyboard_notifier(&keyboard_notifier_block);
	unregister_vt_notifier(&vt_notifier_block);
	braille_co = NULL;
	return 1;
}
