From 4db550c13bf0eca956191739374addea8ac8db2d Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 21 Aug 2011 12:47:59 +0200 Subject: [PATCH] Added libmaxsi keyboard API, allowing user-space to use the keyboard. --- libmaxsi/Makefile | 16 +++++- libmaxsi/hsrc/keyboard.h | 69 ++++++++++++++++++++++++ libmaxsi/hsrc/sortix-keyboard.h | 47 +++++++++++++++++ libmaxsi/sortix-keyboard.cpp | 41 +++++++++++++++ sortix/isr.cpp | 4 +- sortix/kernel.cpp | 6 +-- sortix/keyboard.cpp | 93 ++++++++++++++++++++------------- sortix/keyboard.h | 1 + sortix/syscall.cpp | 4 +- 9 files changed, 235 insertions(+), 46 deletions(-) create mode 100644 libmaxsi/hsrc/keyboard.h create mode 100644 libmaxsi/hsrc/sortix-keyboard.h create mode 100644 libmaxsi/sortix-keyboard.cpp diff --git a/libmaxsi/Makefile b/libmaxsi/Makefile index 5f0f503e..523da024 100644 --- a/libmaxsi/Makefile +++ b/libmaxsi/Makefile @@ -44,8 +44,20 @@ c/h/stdio.h COMMONOBJS=c++.o thread.o io.o memory.o string.o error.o format.o SORTIXOBJS:=$(addprefix sortix/,$(COMMONOBJS)) -LIBMAXSIOBJS:=$(COMMONOBJS) sortix-vga.o -HEADERS=error.h io.h memory.h platform.h string.h syscall.h thread.h types.h format.h sortix-vga.h +LIBMAXSIOBJS:=$(COMMONOBJS) sortix-vga.o sortix-keyboard.o +HEADERS=\ +error.h \ +io.h \ +memory.h \ +platform.h \ +string.h \ +syscall.h \ +thread.h \ +types.h \ +format.h \ +keyboard.h \ +sortix-vga.h \ +sortix-keyboard.h OBJS:=$(LIBMAXSIOBJS) BINS:=libmaxsi.so diff --git a/libmaxsi/hsrc/keyboard.h b/libmaxsi/hsrc/keyboard.h new file mode 100644 index 00000000..e3d4ac2d --- /dev/null +++ b/libmaxsi/hsrc/keyboard.h @@ -0,0 +1,69 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + 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 . + + keyboard.h + Provides constants for various useful keys related to keyboard input. + +******************************************************************************/ + +#ifndef LIBMAXSI_KEYBOARD_H +#define LIBMAXSI_KEYBOARD_H + +namespace Maxsi +{ + namespace Keyboard + { + const uint32_t UNKNOWN = 0x40000000; + const uint32_t ESC = 0x40000000 + 1; + const uint32_t CTRL = 0x40000000 + 2; + const uint32_t LSHFT = 0x40000000 + 3; + const uint32_t RSHFT = 0x40000000 + 4; + const uint32_t ALT = 0x40000000 + 5; + const uint32_t F1 = 0x40000000 + 6; + const uint32_t F2 = 0x40000000 + 7; + const uint32_t F3 = 0x40000000 + 8; + const uint32_t F4 = 0x40000000 + 9; + const uint32_t F5 = 0x40000000 + 10; + const uint32_t F6 = 0x40000000 + 11; + const uint32_t F7 = 0x40000000 + 12; + const uint32_t F8 = 0x40000000 + 13; + const uint32_t F9 = 0x40000000 + 14; + const uint32_t F10 = 0x40000000 + 15; + const uint32_t F11 = 0x40000000 + 16; + const uint32_t F12 = 0x40000000 + 17; + const uint32_t SCRLCK = 0x40000000 + 18; + const uint32_t HOME = 0x40000000 + 19; + const uint32_t UP = 0x40000000 + 20; + const uint32_t LEFT = 0x40000000 + 21; + const uint32_t RIGHT = 0x40000000 + 22; + const uint32_t DOWN = 0x40000000 + 23; + const uint32_t PGUP = 0x40000000 + 24; + const uint32_t PGDOWN = 0x40000000 + 25; + const uint32_t END = 0x40000000 + 26; + const uint32_t INS = 0x40000000 + 27; + const uint32_t DEL = 0x40000000 + 28; + const uint32_t CAPS = 0x40000000 + 29; + const uint32_t NONE = 0x40000000 + 30; + const uint32_t ALTGR = 0x40000000 + 31; + const uint32_t NUMLCK = 0x40000000 + 32; + const uint32_t DEPRESSED = (1<<31); + } +} + +#endif diff --git a/libmaxsi/hsrc/sortix-keyboard.h b/libmaxsi/hsrc/sortix-keyboard.h new file mode 100644 index 00000000..bde88d2a --- /dev/null +++ b/libmaxsi/hsrc/sortix-keyboard.h @@ -0,0 +1,47 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + 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 . + + sortix-keyboard.h + Provides access to the keyboard input meant for this process. This is highly + unportable and is very likely to be removed or changed radically. + +******************************************************************************/ + +#ifndef LIBMAXSI_SORTIX_KEYBOARD_H +#define LIBMAXSI_SORTIX_KEYBOARD_H + +#include +#include + +namespace System +{ + namespace Keyboard + { + // Receives the next pending 32-bit unicode character from the user's + // input device (truncated to 30-bits). Bit (1<<31) is set if the key + // was depressed. Bit (1<<30) is used for the various constants found + // in . This is just a temporary API. Returns 0 if + // no character point was available at this time. + const unsigned WAIT = 0; + const unsigned POLL = 1; + uint32_t ReceieveKeystroke(unsigned method); + } +} + +#endif diff --git a/libmaxsi/sortix-keyboard.cpp b/libmaxsi/sortix-keyboard.cpp new file mode 100644 index 00000000..a2f22c4c --- /dev/null +++ b/libmaxsi/sortix-keyboard.cpp @@ -0,0 +1,41 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + 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 . + + sortix-keyboard.cpp + Provides access to the keyboard input meant for this process. This is highly + unportable and is very likely to be removed or changed radically. + +******************************************************************************/ + +#include "platform.h" +#include "syscall.h" + +namespace System +{ + namespace Keyboard + { + DEFN_SYSCALL1(uint32_t, SysReceieveKeystroke, 8, unsigned); + + uint32_t ReceieveKeystroke(unsigned method) + { + return SysReceieveKeystroke(method); + } + } +} + diff --git a/sortix/isr.cpp b/sortix/isr.cpp index d81c88d8..008a1c91 100644 --- a/sortix/isr.cpp +++ b/sortix/isr.cpp @@ -51,9 +51,9 @@ const char* exceptions[] = { "Divide by zero", "Debug", "Non maskable interrupt" extern "C" void irq_handler(Sortix::CPU::InterruptRegisters* Regs) { #ifdef PLATFORM_X86 - if ( Regs->int_no != 32 ) + if ( Regs->int_no != 32 && Regs->int_no != 33 ) { - Sortix::Log::PrintF("IRQ eax=%u, int_no=%u, err_code=%u, eip=0x%x!\n", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); + //Sortix::Log::PrintF("IRQ eax=%u, int_no=%u, err_code=%u, eip=0x%x!\n", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); } if ( Regs->int_no < 32 || 48 < Regs->int_no ) { Sortix::PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); } diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index bc923642..8e6dc179 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -218,10 +218,6 @@ namespace Sortix if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); } - - // Initialize the keyboard. - Keyboard::Init(); - #ifdef PLATFORM_VIRTUAL_MEMORY // Initialize virtual memory. TODO: This is not fully working yet. VirtualMemory::Init(); @@ -232,6 +228,8 @@ namespace Sortix #endif #endif + // Initialize the keyboard. + Keyboard::Init(); // Initialize system calls. Syscall::Init(); diff --git a/sortix/keyboard.cpp b/sortix/keyboard.cpp index 223ec6b4..f1cbd5f9 100644 --- a/sortix/keyboard.cpp +++ b/sortix/keyboard.cpp @@ -23,8 +23,8 @@ ******************************************************************************/ #include "platform.h" -#include "globals.h" -#include "iprintable.h" +#include +#include #include "iirqhandler.h" #include "log.h" #include "panic.h" @@ -33,46 +33,14 @@ #include "pong.h" +using namespace Maxsi::Keyboard; + namespace Sortix { namespace Keyboard { namespace Layouts { - const uint32_t UNKNOWN = 0xFFFFFFFF; - const uint32_t ESC = 0xFFFFFFFF - 1; - const uint32_t CTRL = 0xFFFFFFFF - 2; - const uint32_t LSHFT = 0xFFFFFFFF - 3; - const uint32_t RSHFT = 0xFFFFFFFF - 4; - const uint32_t ALT = 0xFFFFFFFF - 5; - const uint32_t F1 = 0xFFFFFFFF - 6; - const uint32_t F2 = 0xFFFFFFFF - 7; - const uint32_t F3 = 0xFFFFFFFF - 8; - const uint32_t F4 = 0xFFFFFFFF - 9; - const uint32_t F5 = 0xFFFFFFFF - 10; - const uint32_t F6 = 0xFFFFFFFF - 11; - const uint32_t F7 = 0xFFFFFFFF - 12; - const uint32_t F8 = 0xFFFFFFFF - 13; - const uint32_t F9 = 0xFFFFFFFF - 14; - const uint32_t F10 = 0xFFFFFFFF - 15; - const uint32_t F11 = 0xFFFFFFFF - 16; - const uint32_t F12 = 0xFFFFFFFF - 17; - const uint32_t SCRLCK = 0xFFFFFFFF - 18; - const uint32_t HOME = 0xFFFFFFFF - 19; - const uint32_t UP = 0xFFFFFFFF - 20; - const uint32_t LEFT = 0xFFFFFFFF - 21; - const uint32_t RIGHT = 0xFFFFFFFF - 22; - const uint32_t DOWN = 0xFFFFFFFF - 23; - const uint32_t PGUP = 0xFFFFFFFF - 24; - const uint32_t PGDOWN = 0xFFFFFFFF - 25; - const uint32_t END = 0xFFFFFFFF - 26; - const uint32_t INS = 0xFFFFFFFF - 27; - const uint32_t DEL = 0xFFFFFFFF - 28; - const uint32_t CAPS = 0xFFFFFFFF - 29; - const uint32_t NONE = 0xFFFFFFFF - 30; - const uint32_t ALTGR = 0xFFFFFFFF - 31; - const uint32_t NUMLCK = 0xFFFFFFFF - 32; - namespace US { uint32_t sg[128] = @@ -647,6 +615,11 @@ namespace Sortix uint8_t LEDs; + size_t keystrokeQueueOffset; + size_t keystrokeQueueUsed; + size_t keystrokeQueueLength; + uint32_t* keystrokeQueue; + void Init() { // Initialize variables. @@ -658,6 +631,30 @@ namespace Sortix // 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"); + } + } + + 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) @@ -671,6 +668,11 @@ namespace Sortix bool KeyUp = (Scancode & 0x80) > 0; + if ( KeyUp ) { CodePoint |= DEPRESSED; } + + QueueKeystroke(CodePoint); + return; + #if PONG Pong::OnKeystroke(CodePoint, KeyUp); return; #endif @@ -683,7 +685,7 @@ namespace Sortix // Use this to debug the exact scancodes you receive! //Log::PrintF("[%u/U+%x]", Scancode, CodePoint); - if ( CodePoint == Layouts::UNKNOWN ) { Log::PrintF("^%u", Scancode);return; } + if ( CodePoint == UNKNOWN ) { Log::PrintF("^%u", Scancode);return; } if ( CodePoint & (1<<31) ) { return; } @@ -704,6 +706,23 @@ namespace Sortix while ( (CPU::InPortB(0x64) & (1<<1)) != 0 ) { } //loop Until zero CPU::OutPortB(0x60, LEDs); } + + void SysReceieveKeystroke(CPU::InterruptRegisters* R) + { + uint32_t codepoint; + if ( keystrokeQueueUsed == 0 ) + { + codepoint = 0; + } + else + { + codepoint = keystrokeQueue[keystrokeQueueOffset]; + keystrokeQueueOffset++; + keystrokeQueueOffset %= keystrokeQueueLength; + keystrokeQueueUsed--; + } + R->eax = codepoint; + } } } diff --git a/sortix/keyboard.h b/sortix/keyboard.h index d6068740..24e7a861 100644 --- a/sortix/keyboard.h +++ b/sortix/keyboard.h @@ -41,6 +41,7 @@ namespace Sortix void Init(); void SetLEDs(uint8_t Toggle); void OnIRQ1(CPU::InterruptRegisters* Regs); + void SysReceieveKeystroke(CPU::InterruptRegisters* R); } } diff --git a/sortix/syscall.cpp b/sortix/syscall.cpp index 0e36950d..16d52be1 100644 --- a/sortix/syscall.cpp +++ b/sortix/syscall.cpp @@ -32,6 +32,7 @@ #include "log.h" #include "panic.h" #include "vga.h" +#include "keyboard.h" namespace Sortix { @@ -48,7 +49,7 @@ namespace Sortix #endif } - const size_t NumSyscalls = 8; + const size_t NumSyscalls = 9; const Syscall Syscalls[NumSyscalls] = { &Scheduler::SysCreateThread, @@ -59,6 +60,7 @@ namespace Sortix &VGA::SysCreateFrame, &VGA::SysChangeFrame, &VGA::SysDeleteFrame, + &Keyboard::SysReceieveKeystroke, }; void Init()