/*
- * Acess2 Kernel - Keyboard Character Mappings
+ * Acess2 Kernel - Keyboard Driver
* - By John Hodge (thePowersGang)
*
* main.c
- * - Core keyboard multiplexer
+ * - Keyboard driver core
*
* TODO: Make the key transation code more general (for non-US layouts)
* TODO: Support multiple virtual keyboards
#include <Input/Keyboard/include/keyboard.h>
#include "keymap_int.h"
#include "layout_kbdus.h"
+#include <debug_hooks.h>
#define USE_KERNEL_MAGIC 1
-// === IMPORTS ===
-#if USE_KERNEL_MAGIC
-extern void Threads_ToggleTrace(int TID);
-extern void Threads_Dump(void);
-extern void Heap_Stats(void);
-#endif
+extern void Validate_VirtualMemoryUsage(void);
// === PROTOTYPES ===
int Keyboard_Install(char **Arguments);
-void Keyboard_Cleanup(void);
+ int Keyboard_Cleanup(void);
// - Internal
tKeymap *Keyboard_LoadMap(const char *Name);
void Keyboard_FreeMap(tKeymap *Keymap);
-// - User side
+// - "User" side (Actually VT)
int Keyboard_IOCtl(tVFS_Node *Node, int ID, void *Data);
// - Device Side
tKeyboard *Keyboard_CreateInstance(int MaxSym, const char *Name);
{ .Type = &gKB_NodeType }
};
#if USE_KERNEL_MAGIC
- int giKB_MagicAddress = 0;
- int giKB_MagicAddressPos = 0;
+tDebugHook gKB_DebugHookInfo;
#endif
// === CODE ===
+/**
+ * \brief Initialise the keyboard driver
+ */
int Keyboard_Install(char **Arguments)
{
+ /// - Register with DevFS
DevFS_AddDevice( &gKB_DevInfo );
return 0;
}
-void Keyboard_Cleanup(void)
+/**
+ * \brief Pre-unload cleanup function
+ */
+int Keyboard_Cleanup(void)
{
// TODO: Do I need this?
+ return 0;
}
-tKeymap *Keyboard_LoadMap(const char *Name)
+// --- Map Management ---
+/**
+ * \brief Load an arbitary keyboard map
+ * \param Name Keymap name (e.g. "en-us")
+ * \return Keymap pointer
+ */
+tKeymap *Keyboard_int_LoadMap(const char *Name)
{
+ Log_Warning("Keyboard", "TOD: Impliment Keyboard_int_LoadMap");
return NULL;
}
-void Keyboard_FreeMap(tKeymap *Keymap)
+/**
+ * \brief Unload a keyboard map
+ * \param Keymap Keymap to unload/free
+ */
+void Keyboard_int_FreeMap(tKeymap *Keymap)
{
}
// --- VFS Interface ---
static const char *csaIOCTL_NAMES[] = {DRV_IOCTLNAMES, DRV_KEYBAORD_IOCTLNAMES, NULL};
+/**
+ * \brief Keyboard IOCtl
+ */
int Keyboard_IOCtl(tVFS_Node *Node, int Id, void *Data)
{
switch(Id)
}
// --- Device Interface ---
+/*
+ * Create a new keyboard device instance
+ * TODO: Allow linking to other VFS nodes
+ * See Input/Keyboard/include/keyboard.h
+ */
tKeyboard *Keyboard_CreateInstance(int MaxSym, const char *Name)
{
tKeyboard *ret;
return ret;
}
+/*
+ * Destroy a keyboard instance
+ * - See Input/Keyboard/include/keyboard.h
+ */
void Keyboard_RemoveInstance(tKeyboard *Instance)
{
// TODO: Implement
Log_Error("Keyboard", "TODO: Implement Keyboard_RemoveInstance");
}
+inline bool IsPressed(tKeyboard *Kb, Uint8 KeySym)
+{
+ return !!(Kb->KeyStates[KeySym/8] & (1 << (KeySym&7)));
+}
+
+/*
+ * Handle a key press/release event
+ * - See Input/Keyboard/include/keyboard.h
+ */
void Keyboard_HandleKey(tKeyboard *Source, Uint32 HIDKeySym)
{
int bPressed;
Uint32 flag;
Uint8 layer;
+ if( !Source ) {
+ Log_Error("Keyboard", "Passed NULL handle");
+ return ;
+ }
+ if( !Source->Node ) {
+ Log_Error("Keyboard", "Passed handle with NULL node");
+ return ;
+ }
+
bPressed = !(HIDKeySym & (1 << 31));
HIDKeySym &= 0x7FFFFFFF;
- // Determine action
+ // - Determine the action (Press, Release or Refire)
{
Uint8 mask = 1 << (HIDKeySym&7);
int ofs = HIDKeySym / 8;
else
Source->KeyStates[ ofs ] &= ~mask;
- // Get the action (Press, Refire or Release)
+ // Get the final flag
if( bPressed )
{
if( !oldstate && !otherstate )
if( !otherstate )
flag = KEY_ACTION_RELEASE; // Up
else
- flag = -1 ; // Do nothing
+ flag = -1; // Do nothing
}
}
// TODO: Support non-trivial layouts
layer = !!(Source->State & 3);
- // Send raw symbol
+ // Do translation
if( flag == KEY_ACTION_RELEASE )
trans = 0;
else {
trans = Source->Keymap->Layers[0]->Sym[HIDKeySym];
}
+ // Call callback (only if the action is valid)
if( flag != -1 )
{
tKeybardCallback Callback = (void*)Source->Node->ImplInt;
break;
}
- // --- Check for Kernel Magic Combos
+ // Magic debug hooks
#if USE_KERNEL_MAGIC
- if(Source->KeyStates[KEYSYM_LEFTCTRL/8] & (1 << (KEYSYM_LEFTCTRL&7))
- && Source->KeyStates[KEYSYM_LEFTALT/8] & (1 << (KEYSYM_LEFTALT &7)) )
+ if(bPressed && IsPressed(Source, KEYSYM_LEFTCTRL) && IsPressed(Source, KEYSYM_LEFTALT))
+ {
+ if( trans == '~' ) {
+ // TODO: Latch mode
+ }
+ else {
+ char str[5]; // utf8 only supports 8 bytes
+ size_t len = WriteUTF8((Uint8*)str, trans);
+ str[len] = '\0';
+ DebugHook_HandleInput(&gKB_DebugHookInfo, len, str);
+ }
+ return ;
+ }
+ #endif
+
+ // Ctrl-Alt-Del == Reboot
+ #if defined(ARCHDIR_is_x86) || defined(ARCHDIR_is_x86_64)
+ if(bPressed
+ && (IsPressed(Source, KEYSYM_LEFTCTRL) || IsPressed(Source, KEYSYM_RIGHTCTRL))
+ && (IsPressed(Source, KEYSYM_LEFTALT) || IsPressed(Source, KEYSYM_LEFTALT))
+ )
{
- int val;
- switch(trans)
+ if( HIDKeySym == KEYSYM_DELETE )
{
- case '0': val = 0; goto _av; case '1': val = 1; goto _av;
- case '2': val = 2; goto _av; case '3': val = 3; goto _av;
- case '4': val = 4; goto _av; case '5': val = 5; goto _av;
- case '6': val = 6; goto _av; case '7': val = 7; goto _av;
- case '8': val = 8; goto _av; case '9': val = 9; goto _av;
- case 'a': val = 10; goto _av; case 'b': val = 11; goto _av;
- case 'c': val = 12; goto _av; case 'd': val = 13; goto _av;
- case 'e': val = 14; goto _av; case 'f': val = 15; goto _av;
- _av:
- if(giKB_MagicAddressPos == BITS/4) break;
- giKB_MagicAddress |= (Uint)val << giKB_MagicAddressPos;
- giKB_MagicAddressPos ++;
- break;
-
- // Instruction Tracing
- case 't':
- Log("Toggle instruction tracing on %i\n", giKB_MagicAddress);
- Threads_ToggleTrace( giKB_MagicAddress );
- giKB_MagicAddress = 0; giKB_MagicAddressPos = 0;
- return;
-
- // Thread List Dump
- case 'p': Threads_Dump(); return;
- // Heap Statistics
- case 'h': Heap_Stats(); return;
- // Dump Structure
- case 's': return;
+ // Trigger triple fault
+ __asm__ __volatile__ ("lgdt (%esp) ; int $0x0");
+ for(;;);
}
}
#endif