mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Refactored the kernel keyboard API, but kept system calls compatible.
Caps lock now works as caps lock, not as shift lock. This new design will allow implementing a working tty, such that stdin is the only way to access the keyboard, instead of the current hacky way of using a special system call to read from the keyboard. Added a new system header file <sys/keycodes.h> defining the constants for every key on the keyboard. This will be used in future APIs. The main change is to split the keyboard driver into a class that reads from the keyboard, while another class handles the translation into printable characters (if possible). This allows a terminal driver based on logical key presses and printable characters, instead of a terminal driver based only on unicode-ish codes.
This commit is contained in:
parent
16dd39e467
commit
ead0e1523f
13 changed files with 909 additions and 711 deletions
|
@ -50,6 +50,7 @@ c/h/string.h \
|
|||
c/h/errno.h \
|
||||
c/h/error.h \
|
||||
c/h/dirent.h \
|
||||
c/h/sys/keycodes.h \
|
||||
c/h/sys/readdirents.h \
|
||||
c/h/sys/stat.h \
|
||||
c/h/sys/types.h \
|
||||
|
|
32
libmaxsi/c/hsrc/sys/keycodes.h
Normal file
32
libmaxsi/c/hsrc/sys/keycodes.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
keycodes.h
|
||||
Defines codes for every logical key on keyboards.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _SYS_KEYCODES_H
|
||||
#define _SYS_KEYCODES_H 1
|
||||
|
||||
#include <features.h>
|
||||
#include <sortix/keycodes.h>
|
||||
|
||||
#endif
|
||||
|
|
@ -42,7 +42,7 @@ ifdef X86FAMILY
|
|||
CPUFLAGS:=$(CPUFLAGS) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
|
||||
endif
|
||||
|
||||
DIRS=. x64 x86 x86-family fs
|
||||
DIRS=. x64 x86 x86-family fs kb kb/layout
|
||||
|
||||
DEFINES:=-DSORTIX_KERNEL $(CPUDEFINES)
|
||||
ifeq ($(JSSORTIX),1)
|
||||
|
@ -69,6 +69,9 @@ log.o \
|
|||
utf8.o \
|
||||
panic.o \
|
||||
keyboard.o \
|
||||
kbapiadapter.o \
|
||||
kb/ps2.o \
|
||||
kb/layout/us.o \
|
||||
scheduler.o \
|
||||
syscall.o \
|
||||
sound.o \
|
||||
|
|
153
sortix/kb/layout/us.cpp
Normal file
153
sortix/kb/layout/us.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ks/layout/us.cpp
|
||||
The United States keyboard layout.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "../../platform.h"
|
||||
#include "../../keyboard.h"
|
||||
#include "../../keycodes.h"
|
||||
#include "us.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
const unsigned MOD_LSHIFT = (1U<<0U);
|
||||
const unsigned MOD_CAPS = (1U<<1U);
|
||||
|
||||
const uint32_t LAYOUT_US[4UL*128UL] =
|
||||
{
|
||||
0, 0, 0, 0, /* unused: kbkey 0 is invalid */
|
||||
0, 0, 0, 0, /* KBKEY_ESC */
|
||||
'1', '!', '1', '!',
|
||||
'2', '@', '2', '@',
|
||||
'3', '#', '3', '#',
|
||||
'4', '$', '4', '$',
|
||||
'5', '%', '5', '%',
|
||||
'6', '^', '6', '^',
|
||||
'7', '&', '7', '&',
|
||||
'8', '*', '8', '*',
|
||||
'9', '(', '9', '(',
|
||||
'0', ')', '0', ')',
|
||||
'-', '_', '-', '_',
|
||||
'=', '+', '=', '+',
|
||||
'\b', '\b', '\b', '\b',
|
||||
'\t', '\t', '\t', '\t',
|
||||
'q', 'Q', 'Q', 'q',
|
||||
'w', 'W', 'W', 'w',
|
||||
'e', 'E', 'E', 'e',
|
||||
'r', 'R', 'R', 'r',
|
||||
't', 'T', 'T', 't',
|
||||
'y', 'Y', 'Y', 'y',
|
||||
'u', 'U', 'U', 'u',
|
||||
'i', 'I', 'I', 'i',
|
||||
'o', 'O', 'O', 'o',
|
||||
'p', 'P', 'P', 'p',
|
||||
'[', '{', '[', '{',
|
||||
']', '}', ']', '}',
|
||||
'\n', '\n', '\n', '\n',
|
||||
0, 0, 0, 0, /* KBKEY_LCTRL */
|
||||
'a', 'A', 'A', 'a',
|
||||
's', 'S', 'S', 's',
|
||||
'd', 'D', 'D', 'd',
|
||||
'f', 'F', 'F', 'f',
|
||||
'g', 'G', 'G', 'g',
|
||||
'h', 'H', 'H', 'h',
|
||||
'j', 'J', 'J', 'j',
|
||||
'k', 'K', 'K', 'k',
|
||||
'l', 'L', 'L', 'l',
|
||||
';', ':', ';', ':',
|
||||
':', '"', ':', '"',
|
||||
'`', '~', '`', '~',
|
||||
0, 0, 0, 0, /* KBKEY_LSHIFT */
|
||||
'\\', '|', '\\', '|',
|
||||
'z', 'Z', 'Z', 'z',
|
||||
'x', 'X', 'X', 'x',
|
||||
'c', 'C', 'C', 'c',
|
||||
'v', 'V', 'V', 'v',
|
||||
'b', 'B', 'B', 'b',
|
||||
'n', 'N', 'N', 'n',
|
||||
'm', 'M', 'M', 'm',
|
||||
',', '<', ',', '<',
|
||||
'.', '>', '.', '>',
|
||||
'/', '?', '/', '?',
|
||||
0, 0, 0, 0, /* KBKEY_RSHIFT */
|
||||
'*', '*', '*', '*',
|
||||
0, 0, 0, 0, /* KBKEY_LALT */
|
||||
' ', ' ', ' ', ' ',
|
||||
0, 0, 0, 0, /* KBKEY_CAPSLOCK */
|
||||
0, 0, 0, 0, /* KBKEY_F1 */
|
||||
0, 0, 0, 0, /* KBKEY_F2 */
|
||||
0, 0, 0, 0, /* KBKEY_F3 */
|
||||
0, 0, 0, 0, /* KBKEY_F4 */
|
||||
0, 0, 0, 0, /* KBKEY_F5 */
|
||||
0, 0, 0, 0, /* KBKEY_F6 */
|
||||
0, 0, 0, 0, /* KBKEY_F7 */
|
||||
0, 0, 0, 0, /* KBKEY_F8 */
|
||||
0, 0, 0, 0, /* KBKEY_F9 */
|
||||
0, 0, 0, 0, /* KBKEY_F10 */
|
||||
0, 0, 0, 0, /* KBKEY_NUMLOCK */
|
||||
0, 0, 0, 0, /* KBKEY_SCROLLLOCK */
|
||||
0, 0, 0, 0, /* KBKEY_KPAD7 */
|
||||
0, 0, 0, 0, /* KBKEY_KPAD8 */
|
||||
0, 0, 0, 0, /* KBKEY_KPAD9 */
|
||||
'-', '-', '-', '-',
|
||||
0, 0, 0, 0, /* KBKEY_KPAD4 */
|
||||
0, 0, 0, 0, /* KBKEY_KPAD5 */
|
||||
0, 0, 0, 0, /* KBKEY_KPAD6 */
|
||||
'+', '+', '+', '+',
|
||||
/* Nothing printable after this point */
|
||||
};
|
||||
|
||||
KBLayoutUS::KBLayoutUS()
|
||||
{
|
||||
modifiers = 0;
|
||||
}
|
||||
|
||||
KBLayoutUS::~KBLayoutUS()
|
||||
{
|
||||
}
|
||||
|
||||
bool KBLayoutUS::ProcessModifier(int logickey, int modkey, unsigned flag)
|
||||
{
|
||||
if ( logickey == modkey ) { modifiers |= flag; return true; }
|
||||
if ( logickey == -modkey ) { modifiers &= ~flag; return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t KBLayoutUS::Translate(int kbkey)
|
||||
{
|
||||
if ( kbkey == KBKEY_LSHIFT ) { modifiers |= MOD_LSHIFT; return 0; }
|
||||
if ( kbkey == -KBKEY_LSHIFT ) { modifiers &= ~MOD_LSHIFT; return 0; }
|
||||
if ( kbkey == KBKEY_CAPSLOCK ) { modifiers ^= MOD_CAPS; return 0; }
|
||||
|
||||
int abskbkey = (kbkey < 0) ? -kbkey : kbkey;
|
||||
|
||||
unsigned usedmods = modifiers & (MOD_LSHIFT | MOD_CAPS);
|
||||
size_t index = (abskbkey<<2) | usedmods;
|
||||
|
||||
// Check if the kbkey is outside the layout structure (not printable).
|
||||
size_t numchars = sizeof(LAYOUT_US) / 4UL / sizeof(uint32_t);
|
||||
if ( numchars < abskbkey ) { return 0; }
|
||||
|
||||
return LAYOUT_US[index];
|
||||
}
|
||||
}
|
||||
|
49
sortix/kb/layout/us.h
Normal file
49
sortix/kb/layout/us.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ks/layout/us.h
|
||||
The United States keyboard layout.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_KB_LAYOUT_US_H
|
||||
#define SORTIX_KB_LAYOUT_US_H
|
||||
|
||||
#include "../../keyboard.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class KBLayoutUS : public KeyboardLayout
|
||||
{
|
||||
public:
|
||||
KBLayoutUS();
|
||||
virtual ~KBLayoutUS();
|
||||
virtual uint32_t Translate(int kbkey);
|
||||
|
||||
public:
|
||||
bool ProcessModifier(int kbkey, int modkey, unsigned flag);
|
||||
|
||||
private:
|
||||
unsigned modifiers;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
193
sortix/kb/ps2.cpp
Normal file
193
sortix/kb/ps2.cpp
Normal file
|
@ -0,0 +1,193 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
kb/ps2.cpp
|
||||
A driver for the PS2 Keyboard.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "../platform.h"
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "../interrupt.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../keycodes.h"
|
||||
#include "ps2.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
const uint16_t DATA = 0x0;
|
||||
const uint16_t COMMAND = 0x0;
|
||||
const uint16_t STATUS = 0x4;
|
||||
const uint8_t CMD_SETLED = 0xED;
|
||||
const uint8_t LED_SCRLCK = (1<<0);
|
||||
const uint8_t LED_NUMLCK = (1<<1);
|
||||
const uint8_t LED_CAPSLCK = (1<<2);
|
||||
|
||||
void PS2Keyboard__OnInterrupt(CPU::InterruptRegisters* regs, void* user)
|
||||
{
|
||||
((PS2Keyboard*) user)->OnInterrupt(regs);
|
||||
}
|
||||
|
||||
PS2Keyboard::PS2Keyboard(uint16_t iobase, uint8_t interrupt)
|
||||
{
|
||||
this->queue = NULL;
|
||||
this->queuelength = 0;
|
||||
this->queueoffset = 0;
|
||||
this->queueused = 0;
|
||||
this->owner = NULL;
|
||||
this->ownerptr = NULL;
|
||||
this->iobase = iobase;
|
||||
this->interrupt = interrupt;
|
||||
this->leds = 0;
|
||||
this->scancodeescaped = false;
|
||||
Interrupt::RegisterHandler(interrupt, PS2Keyboard__OnInterrupt, this);
|
||||
|
||||
// If any scancodes were already pending, our interrupt handler will
|
||||
// never be called. Let's just discard anything pending.
|
||||
PopScancode();
|
||||
}
|
||||
|
||||
PS2Keyboard::~PS2Keyboard()
|
||||
{
|
||||
Interrupt::RegisterHandler(interrupt, NULL, NULL);
|
||||
delete[] queue;
|
||||
}
|
||||
|
||||
void PS2Keyboard::OnInterrupt(CPU::InterruptRegisters* /*regs*/)
|
||||
{
|
||||
uint8_t scancode = PopScancode();
|
||||
int kbkey = DecodeScancode(scancode);
|
||||
if ( !kbkey ) { return; }
|
||||
|
||||
if ( !PushKey(kbkey) )
|
||||
{
|
||||
Log::PrintF("Warning: dropping keystroke due to insufficient "
|
||||
"storage space in PS2 keyboard driver.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t newleds = leds;
|
||||
|
||||
if ( kbkey == KBKEY_CAPSLOCK ) { newleds ^= LED_CAPSLCK; }
|
||||
if ( kbkey == KBKEY_SCROLLLOCK ) { newleds ^= LED_SCRLCK; }
|
||||
if ( kbkey == KBKEY_NUMLOCK ) { newleds ^= LED_NUMLCK; }
|
||||
|
||||
if ( newleds != leds ) { UpdateLEDs(leds = newleds); }
|
||||
|
||||
NotifyOwner();
|
||||
}
|
||||
|
||||
void PS2Keyboard::NotifyOwner()
|
||||
{
|
||||
if ( !owner) { return; }
|
||||
owner->OnKeystroke(this, ownerptr);
|
||||
}
|
||||
|
||||
int PS2Keyboard::DecodeScancode(uint8_t scancode)
|
||||
{
|
||||
const uint8_t SCANCODE_ESCAPE = 0xE0;
|
||||
if ( scancode == SCANCODE_ESCAPE )
|
||||
{
|
||||
scancodeescaped = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = (scancodeescaped) ? 0x80 : 0;
|
||||
int kbkey = scancode & 0x7F;
|
||||
if ( scancode & 0x80 ) { kbkey = -kbkey - offset; }
|
||||
else { kbkey = kbkey + offset; }
|
||||
|
||||
scancodeescaped = false;
|
||||
|
||||
// kbkey is now in the format specified in <sortix/keycodes.h>.
|
||||
|
||||
return kbkey;
|
||||
}
|
||||
|
||||
uint8_t PS2Keyboard::PopScancode()
|
||||
{
|
||||
return CPU::InPortB(iobase + DATA);
|
||||
}
|
||||
|
||||
void PS2Keyboard::UpdateLEDs(int ledval)
|
||||
{
|
||||
while ( (CPU::InPortB(iobase + STATUS) & (1<<1)) != 0 ) { }
|
||||
CPU::OutPortB(iobase + COMMAND, CMD_SETLED);
|
||||
while ( (CPU::InPortB(iobase + STATUS) & (1<<1)) != 0 ) { }
|
||||
CPU::OutPortB(iobase + COMMAND, ledval);
|
||||
}
|
||||
|
||||
void PS2Keyboard::SetOwner(KeyboardOwner* owner, void* user)
|
||||
{
|
||||
this->owner = owner;
|
||||
this->ownerptr = user;
|
||||
if ( queueused ) { NotifyOwner(); }
|
||||
}
|
||||
|
||||
bool PS2Keyboard::PushKey(int key)
|
||||
{
|
||||
// Check if we need to allocate or resize the circular queue.
|
||||
if ( queueused == queuelength )
|
||||
{
|
||||
size_t newqueuelength = (queuelength) ? queuelength * 2 : 32UL;
|
||||
int* newqueue = new int[newqueuelength];
|
||||
if ( !newqueue ) { return false; }
|
||||
size_t elemsize = sizeof(*queue);
|
||||
size_t leadingavai = queuelength-queueoffset;
|
||||
size_t leading = (leadingavai < queueused) ? leadingavai : queueused;
|
||||
size_t trailing = queueused - leading;
|
||||
Memory::Copy(newqueue, queue + queueoffset, leading * elemsize);
|
||||
Memory::Copy(newqueue + leading, queue, trailing * elemsize);
|
||||
delete[] queue;
|
||||
queue = newqueue;
|
||||
queuelength = newqueuelength;
|
||||
queueoffset = 0;
|
||||
}
|
||||
|
||||
queue[(queueoffset + queueused++) % queuelength] = key;
|
||||
return true;
|
||||
}
|
||||
|
||||
int PS2Keyboard::PopKey()
|
||||
{
|
||||
if ( !queueused ) { return 0; }
|
||||
int kbkey = queue[queueoffset];
|
||||
queueoffset = (queueoffset + 1) % queuelength;
|
||||
queueused--;
|
||||
return kbkey;
|
||||
}
|
||||
|
||||
int PS2Keyboard::Read()
|
||||
{
|
||||
return PopKey();
|
||||
}
|
||||
|
||||
size_t PS2Keyboard::GetPending() const
|
||||
{
|
||||
return queueused;
|
||||
}
|
||||
|
||||
bool PS2Keyboard::HasPending() const
|
||||
{
|
||||
return queueused;
|
||||
}
|
||||
}
|
||||
|
69
sortix/kb/ps2.h
Normal file
69
sortix/kb/ps2.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
kb/ps2.h
|
||||
A driver for the PS2 Keyboard.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_KB_PS2_H
|
||||
#define SORTIX_KB_PS2_H
|
||||
|
||||
#include "../keyboard.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class PS2Keyboard : public Keyboard
|
||||
{
|
||||
public:
|
||||
PS2Keyboard(uint16_t iobase, uint8_t interrupt);
|
||||
virtual ~PS2Keyboard();
|
||||
virtual int Read();
|
||||
virtual size_t GetPending() const;
|
||||
virtual bool HasPending() const;
|
||||
virtual void SetOwner(KeyboardOwner* owner, void* user);
|
||||
|
||||
public:
|
||||
void OnInterrupt(CPU::InterruptRegisters* regs);
|
||||
|
||||
private:
|
||||
uint8_t PopScancode();
|
||||
int DecodeScancode(uint8_t scancode);
|
||||
void UpdateLEDs(int ledval);
|
||||
bool PushKey(int key);
|
||||
int PopKey();
|
||||
void NotifyOwner();
|
||||
|
||||
private:
|
||||
int* queue;
|
||||
size_t queuelength;
|
||||
size_t queueoffset;
|
||||
size_t queueused;
|
||||
KeyboardOwner* owner;
|
||||
void* ownerptr;
|
||||
uint16_t iobase;
|
||||
uint8_t interrupt;
|
||||
bool scancodeescaped;
|
||||
uint8_t leds;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
142
sortix/kbapiadapter.cpp
Normal file
142
sortix/kbapiadapter.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
kbapidapter.cpp
|
||||
This class is a hack connecting the Keyboard and Keyboard layout classes
|
||||
with the older and really bad Keyboard API. This class is intended to be
|
||||
replaced by a real terminal driver working over /dev/tty descriptors.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include <libmaxsi/keyboard.h>
|
||||
#include "scheduler.h" // SIGINT
|
||||
#include "keyboard.h"
|
||||
#include "keycodes.h"
|
||||
#include "kbapiadapter.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
KBAPIAdapter::KBAPIAdapter(Keyboard* keyboard, KeyboardLayout* kblayout)
|
||||
{
|
||||
this->keyboard = keyboard;
|
||||
this->kblayout = kblayout;
|
||||
this->control = false;
|
||||
this->queuelength = QUEUELENGTH;
|
||||
this->queueused = 0;
|
||||
this->queueoffset = 0;
|
||||
keyboard->SetOwner(this, NULL);
|
||||
}
|
||||
|
||||
KBAPIAdapter::~KBAPIAdapter()
|
||||
{
|
||||
delete keyboard;
|
||||
delete kblayout;
|
||||
}
|
||||
|
||||
void KBAPIAdapter::OnKeystroke(Keyboard* kb, void* /*user*/)
|
||||
{
|
||||
while ( kb->HasPending() )
|
||||
{
|
||||
ProcessKeystroke(kb->Read());
|
||||
}
|
||||
}
|
||||
|
||||
void KBAPIAdapter::ProcessKeystroke(int kbkey)
|
||||
{
|
||||
if ( !kbkey ) { return; }
|
||||
int abskbkey = (kbkey < 0) ? -kbkey : kbkey;
|
||||
|
||||
uint32_t unicode = kblayout->Translate(kbkey);
|
||||
|
||||
// Now translate the keystroke into the older API's charset..
|
||||
uint32_t maxsicode = (unicode) ? unicode : ToMaxsiCode(abskbkey);
|
||||
|
||||
if ( kbkey < 0 ) { maxsicode |= Maxsi::Keyboard::DEPRESSED; }
|
||||
|
||||
if ( kbkey == KBKEY_LCTRL ) { control = true; }
|
||||
if ( kbkey == -KBKEY_LCTRL ) { control = false; }
|
||||
if ( control && kbkey == KBKEY_C )
|
||||
{
|
||||
Scheduler::SigIntHack();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !QueueKeystroke(maxsicode) )
|
||||
{
|
||||
Log::PrintF("Warning: KBAPIAdapter driver dropping keystroke due "
|
||||
"to insufficient buffer space\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t KBAPIAdapter::ToMaxsiCode(int abskbkey)
|
||||
{
|
||||
switch ( abskbkey )
|
||||
{
|
||||
case KBKEY_ESC: return Maxsi::Keyboard::ESC;
|
||||
case KBKEY_LCTRL: return Maxsi::Keyboard::CTRL;
|
||||
case KBKEY_LSHIFT: return Maxsi::Keyboard::LSHFT;
|
||||
case KBKEY_RSHIFT: return Maxsi::Keyboard::RSHFT;
|
||||
case KBKEY_LALT: return Maxsi::Keyboard::ALT;
|
||||
case KBKEY_F1: return Maxsi::Keyboard::F1;
|
||||
case KBKEY_F2: return Maxsi::Keyboard::F2;
|
||||
case KBKEY_F3: return Maxsi::Keyboard::F3;
|
||||
case KBKEY_F4: return Maxsi::Keyboard::F4;
|
||||
case KBKEY_F5: return Maxsi::Keyboard::F5;
|
||||
case KBKEY_F6: return Maxsi::Keyboard::F6;
|
||||
case KBKEY_F7: return Maxsi::Keyboard::F7;
|
||||
case KBKEY_F8: return Maxsi::Keyboard::F8;
|
||||
case KBKEY_F9: return Maxsi::Keyboard::F9;
|
||||
case KBKEY_F10: return Maxsi::Keyboard::F10;
|
||||
case KBKEY_F11: return Maxsi::Keyboard::F11;
|
||||
case KBKEY_F12: return Maxsi::Keyboard::F12;
|
||||
case KBKEY_SCROLLLOCK: return Maxsi::Keyboard::SCRLCK;
|
||||
case KBKEY_HOME: return Maxsi::Keyboard::HOME;
|
||||
case KBKEY_UP: return Maxsi::Keyboard::UP;
|
||||
case KBKEY_LEFT: return Maxsi::Keyboard::LEFT;
|
||||
case KBKEY_RIGHT: return Maxsi::Keyboard::RIGHT;
|
||||
case KBKEY_DOWN: return Maxsi::Keyboard::DOWN;
|
||||
case KBKEY_PGUP: return Maxsi::Keyboard::PGUP;
|
||||
case KBKEY_PGDOWN: return Maxsi::Keyboard::PGDOWN;
|
||||
case KBKEY_END: return Maxsi::Keyboard::END;
|
||||
case KBKEY_INSERT: return Maxsi::Keyboard::INS;
|
||||
case KBKEY_DELETE: return Maxsi::Keyboard::DEL;
|
||||
case KBKEY_CAPSLOCK: return Maxsi::Keyboard::CAPS;
|
||||
case KBKEY_RALT: return Maxsi::Keyboard::ALTGR;
|
||||
case KBKEY_NUMLOCK: return Maxsi::Keyboard::NUMLCK;
|
||||
default: return Maxsi::Keyboard::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool KBAPIAdapter::QueueKeystroke(uint32_t keystroke)
|
||||
{
|
||||
if ( queuelength <= queueused ) { return false; }
|
||||
queue[(queueoffset + queueused++) % queuelength] = keystroke;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t KBAPIAdapter::DequeueKeystroke()
|
||||
{
|
||||
if ( !queueused ) { return 0; }
|
||||
uint32_t codepoint = queue[queueoffset++];
|
||||
queueoffset %= queuelength;
|
||||
queueused--;
|
||||
return codepoint;
|
||||
}
|
||||
}
|
63
sortix/kbapiadapter.h
Normal file
63
sortix/kbapiadapter.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
kbapidapter.h
|
||||
This class is a hack connecting the Keyboard and Keyboard layout classes
|
||||
with the older and really bad Keyboard API. This class is intended to be
|
||||
replaced by a real terminal driver working over /dev/tty descriptors.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_KBAPIADAPTER_H
|
||||
#define SORTIX_KBAPIADAPTER_H
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class KBAPIAdapter : public KeyboardOwner
|
||||
{
|
||||
public:
|
||||
KBAPIAdapter(Keyboard* keyboard, KeyboardLayout* kblayout);
|
||||
virtual ~KBAPIAdapter();
|
||||
virtual void OnKeystroke(Keyboard* keyboard, void* user);
|
||||
|
||||
public:
|
||||
uint32_t DequeueKeystroke();
|
||||
|
||||
private:
|
||||
void ProcessKeystroke(int kbkey);
|
||||
bool QueueKeystroke(uint32_t keystroke);
|
||||
static uint32_t ToMaxsiCode(int abskbkey);
|
||||
|
||||
private:
|
||||
Keyboard* keyboard;
|
||||
KeyboardLayout* kblayout;
|
||||
bool control;
|
||||
static const size_t QUEUELENGTH = 1024UL;
|
||||
size_t queuelength;
|
||||
size_t queueused;
|
||||
size_t queueoffset;
|
||||
uint32_t queue[QUEUELENGTH];
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
|
@ -18,721 +18,39 @@
|
|||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
keyboard.cpp
|
||||
A driver for the PS2 Keyboard.
|
||||
An interface to keyboards.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include <libmaxsi/memory.h>
|
||||
#include <libmaxsi/keyboard.h>
|
||||
#include "log.h"
|
||||
#include "panic.h"
|
||||
#include "keyboard.h"
|
||||
#include "interrupt.h"
|
||||
#include "scheduler.h"
|
||||
#include "syscall.h"
|
||||
|
||||
using namespace Maxsi::Keyboard;
|
||||
#include "keyboard.h"
|
||||
#include "kb/ps2.h"
|
||||
#include "kb/layout/us.h"
|
||||
#include "kbapiadapter.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace Keyboard
|
||||
KBAPIAdapter* tty;
|
||||
|
||||
uint32_t SysReceiveKeystroke()
|
||||
{
|
||||
namespace Layouts
|
||||
{
|
||||
namespace US
|
||||
{
|
||||
uint32_t sg[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'0',
|
||||
'-',
|
||||
'=',
|
||||
'\b',
|
||||
'\t',
|
||||
'q',
|
||||
'w',
|
||||
'e',
|
||||
'r',
|
||||
't',
|
||||
'y',
|
||||
'u',
|
||||
'i',
|
||||
'o',
|
||||
'p',
|
||||
'[',
|
||||
']',
|
||||
'\n',
|
||||
CTRL,
|
||||
'a',
|
||||
's',
|
||||
'd',
|
||||
'f',
|
||||
'g',
|
||||
'h',
|
||||
'j',
|
||||
'k',
|
||||
'l',
|
||||
';',
|
||||
'\'',
|
||||
'`',
|
||||
LSHFT,
|
||||
'\\',
|
||||
'z',
|
||||
'x',
|
||||
'c',
|
||||
'v',
|
||||
'b',
|
||||
'n',
|
||||
'm',
|
||||
',',
|
||||
'.',
|
||||
'/',
|
||||
RSHFT,
|
||||
'*',
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
return tty->DequeueKeystroke();
|
||||
}
|
||||
|
||||
uint32_t Sg[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
'!',
|
||||
'@',
|
||||
'#',
|
||||
'$',
|
||||
'%',
|
||||
'^',
|
||||
'&',
|
||||
'*',
|
||||
'(',
|
||||
')',
|
||||
'_',
|
||||
'+',
|
||||
'\b',
|
||||
'\t', // TODO: Make it de-tab!
|
||||
'Q',
|
||||
'W',
|
||||
'E',
|
||||
'R',
|
||||
'T',
|
||||
'Y',
|
||||
'U',
|
||||
'I',
|
||||
'O',
|
||||
'P',
|
||||
'{',
|
||||
'}',
|
||||
'\n',
|
||||
CTRL,
|
||||
'A',
|
||||
'S',
|
||||
'D',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
':',
|
||||
'"',
|
||||
'~',
|
||||
LSHFT,
|
||||
'|',
|
||||
'Z',
|
||||
'X',
|
||||
'C',
|
||||
'V',
|
||||
'B',
|
||||
'N',
|
||||
'M',
|
||||
'<',
|
||||
'>',
|
||||
'?',
|
||||
RSHFT,
|
||||
'*',
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
void Keyboard::Init()
|
||||
{
|
||||
Keyboard* keyboard = new PS2Keyboard(0x60, Interrupt::IRQ1);
|
||||
if ( !keyboard ) { Panic("Could not allocate PS2 Keyboard driver"); }
|
||||
|
||||
uint32_t sG[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\b',
|
||||
'\t',
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\n',
|
||||
CTRL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
LSHFT,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
RSHFT,
|
||||
UNKNOWN,
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
KeyboardLayout* kblayout = new KBLayoutUS;
|
||||
if ( !kblayout ) { Panic("Could not allocate keyboard layout driver"); }
|
||||
|
||||
uint32_t SG[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\b',
|
||||
'\t',
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\n',
|
||||
CTRL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
LSHFT,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
RSHFT,
|
||||
UNKNOWN,
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
tty = new KBAPIAdapter(keyboard, kblayout);
|
||||
if ( !tty ) { Panic("Could not allocate a simple terminal"); }
|
||||
|
||||
uint32_t* Layout[4] = { sg, Sg, sG, SG };
|
||||
}
|
||||
|
||||
uint32_t** Layout = US::Layout;
|
||||
|
||||
nat Mask;
|
||||
nat LockMask;
|
||||
bool control;
|
||||
|
||||
void Init()
|
||||
{
|
||||
Mask = 0;
|
||||
LockMask = 0;
|
||||
control = false;
|
||||
}
|
||||
|
||||
const nat Shift = (1<<0);
|
||||
const nat AltGr = (1<<1);
|
||||
const nat ScrLck = (1<<2);
|
||||
const nat LEDScrLck = (1<<0);
|
||||
const nat LEDNumLck = (1<<1);
|
||||
const nat LEDCapsLck = (1<<2);
|
||||
|
||||
uint32_t GetCodePoint(uint8_t Scancode)
|
||||
{
|
||||
nat TableIndex = 0x3 & (Mask ^ LockMask);
|
||||
|
||||
//Log::PrintF("[m=%x,lm=%x,ti=%x]", Mask, LockMask, TableIndex);
|
||||
|
||||
uint32_t CodePoint = Layout[TableIndex][Scancode & 0x7F];
|
||||
|
||||
if ( CodePoint == UNKNOWN ) { return UNKNOWN; }
|
||||
if ( Scancode & 0x80 )
|
||||
{
|
||||
if ( CodePoint == LSHFT ) { Mask &= ~Shift; }
|
||||
if ( CodePoint == ALTGR ) { Mask &= ~AltGr; }
|
||||
if ( CodePoint == SCRLCK ) { Mask &= ~ScrLck; }
|
||||
if ( CodePoint == CTRL ) { control = false; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( CodePoint == LSHFT ) { Mask |= Shift; }
|
||||
if ( CodePoint == ALTGR ) { Mask |= AltGr; }
|
||||
if ( CodePoint == SCRLCK ) { Mask |= ScrLck; }
|
||||
if ( CodePoint == CAPS ) { LockMask ^= Shift; SetLEDs(LEDCapsLck); }
|
||||
if ( CodePoint == CTRL ) { control = true; }
|
||||
}
|
||||
|
||||
if ( control && ( CodePoint == 'c' || CodePoint == 'C' ) )
|
||||
{
|
||||
CodePoint = SIGINT;
|
||||
}
|
||||
|
||||
return CodePoint;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LEDs;
|
||||
|
||||
size_t keystrokeQueueOffset;
|
||||
size_t keystrokeQueueUsed;
|
||||
size_t keystrokeQueueLength;
|
||||
uint32_t* keystrokeQueue;
|
||||
|
||||
uint32_t SysReceiveKeystroke()
|
||||
{
|
||||
if ( keystrokeQueueUsed == 0 ) { return 0; }
|
||||
|
||||
uint32_t codepoint = keystrokeQueue[keystrokeQueueOffset++];
|
||||
keystrokeQueueOffset %= keystrokeQueueLength;
|
||||
keystrokeQueueUsed--;
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
// Initialize variables.
|
||||
LEDs = 0;
|
||||
|
||||
Layouts::Init();
|
||||
|
||||
// Register our keystroke callback.
|
||||
Interrupt::RegisterHandler(Interrupt::IRQ1, OnIRQ1, NULL);
|
||||
|
||||
// If any scancodes were already pending, our interrupt handler
|
||||
// will never be called. Let's just discard anything pending.
|
||||
CPU::InPortB(0x60);
|
||||
|
||||
// Create a queue where pending keystrokes can be stored until
|
||||
// user-space applications access them.
|
||||
keystrokeQueueUsed = 0;
|
||||
keystrokeQueueOffset = 0;
|
||||
keystrokeQueueLength = 1024ULL;
|
||||
keystrokeQueue = new uint32_t[keystrokeQueueLength];
|
||||
if ( keystrokeQueue == NULL )
|
||||
{
|
||||
Panic("Could not allocate keystroke buffer");
|
||||
}
|
||||
|
||||
Syscall::Register(SYSCALL_RECEIVE_KEYSTROKE, (void*) SysReceiveKeystroke);
|
||||
}
|
||||
|
||||
bool QueueKeystroke(uint32_t keystroke)
|
||||
{
|
||||
if ( keystrokeQueueLength <= keystrokeQueueUsed ) { return false; }
|
||||
|
||||
size_t position = keystrokeQueueOffset + keystrokeQueueUsed;
|
||||
position %= keystrokeQueueLength;
|
||||
keystrokeQueueUsed++;
|
||||
|
||||
keystrokeQueue[position] = keystroke;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnIRQ1(CPU::InterruptRegisters* Regs, void* user)
|
||||
{
|
||||
// Read the scancode from the data register.
|
||||
uint8_t Scancode = CPU::InPortB(0x60);
|
||||
|
||||
//Log::PrintF("[%u]", Scancode);
|
||||
|
||||
uint32_t CodePoint = Layouts::GetCodePoint(Scancode);
|
||||
|
||||
if ( CodePoint == SIGINT )
|
||||
{
|
||||
Scheduler::SigIntHack();
|
||||
return;
|
||||
}
|
||||
|
||||
bool KeyUp = (Scancode & 0x80);
|
||||
|
||||
if ( KeyUp ) { CodePoint |= DEPRESSED; }
|
||||
|
||||
QueueKeystroke(CodePoint);
|
||||
return;
|
||||
|
||||
//if ( Reader != NULL ) { Reader->OnKeystroke(CodePoint, KeyUp); return; }
|
||||
|
||||
// Use this to debug the exact scancodes you receive!
|
||||
//Log::PrintF("[%u/U+%x]", Scancode, CodePoint);
|
||||
|
||||
if ( CodePoint == UNKNOWN ) { Log::PrintF("^%u", Scancode);return; }
|
||||
|
||||
if ( CodePoint & (1<<31) ) { return; }
|
||||
|
||||
// The high bit of the scancode is set if the key is released.
|
||||
if ( Scancode & 0x80 ) { return; }
|
||||
|
||||
if ( CodePoint & 0xFFFFFF80 ) { Log::PrintF("U+%x", CodePoint); return; }
|
||||
|
||||
Log::PrintF("%s", &CodePoint); // Little endian hack!
|
||||
}
|
||||
|
||||
void SetLEDs(uint8_t Toggle)
|
||||
{
|
||||
LEDs ^= Toggle;
|
||||
|
||||
while ( (CPU::InPortB(0x64) & (1<<1)) != 0 ) { } //loop Until zero
|
||||
CPU::OutPortB(0x60, 0xED);
|
||||
while ( (CPU::InPortB(0x64) & (1<<1)) != 0 ) { } //loop Until zero
|
||||
CPU::OutPortB(0x60, LEDs);
|
||||
}
|
||||
Syscall::Register(SYSCALL_RECEIVE_KEYSTROKE, (void*) SysReceiveKeystroke);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
keyboard.h
|
||||
A driver for the PS2 Keyboard.
|
||||
An interface to keyboards.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -27,13 +27,35 @@
|
|||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace Keyboard
|
||||
class Keyboard;
|
||||
class KeyboardOwner;
|
||||
|
||||
class Keyboard
|
||||
{
|
||||
void Init();
|
||||
void SetLEDs(uint8_t Toggle);
|
||||
void OnIRQ1(CPU::InterruptRegisters* Regs, void* user);
|
||||
bool QueueKeystroke(uint32_t keystroke);
|
||||
}
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
public:
|
||||
virtual ~Keyboard() { }
|
||||
virtual int Read() = 0;
|
||||
virtual size_t GetPending() const = 0;
|
||||
virtual bool HasPending() const = 0;
|
||||
virtual void SetOwner(KeyboardOwner* owner, void* user) = 0;
|
||||
};
|
||||
|
||||
class KeyboardOwner
|
||||
{
|
||||
public:
|
||||
virtual ~KeyboardOwner() { }
|
||||
virtual void OnKeystroke(Keyboard* keyboard, void* user) = 0;
|
||||
};
|
||||
|
||||
class KeyboardLayout
|
||||
{
|
||||
public:
|
||||
virtual ~KeyboardLayout() { }
|
||||
virtual uint32_t Translate(int kbkey) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
145
sortix/keycodes.h
Normal file
145
sortix/keycodes.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
keycodes.h
|
||||
Defines codes for every logical key on keyboards.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_KEYCODES_H
|
||||
#define SORTIX_KEYCODES_H
|
||||
|
||||
/* Each of these keycodes corrospond to a logical key on a keyboard. Code
|
||||
reading logical keystrokes from the keyboard will receive a code from this
|
||||
list when the key is pressed, and a negative version of the same key when it
|
||||
is released by the user. */
|
||||
|
||||
#define KBKEY_ESC 0x01
|
||||
#define KBKEY_NUM1 0x02
|
||||
#define KBKEY_NUM2 0x03
|
||||
#define KBKEY_NUM3 0x04
|
||||
#define KBKEY_NUM4 0x05
|
||||
#define KBKEY_NUM5 0x06
|
||||
#define KBKEY_NUM6 0x07
|
||||
#define KBKEY_NUM7 0x08
|
||||
#define KBKEY_NUM8 0x09
|
||||
#define KBKEY_NUM9 0x0A
|
||||
#define KBKEY_NUM0 0x0B
|
||||
#define KBKEY_SYM1 0x0C
|
||||
#define KBKEY_SYM2 0x0D
|
||||
#define KBKEY_BKSPC 0x0E
|
||||
#define KBKEY_TAB 0x0F
|
||||
#define KBKEY_Q 0x10
|
||||
#define KBKEY_W 0x11
|
||||
#define KBKEY_E 0x12
|
||||
#define KBKEY_R 0x13
|
||||
#define KBKEY_T 0x14
|
||||
#define KBKEY_Y 0x15
|
||||
#define KBKEY_U 0x16
|
||||
#define KBKEY_I 0x17
|
||||
#define KBKEY_O 0x18
|
||||
#define KBKEY_P 0x19
|
||||
#define KBKEY_SYM3 0x1A
|
||||
#define KBKEY_SYM4 0x1B
|
||||
#define KBKEY_ENTER 0x1C
|
||||
#define KBKEY_LCTRL 0x1D
|
||||
#define KBKEY_A 0x1E
|
||||
#define KBKEY_S 0x1F
|
||||
#define KBKEY_D 0x20
|
||||
#define KBKEY_F 0x21
|
||||
#define KBKEY_G 0x22
|
||||
#define KBKEY_H 0x23
|
||||
#define KBKEY_J 0x24
|
||||
#define KBKEY_K 0x25
|
||||
#define KBKEY_L 0x26
|
||||
#define KBKEY_SYM5 0x27
|
||||
#define KBKEY_SYM6 0x28
|
||||
#define KBKEY_SYM7 0x29
|
||||
#define KBKEY_LSHIFT 0x2A
|
||||
#define KBKEY_SYM8 0x2B
|
||||
#define KBKEY_Z 0x2C
|
||||
#define KBKEY_X 0x2D
|
||||
#define KBKEY_C 0x2E
|
||||
#define KBKEY_V 0x2F
|
||||
#define KBKEY_B 0x30
|
||||
#define KBKEY_N 0x31
|
||||
#define KBKEY_M 0x32
|
||||
#define KBKEY_SYM9 0x33
|
||||
#define KBKEY_SYM10 0x34
|
||||
#define KBKEY_SYM11 0x35
|
||||
#define KBKEY_RSHIFT 0x36
|
||||
#define KBKEY_SYM12 0x37
|
||||
#define KBKEY_LALT 0x38
|
||||
#define KBKEY_SPACE 0x39
|
||||
#define KBKEY_CAPSLOCK 0x3A
|
||||
#define KBKEY_F1 0x3B
|
||||
#define KBKEY_F2 0x3C
|
||||
#define KBKEY_F3 0x3D
|
||||
#define KBKEY_F4 0x3E
|
||||
#define KBKEY_F5 0x3F
|
||||
#define KBKEY_F6 0x40
|
||||
#define KBKEY_F7 0x41
|
||||
#define KBKEY_F8 0x42
|
||||
#define KBKEY_F9 0x43
|
||||
#define KBKEY_F10 0x44
|
||||
#define KBKEY_NUMLOCK 0x45
|
||||
#define KBKEY_SCROLLLOCK 0x46
|
||||
#define KBKEY_KPAD7 0x47
|
||||
#define KBKEY_KPAD8 0x48
|
||||
#define KBKEY_KPAD9 0x49
|
||||
#define KBKEY_SYM13 0x4A
|
||||
#define KBKEY_KPAD4 0x4B
|
||||
#define KBKEY_KPAD5 0x4C
|
||||
#define KBKEY_KPAD6 0x4D
|
||||
#define KBKEY_SYM14 0x4E
|
||||
#define KBKEY_KPAD1 0x4F
|
||||
#define KBKEY_KPAD2 0x50
|
||||
#define KBKEY_KPAD3 0x51
|
||||
#define KBKEY_KPAD0 0x52
|
||||
#define KBKEY_SYM15 0x53
|
||||
#define KBKEY_ALTSYSRQ 0x54
|
||||
#define KBKEY_NO_STANDARD_MEANING_1 0x55 /* Sometimes F11, F12, or even FN */
|
||||
#define KBKEY_NO_STANDARD_MEANING_2 0x56 /* Possibly Windows key? */
|
||||
#define KBKEY_F11 0x57
|
||||
#define KBKEY_F12 0x58
|
||||
/* [0x59, 0x7F] are not really standard. */
|
||||
#define KBKEY_KPADENTER (0x80 + 0x1C)
|
||||
#define KBKEY_RCTRL (0x80 + 0x1D)
|
||||
#define KBKEY_FAKELSHIFT (0x80 + 0x2A)
|
||||
#define KBKEY_SYM16 (0x80 + 0x35)
|
||||
#define KBKEY_FAKERSHIFT (0x80 + 0x36)
|
||||
#define KBKEY_CTRLPRINTSCRN (0x80 + 0x37)
|
||||
#define KBKEY_RALT (0x80 + 0x38)
|
||||
#define KBKEY_CTRLBREAK (0x80 + 0x46)
|
||||
#define KBKEY_HOME (0x80 + 0x47)
|
||||
#define KBKEY_UP (0x80 + 0x48)
|
||||
#define KBKEY_PGUP (0x80 + 0x49)
|
||||
#define KBKEY_LEFT (0x80 + 0x4B)
|
||||
#define KBKEY_RIGHT (0x80 + 0x4D)
|
||||
#define KBKEY_END (0x80 + 0x4F)
|
||||
#define KBKEY_DOWN (0x80 + 0x50)
|
||||
#define KBKEY_PGDOWN (0x80 + 0x51)
|
||||
#define KBKEY_INSERT (0x80 + 0x52)
|
||||
#define KBKEY_DELETE (0x80 + 0x53)
|
||||
#define KBKEY_LSUPER (0x80 + 0x5B)
|
||||
#define KBKEY_RSUPER (0x80 + 0x5C)
|
||||
#define KBKEY_MENU (0x80 + 0x5D)
|
||||
|
||||
#endif
|
||||
|
|
@ -69,6 +69,13 @@ namespace Sortix
|
|||
int c;
|
||||
while ( (c=UART::TryPopChar()) != -1 )
|
||||
{
|
||||
#warning Support for hooking the serial input up against the keyboard API have broken
|
||||
#if 0
|
||||
// TODO: This is no longer compatible with the keyboard API, so
|
||||
// it has been commented out. Besides, JSSortix isn't really
|
||||
// supported anyway. It'd be nice to refactor this into a
|
||||
// SerialKeyboard class or something.
|
||||
|
||||
using namespace Maxsi::Keyboard;
|
||||
|
||||
if ( !isEsc && c == '\e' ) { isEsc = true; continue; }
|
||||
|
@ -121,6 +128,7 @@ namespace Sortix
|
|||
c &= ~(1<<7); c |= DEPRESSED;
|
||||
}
|
||||
Keyboard::QueueKeystroke(c);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue