+/**
+ * @file lxconsole.c
+ * @author Lunaixsky (lunaxisky@qq.com)
+ * @brief Provides simple terminal support
+ * @version 0.1
+ * @date 2023-06-18
+ *
+ * @copyright Copyright (c) 2023
+ *
+ */
+
#include <klibc/string.h>
#include <lunaix/device.h>
#include <lunaix/input.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/sched.h>
+#include <lunaix/signal.h>
#include <lunaix/tty/console.h>
#include <lunaix/tty/tty.h>
-#include <lunaix/lxsignal.h>
-
static struct console lx_console;
int
int
__tty_read(struct device* dev, void* buf, size_t offset, size_t len);
+void
+console_write(struct console* console, u8_t* data, size_t size);
+
void
console_flush();
static volatile pid_t fg_pgid = 0;
-inline void
+static inline void
print_control_code(const char cntrl)
{
console_write_char('^');
int
__lxconsole_listener(struct input_device* dev)
{
- uint32_t key = dev->current_pkt.sys_code;
- uint32_t type = dev->current_pkt.pkt_type;
+ u32_t key = dev->current_pkt.sys_code;
+ u32_t type = dev->current_pkt.pkt_type;
kbd_kstate_t state = key >> 16;
ttychr = key & 0xff;
key = key & 0xffff;
}
int
-__tty_exec_cmd(struct device* dev, uint32_t req, va_list args)
+__tty_exec_cmd(struct device* dev, u32_t req, va_list args)
{
switch (req) {
case TIOCGPGRP:
fifo_init(&lx_console.input, valloc(4096), 4096, 0);
lx_console.flush_timer = NULL;
+}
- struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
- tty_dev->write = __tty_write;
- tty_dev->read = __tty_read;
- tty_dev->exec_cmd = __tty_exec_cmd;
+int
+__tty_write_pg(struct device* dev, void* buf, size_t offset)
+{
+ return __tty_write(dev, buf, offset, PG_SIZE);
+}
- waitq_init(&lx_reader);
- input_add_listener(__lxconsole_listener);
+int
+__tty_read_pg(struct device* dev, void* buf, size_t offset)
+{
+ return __tty_read(dev, buf, offset, PG_SIZE);
}
int
{
struct console* console = (struct console*)dev->underlay;
console_write(console, buf, len);
+
+ return len;
}
int
break;
}
}
+
return count + fifo_read(&console->input, buf + count, len - count);
}
}
void
-console_write(struct console* console, uint8_t* data, size_t size)
+console_write(struct console* console, u8_t* data, size_t size)
{
struct fifo_buf* fbuf = &console->output;
mutex_lock(&console->output.lock);
fifo_set_rdptr(fbuf, console->wnd_start);
- uint8_t* buffer = fbuf->data;
- uintptr_t ptr = fbuf->wr_pos;
- uintptr_t rd_ptr = fbuf->rd_pos;
+ u8_t* buffer = fbuf->data;
+ ptr_t ptr = fbuf->wr_pos;
+ ptr_t rd_ptr = fbuf->rd_pos;
char c;
for (size_t i = 0; i < size; i++) {
console->wnd_start = rd_ptr;
fbuf->flags |= FIFO_DIRTY;
mutex_unlock(&fbuf->lock);
+
+ if (!lx_console.flush_timer) {
+ console_flush();
+ }
}
void
console_write_str(char* str)
{
- console_write(&lx_console, str, strlen(str));
+ console_write(&lx_console, (u8_t*)str, strlen(str));
}
void
console_write_char(char str)
{
- console_write(&lx_console, &str, 1);
+ console_write(&lx_console, (u8_t*)&str, 1);
}
void
struct lx_timer* timer =
timer_run_ms(20, console_flush, NULL, TIMER_MODE_PERIODIC);
lx_console.flush_timer = timer;
-}
\ No newline at end of file
+}
+
+static int
+lxconsole_spawn_ttydev(struct device_def* devdef)
+{
+ struct device* tty_dev = device_allocseq(NULL, &lx_console);
+ tty_dev->ops.write = __tty_write;
+ tty_dev->ops.write_page = __tty_write_pg;
+ tty_dev->ops.read = __tty_read;
+ tty_dev->ops.read_page = __tty_read_pg;
+ tty_dev->ops.exec_cmd = __tty_exec_cmd;
+
+ waitq_init(&lx_reader);
+ input_add_listener(__lxconsole_listener);
+
+ device_register(tty_dev, &devdef->class, "tty");
+
+ return 0;
+}
+
+static struct device_def lxconsole_def = {
+ .name = "Lunaix Virtual Console",
+ .class = DEVCLASSV(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 12),
+ .init = lxconsole_spawn_ttydev
+};
+EXPORT_DEVICE(lxconsole, &lxconsole_def, load_earlystage);
\ No newline at end of file