/*
 * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */

FILE_LICENCE(GPL2_OR_LATER);

/** @file
 *
 * Linux console implementation.
 *
 */

#include <ipxe/console.h>

#include <ipxe/init.h>
#include <ipxe/keys.h>
#include <ipxe/linux_api.h>

#include <linux/termios.h>
#include <asm/errno.h>

#include <config/console.h>

/* Set default console usage if applicable */
#if ! ( defined ( CONSOLE_LINUX ) && CONSOLE_EXPLICIT ( CONSOLE_LINUX ) )
#undef CONSOLE_LINUX
#define CONSOLE_LINUX ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#endif

static void linux_console_putchar(int c)
{
	/* write to stdout */
	if (linux_write(1, &c, 1) != 1)
		DBG("linux_console write failed (%s)\n", linux_strerror(linux_errno));
}

static int linux_console_getchar()
{
	char c;

	/* read from stdin */
	if (linux_read(0, &c, 1) < 0) {
		DBG("linux_console read failed (%s)\n", linux_strerror(linux_errno));
		return 0;
	}
	/* backspace seems to be returned as ascii del, map it here */
	if (c == 0x7f)
		return KEY_BACKSPACE;
	else
		return c;
}

static int linux_console_iskey()
{
	struct pollfd pfd;
	pfd.fd = 0;
	pfd.events = POLLIN;

	/* poll for data to be read on stdin */
	if (linux_poll(&pfd, 1, 0) == -1) {
		DBG("linux_console poll failed (%s)\n", linux_strerror(linux_errno));
		return 0;
	}

	if (pfd.revents & POLLIN)
		return 1;
	else
		return 0;
}

struct console_driver linux_console __console_driver = {
	.disabled = 0,
	.putchar = linux_console_putchar,
	.getchar = linux_console_getchar,
	.iskey = linux_console_iskey,
	.usage = CONSOLE_LINUX,
};

static int linux_tcgetattr(int fd, struct termios *termios_p)
{
	return linux_ioctl(fd, TCGETS, termios_p);
}

static int linux_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
{
	unsigned long int cmd;

	switch (optional_actions)
	{
		case TCSANOW:
			cmd = TCSETS;
			break;
		case TCSADRAIN:
			cmd = TCSETSW;
			break;
		case TCSAFLUSH:
			cmd = TCSETSF;
			break;
		default:
			linux_errno = EINVAL;
			return -1;
	}

	return linux_ioctl(fd, cmd, termios_p);
}

/** Saved termios attributes */
static struct termios saved_termios;

/** Setup the terminal for our use */
static void linux_console_startup(void)
{
	struct termios t;

	if (linux_tcgetattr(0, &t)) {
		DBG("linux_console tcgetattr failed (%s)", linux_strerror(linux_errno));
		return;
	}

	saved_termios = t;

	/* Disable canonical mode and echo. Let readline handle that */
	t.c_lflag &= ~(ECHO | ICANON);
	/* stop ^C from sending a signal */
	t.c_cc[VINTR] = 0;

	if (linux_tcsetattr(0, TCSAFLUSH, &t))
		DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno));
}

/** Restores original terminal attributes on shutdown */
static void linux_console_shutdown(int flags __unused)
{
	if (linux_tcsetattr(0, TCSAFLUSH, &saved_termios))
		DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno));
}

struct startup_fn linux_console_startup_fn __startup_fn(STARTUP_EARLY) = {
	.name = "linux_console",
	.startup = linux_console_startup,
	.shutdown = linux_console_shutdown,
};
