FOC/L4RE: Upstream revision 40
This commit is contained in:
236
kernel/fiasco/src/kern/vkey.cpp
Normal file
236
kernel/fiasco/src/kern/vkey.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
INTERFACE:
|
||||
|
||||
class Irq_base;
|
||||
|
||||
class Vkey
|
||||
{
|
||||
public:
|
||||
enum Echo_type { Echo_off = 0, Echo_on = 1, Echo_crnl = 2 };
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
IMPLEMENTATION:
|
||||
|
||||
#include "irq_chip.h"
|
||||
|
||||
static Irq_base *vkey_irq;
|
||||
|
||||
PUBLIC static
|
||||
void
|
||||
Vkey::irq(Irq_base *i)
|
||||
{ vkey_irq = i; }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
IMPLEMENTATION [debug && serial && !ux]:
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "globals.h"
|
||||
#include "kernel_console.h"
|
||||
#include "keycodes.h"
|
||||
#include "uart.h"
|
||||
|
||||
static Vkey::Echo_type vkey_echo;
|
||||
static char vkey_buffer[256];
|
||||
static unsigned vkey_tail, vkey_head;
|
||||
static Console *uart = Kconsole::console()->find_console(Console::UART);
|
||||
|
||||
PUBLIC static
|
||||
void
|
||||
Vkey::set_echo(Echo_type echo)
|
||||
{
|
||||
vkey_echo = echo;
|
||||
}
|
||||
|
||||
PRIVATE static
|
||||
bool
|
||||
Vkey::add(int c)
|
||||
{
|
||||
bool hit = false;
|
||||
unsigned nh = (vkey_head + 1) % sizeof(vkey_buffer);
|
||||
unsigned oh = vkey_head;
|
||||
if (nh != vkey_tail)
|
||||
{
|
||||
vkey_buffer[vkey_head] = c;
|
||||
vkey_head = nh;
|
||||
}
|
||||
|
||||
if (oh == vkey_tail)
|
||||
hit = true;
|
||||
|
||||
if (vkey_echo == Vkey::Echo_crnl && c == '\r')
|
||||
c = '\n';
|
||||
|
||||
if (vkey_echo)
|
||||
putchar(c);
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
PRIVATE static
|
||||
bool
|
||||
Vkey::add(const char *seq)
|
||||
{
|
||||
bool hit = false;
|
||||
for (; *seq; ++seq)
|
||||
hit |= add(*seq);
|
||||
return hit;
|
||||
}
|
||||
|
||||
PRIVATE static
|
||||
void
|
||||
Vkey::trigger()
|
||||
{
|
||||
if (vkey_irq)
|
||||
vkey_irq->hit(0);
|
||||
}
|
||||
|
||||
PUBLIC static
|
||||
void
|
||||
Vkey::add_char(int v)
|
||||
{
|
||||
if (add(v))
|
||||
trigger();
|
||||
}
|
||||
|
||||
PUBLIC static
|
||||
int
|
||||
Vkey::check_()
|
||||
{
|
||||
if (!uart)
|
||||
return 1;
|
||||
|
||||
int ret = 1;
|
||||
bool hit = false;
|
||||
|
||||
// disable last branch recording, branch trace recording ...
|
||||
Cpu::cpus.cpu(current_cpu()).debugctl_disable();
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c = uart->getchar(false);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
if (c == KEY_ESC)
|
||||
{
|
||||
ret = 0; // break into kernel debugger
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case KEY_CURSOR_UP: hit |= add("\033[A"); break;
|
||||
case KEY_CURSOR_DOWN: hit |= add("\033[B"); break;
|
||||
case KEY_CURSOR_LEFT: hit |= add("\033[D"); break;
|
||||
case KEY_CURSOR_RIGHT: hit |= add("\033[C"); break;
|
||||
case KEY_CURSOR_HOME: hit |= add("\033[1~"); break;
|
||||
case KEY_CURSOR_END: hit |= add("\033[4~"); break;
|
||||
case KEY_PAGE_UP: hit |= add("\033[5~"); break;
|
||||
case KEY_PAGE_DOWN: hit |= add("\033[6~"); break;
|
||||
case KEY_INSERT: hit |= add("\033[2~"); break;
|
||||
case KEY_DELETE: hit |= add("\033[3~"); break;
|
||||
case KEY_F1: hit |= add("\033OP"); break;
|
||||
case KEY_BACKSPACE: hit |= add(127); break;
|
||||
case KEY_TAB: hit |= add(9); break;
|
||||
case KEY_ESC: hit |= add(27); break;
|
||||
case KEY_RETURN: hit |= add(13); break;
|
||||
default: hit |= add(c); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hit)
|
||||
trigger();
|
||||
|
||||
// Hmmm, we assume that a console with the UART flag set is of type Uart
|
||||
if (Config::serial_esc == Config::SERIAL_ESC_IRQ)
|
||||
static_cast<Uart*>(uart)->enable_rcv_irq();
|
||||
|
||||
// reenable debug stuff (undo debugctl_disable)
|
||||
Cpu::cpus.cpu(current_cpu()).debugctl_enable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PUBLIC static
|
||||
int
|
||||
Vkey::get()
|
||||
{
|
||||
if (vkey_tail != vkey_head)
|
||||
return vkey_buffer[vkey_tail];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
PUBLIC static
|
||||
void
|
||||
Vkey::clear()
|
||||
{
|
||||
if (vkey_tail != vkey_head)
|
||||
vkey_tail = (vkey_tail + 1) % sizeof(vkey_buffer);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IMPLEMENTATION [!debug || !serial || ux]:
|
||||
|
||||
PUBLIC static inline
|
||||
void
|
||||
Vkey::set_echo(Echo_type)
|
||||
{}
|
||||
|
||||
PUBLIC static inline
|
||||
void
|
||||
Vkey::clear()
|
||||
{}
|
||||
|
||||
PUBLIC static inline
|
||||
void
|
||||
Vkey::add_char(int)
|
||||
{}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IMPLEMENTATION [debug && (!serial || ux)]:
|
||||
|
||||
#include "kernel_console.h"
|
||||
|
||||
PUBLIC static
|
||||
int
|
||||
Vkey::get()
|
||||
{
|
||||
return Kconsole::console()->getchar(0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IMPLEMENTATION [!debug && serial]:
|
||||
|
||||
#include "kernel_console.h"
|
||||
#include "kernel_uart.h"
|
||||
|
||||
static Console *uart = Kconsole::console()->find_console(Console::UART);
|
||||
|
||||
PUBLIC static
|
||||
int
|
||||
Vkey::get()
|
||||
{
|
||||
return uart->getchar(false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IMPLEMENTATION[!debug && !serial]:
|
||||
|
||||
PUBLIC static
|
||||
int
|
||||
Vkey::get()
|
||||
{ return -1; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IMPLEMENTATION[!debug || !serial]:
|
||||
|
||||
PUBLIC static inline
|
||||
int
|
||||
Vkey::check_(int = -1)
|
||||
{ return 0; }
|
||||
Reference in New Issue
Block a user