// 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");

/*
 * 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, true);
	}
	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;
}
