mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
termios: stub
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _TERMIOS_H_INCLUDE
|
||||||
|
#define _TERMIOS_H_INCLUDE
|
||||||
|
|
||||||
|
typedef unsigned char cc_t;
|
||||||
|
typedef unsigned int speed_t;
|
||||||
|
typedef unsigned int tcflag_t;
|
||||||
|
#define NCCS 32
|
||||||
|
#define ECHO 0000010
|
||||||
|
#define ICANON 0000002
|
||||||
|
#define VMIN 6
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
tcflag_t c_iflag;
|
||||||
|
tcflag_t c_oflag;
|
||||||
|
tcflag_t c_cflag;
|
||||||
|
tcflag_t c_lflag;
|
||||||
|
cc_t c_line;
|
||||||
|
cc_t c_cc[NCCS];
|
||||||
|
speed_t ibaud;
|
||||||
|
speed_t obaud;
|
||||||
|
} termios;
|
||||||
|
|
||||||
|
#endif
|
||||||
+87
-30
@@ -7,12 +7,14 @@
|
|||||||
#include <ringbuffer.h>
|
#include <ringbuffer.h>
|
||||||
#include <arch/interrupt.h>
|
#include <arch/interrupt.h>
|
||||||
#include <arch/spinlock.h>
|
#include <arch/spinlock.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
static ringbuffer_t input;
|
static ringbuffer_t input;
|
||||||
static thread_t* thread;
|
static thread_t* thread;
|
||||||
static event_t outputevent;
|
static event_t outputevent;
|
||||||
static event_t inputevent;
|
static event_t inputevent;
|
||||||
static int outputlock;
|
static int outputlock;
|
||||||
|
static termios tty;
|
||||||
|
|
||||||
void console_write(char* str, size_t count){
|
void console_write(char* str, size_t count){
|
||||||
|
|
||||||
@@ -42,40 +44,58 @@ __attribute__((noreturn)) static void console_thread(){
|
|||||||
keyboard_getandwait(0, &packet);
|
keyboard_getandwait(0, &packet);
|
||||||
|
|
||||||
if(packet.ascii && (KBPACKET_FLAGS_RELEASED & packet.flags) == 0){
|
if(packet.ascii && (KBPACKET_FLAGS_RELEASED & packet.flags) == 0){
|
||||||
|
if(tty.c_lflag & ICANON){
|
||||||
bool flush = false;
|
bool flush = false;
|
||||||
|
|
||||||
switch(packet.ascii){
|
|
||||||
|
|
||||||
case '\b':
|
switch(packet.ascii){
|
||||||
if(buffpos){
|
|
||||||
--buffpos;
|
case '\b':
|
||||||
buff[buffpos] = '\0';
|
if(buffpos){
|
||||||
console_write(BACKSPACE_STR, strlen(BACKSPACE_STR));
|
--buffpos;
|
||||||
}
|
buff[buffpos] = '\0';
|
||||||
continue;
|
if(tty.c_lflag & ECHO)
|
||||||
case '\n':
|
console_write(BACKSPACE_STR, strlen(BACKSPACE_STR));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case '\n':
|
||||||
|
flush = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tty.c_lflag & ECHO)
|
||||||
|
console_write(&packet.ascii, 1);
|
||||||
|
|
||||||
|
buff[buffpos++] = packet.ascii;
|
||||||
|
|
||||||
|
if(buffpos == THREAD_BUFF_MAX)
|
||||||
flush = true;
|
flush = true;
|
||||||
break;
|
|
||||||
|
if(flush){
|
||||||
|
arch_interrupt_disable();
|
||||||
|
|
||||||
|
ringbuffer_write(&input, buff, buffpos);
|
||||||
|
|
||||||
|
arch_interrupt_enable();
|
||||||
|
|
||||||
|
buffpos = 0;
|
||||||
|
|
||||||
|
event_signal(&inputevent, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else{ // not canon
|
||||||
|
|
||||||
|
if(tty.c_lflag & ECHO)
|
||||||
|
console_write(&packet.ascii, 1);
|
||||||
|
|
||||||
console_write(&packet.ascii, 1);
|
|
||||||
|
|
||||||
buff[buffpos++] = packet.ascii;
|
|
||||||
|
|
||||||
if(buffpos == THREAD_BUFF_MAX)
|
|
||||||
flush = true;
|
|
||||||
|
|
||||||
if(flush){
|
|
||||||
arch_interrupt_disable();
|
arch_interrupt_disable();
|
||||||
|
|
||||||
ringbuffer_write(&input, buff, buffpos);
|
ringbuffer_write(&input, &packet.ascii, 1);
|
||||||
|
|
||||||
arch_interrupt_enable();
|
arch_interrupt_enable();
|
||||||
|
|
||||||
buffpos = 0;
|
|
||||||
|
|
||||||
event_signal(&inputevent, true);
|
event_signal(&inputevent, true);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,15 +112,16 @@ static int read(int *error, int dev, void* buff, size_t count, size_t offset){
|
|||||||
|
|
||||||
*error = 0;
|
*error = 0;
|
||||||
|
|
||||||
while(readc == 0){
|
while(readc < count && readc < tty.c_cc[VMIN]){
|
||||||
|
|
||||||
arch_interrupt_disable();
|
arch_interrupt_disable();
|
||||||
|
|
||||||
readc = ringbuffer_read(&input, buff, count);
|
readc += ringbuffer_read(&input, buff+readc, count-readc);
|
||||||
|
|
||||||
arch_interrupt_enable();
|
arch_interrupt_enable();
|
||||||
|
|
||||||
if(!readc) *error = event_wait(&inputevent, true);
|
if(readc < count && readc < tty.c_cc[VMIN])
|
||||||
|
*error = event_wait(&inputevent, true);
|
||||||
|
|
||||||
if(*error)
|
if(*error)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -125,8 +146,41 @@ static int isseekable(){
|
|||||||
return ESPIPE;
|
return ESPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TCGETS 0x5401
|
||||||
|
#define TCSETS 0x5402
|
||||||
|
#define TIOCGWINSZ 0x5413
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
unsigned short ws_row;
|
||||||
|
unsigned short ws_col;
|
||||||
|
unsigned short ws_xpixel;
|
||||||
|
unsigned short ws_ypixel;
|
||||||
|
} winsize;
|
||||||
|
|
||||||
|
static int ioctl(int minor, unsigned long req, void* arg){
|
||||||
|
switch(req){
|
||||||
|
case TIOCGWINSZ:
|
||||||
|
struct limine_terminal* ltty = liminetty_get(0);
|
||||||
|
winsize* w = arg;
|
||||||
|
w->ws_row = ltty->rows;
|
||||||
|
w->ws_col = ltty->columns;
|
||||||
|
break;
|
||||||
|
case TCGETS:
|
||||||
|
*(termios*)arg = tty;
|
||||||
|
break;
|
||||||
|
case TCSETS:
|
||||||
|
tty = *(termios*)arg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ENOTTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
devcalls calls = {
|
devcalls calls = {
|
||||||
read, write, isatty, isseekable
|
read, write, isatty, isseekable, ioctl
|
||||||
};
|
};
|
||||||
|
|
||||||
void consoledev_init(){
|
void consoledev_init(){
|
||||||
@@ -141,5 +195,8 @@ void consoledev_init(){
|
|||||||
|
|
||||||
if(!thread)
|
if(!thread)
|
||||||
_panic("Failed to initialise console thread", 0);
|
_panic("Failed to initialise console thread", 0);
|
||||||
|
|
||||||
|
tty.c_lflag = ECHO | ICANON;
|
||||||
|
tty.c_cc[VMIN] = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user