2023-06-11 09:23:57 +01:00
|
|
|
#include <socks/tty.h>
|
2023-06-11 16:47:33 +01:00
|
|
|
#include <socks/input.h>
|
2023-06-11 09:23:57 +01:00
|
|
|
#include <socks/printk.h>
|
|
|
|
|
|
2023-06-11 14:54:39 +01:00
|
|
|
static void newline(struct device *tty)
|
2023-06-11 09:23:57 +01:00
|
|
|
{
|
|
|
|
|
struct tty_device *ttydev = TTY_DEVICE(tty);
|
|
|
|
|
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
|
|
|
|
|
struct tty_driver_ops *ops = tty_driver->tty_ops;
|
|
|
|
|
|
2023-06-11 14:54:39 +01:00
|
|
|
ttydev->tty_xcur = 0;
|
|
|
|
|
ttydev->tty_ycur++;
|
2023-06-11 09:23:57 +01:00
|
|
|
|
2023-06-11 14:54:39 +01:00
|
|
|
if (ttydev->tty_ycur >= ttydev->tty_ycells) {
|
|
|
|
|
ttydev->tty_xcur = 0;
|
|
|
|
|
ttydev->tty_ycur = ttydev->tty_ycells - 1;
|
|
|
|
|
|
|
|
|
|
if (ops->tty_scroll) {
|
|
|
|
|
ops->tty_scroll(tty, TTY_SCROLL_DOWN, 1);
|
|
|
|
|
}
|
2023-06-11 09:23:57 +01:00
|
|
|
}
|
|
|
|
|
|
2023-06-11 14:54:39 +01:00
|
|
|
ops->tty_move_cursor(tty, ttydev->tty_xcur, ttydev->tty_ycur);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __putchar(struct device *tty, int c)
|
|
|
|
|
{
|
|
|
|
|
struct tty_device *ttydev = TTY_DEVICE(tty);
|
|
|
|
|
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
|
|
|
|
|
struct tty_driver_ops *ops = tty_driver->tty_ops;
|
|
|
|
|
|
2023-06-11 09:23:57 +01:00
|
|
|
ops->tty_putc(tty, c, ttydev->tty_xcur, ttydev->tty_ycur, ttydev->tty_curattrib);
|
|
|
|
|
ttydev->tty_xcur++;
|
|
|
|
|
|
|
|
|
|
if (ttydev->tty_xcur >= ttydev->tty_xcells) {
|
|
|
|
|
ttydev->tty_xcur = 0;
|
|
|
|
|
ttydev->tty_ycur++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ttydev->tty_ycur >= ttydev->tty_ycells) {
|
2023-06-11 14:54:39 +01:00
|
|
|
ttydev->tty_xcur = 0;
|
|
|
|
|
ttydev->tty_ycur = ttydev->tty_ycells - 1;
|
|
|
|
|
|
2023-06-11 09:23:57 +01:00
|
|
|
if (ops->tty_scroll) {
|
|
|
|
|
ops->tty_scroll(tty, TTY_SCROLL_DOWN, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ops->tty_move_cursor(tty, ttydev->tty_xcur, ttydev->tty_ycur);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-11 14:54:39 +01:00
|
|
|
static void putchar(struct device *tty, int c)
|
|
|
|
|
{
|
|
|
|
|
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
|
|
|
|
|
struct tty_driver_ops *ops = tty_driver->tty_ops;
|
|
|
|
|
|
|
|
|
|
if (!ops->tty_putc) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tty_driver->tty_type == TTY_DRIVER_SIMPLE) {
|
|
|
|
|
ops->tty_putc(tty, c, -1, -1, 0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (c) {
|
|
|
|
|
case '\n':
|
|
|
|
|
newline(tty);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
__putchar(tty, c);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-11 09:23:57 +01:00
|
|
|
kern_status_t tty_read(struct device *tty, void *buf, size_t max, size_t *nr_read, socks_flags_t flags)
|
|
|
|
|
{
|
|
|
|
|
printk("tty_read");
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kern_status_t tty_write(struct device *tty, const void *buf, size_t len, size_t *nr_written, socks_flags_t flags)
|
|
|
|
|
{
|
|
|
|
|
size_t r = 0;
|
|
|
|
|
const char *s = buf;
|
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
|
|
|
putchar(tty, s[i]);
|
|
|
|
|
r++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*nr_written = r;
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|
2023-06-11 16:47:33 +01:00
|
|
|
|
|
|
|
|
static void process_events(struct device *tty)
|
|
|
|
|
{
|
|
|
|
|
struct tty_device *ttydev = TTY_DEVICE(tty);
|
|
|
|
|
|
|
|
|
|
if (!ttydev->tty_ldisc || !ttydev->tty_ldisc->process_events) {
|
|
|
|
|
struct input_event ev;
|
|
|
|
|
while (ringbuffer_unread(&ttydev->tty_events)) {
|
|
|
|
|
ringbuffer_read(&ttydev->tty_events, sizeof ev, &ev, S_NOBLOCK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ttydev->tty_ldisc->process_events(tty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kern_status_t tty_report_event(struct device *tty, const struct input_event *ev)
|
|
|
|
|
{
|
|
|
|
|
struct tty_device *ttydev = TTY_DEVICE(tty);
|
|
|
|
|
size_t w = ringbuffer_write(&ttydev->tty_events, sizeof *ev, ev, S_NOBLOCK);
|
|
|
|
|
|
|
|
|
|
if (w != sizeof *ev) {
|
|
|
|
|
return KERN_WOULD_BLOCK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ringbuffer_unread(&ttydev->tty_events) > 0) {
|
|
|
|
|
process_events(tty);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|