From b21ce7f2b5fda2b8eb6156b3073753296ee7296c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 5 Mar 2012 22:07:57 +0800 Subject: [PATCH] Modules/USB HID - Keyboard support! --- KernelLand/Modules/USB/HID/Makefile | 2 +- KernelLand/Modules/USB/HID/keyboard.c | 113 ++++++++++++++++++++------ KernelLand/Modules/USB/HID/main.c | 8 +- 3 files changed, 93 insertions(+), 30 deletions(-) diff --git a/KernelLand/Modules/USB/HID/Makefile b/KernelLand/Modules/USB/HID/Makefile index e862a26b..598c5918 100644 --- a/KernelLand/Modules/USB/HID/Makefile +++ b/KernelLand/Modules/USB/HID/Makefile @@ -2,7 +2,7 @@ # Acess2 HID Driver # -OBJ = main.o mouse.o +OBJ = main.o mouse.o keyboard.o CPPFLAGS = -I../Core/include NAME = HID diff --git a/KernelLand/Modules/USB/HID/keyboard.c b/KernelLand/Modules/USB/HID/keyboard.c index 839bb1e7..59a89b91 100644 --- a/KernelLand/Modules/USB/HID/keyboard.c +++ b/KernelLand/Modules/USB/HID/keyboard.c @@ -5,8 +5,10 @@ * keyboard.c * - Keyboard translation */ -#define DEBUG 0 +#define DEBUG 1 +#include #include +#include "hid_reports.h" #include typedef struct sUSB_Keyboard tUSB_Keyboard; @@ -14,7 +16,17 @@ typedef struct sUSB_Keyboard tUSB_Keyboard; // === STRUCTURES === struct sUSB_Keyboard { + void *Next; // Is this needed? (I think main.c wants it) + tUSB_DataCallback DataAvail; + tKeyboard *Info; + int bIsBoot; + + // Boot keyboard hackery + Uint8 oldmods; + Uint8 oldkeys[6]; + + int CollectionDepth; }; // === PROTOTYPES === @@ -34,7 +46,68 @@ tHID_ReportCallbacks gHID_Kb_ReportCBs = { // === CODE === void HID_Kb_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data) { + tUSB_Keyboard *info; + info = USB_GetDeviceDataPtr(Dev); + + LOG("info = %p", info); + if( info->bIsBoot ) + { + Uint8 *bytes = Data; + Uint8 modchange = bytes[0] ^ info->oldmods; + LOG("modchange = %x", modchange); + // Modifiers + const int firstmod = 224; // from qemu + for( int i = 0; i < 8; i ++ ) + { + if( !(modchange & (1 << i)) ) continue ; + if( bytes[0] & (1 << i) ) { + LOG("mod press %i", firstmod+i); + Keyboard_HandleKey(info->Info, firstmod + i); + } + else { + LOG("mod release %i", firstmod+i); + Keyboard_HandleKey(info->Info, (1 << 31)|(firstmod + i)); + } + } + info->oldmods = bytes[0]; + + // Keycodes + // - Presses + for( int i = 0; i < 6; i ++ ) + { + int j; + Uint8 code = bytes[2+i]; + // Check if the button was pressed before + for( j = 0; j < 6; j ++ ) + { + if( info->oldkeys[j] == code ) + { + info->oldkeys[j] = 0; + break; + } + } + // Press? + if( j == 6 ) { + LOG("press %i", code); + Keyboard_HandleKey(info->Info, (0 << 31)|code); + } + } + // - Check for releases + for( int i = 0; i < 6; i ++ ) + { + if( info->oldkeys[i] ) { + LOG("release %i", info->oldkeys[i]); + Keyboard_HandleKey(info->Info, (1 << 31)|info->oldkeys[i]); + } + } + // - Update state + memcpy(info->oldkeys, bytes+2, 6); + } + else + { + // Oops... TODO: Support non boot keyboards + } } // --- --- @@ -43,40 +116,28 @@ tHID_ReportCallbacks *HID_Kb_Report_Collection( Uint32 Value ) { - tUSB_Keyboard *info; - - info = USB_GetDeviceDataPtr(Dev); - if( !info ) - { - info = malloc( sizeof(tUSB_Keyboard) ); - USB_SetDeviceDataPtr(Dev, info); - info->Keyboard = NULL; - info->CollectionDepth = 1; - } - else - { - info->CollectionDepth ++; - } - return &gHID_Kb_ReportCBs; } void HID_Kb_Report_EndCollection(tUSBInterface *Dev) { - tUSB_Keyboard *info; - - info = USB_GetDeviceDataPtr(Dev); - if( !info ) return ; - - info->CollectionDepth --; - if( info->CollectionDepth == 0 ) - { - info->Keyboard = Keyboard_CreateInstance(0, "USBKeyboard"); - } } void HID_Kb_Report_Input(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value) { + tUSB_Keyboard *info; + info = USB_GetDeviceDataPtr(Dev); + if( !info ) + { + info = malloc( sizeof(tUSB_Keyboard) ); + LOG("info = %p", info); + USB_SetDeviceDataPtr(Dev, info); + info->DataAvail = HID_Kb_DataAvail; + info->Info = NULL; + info->CollectionDepth = 1; + info->bIsBoot = 1; + info->Info = Keyboard_CreateInstance(0, "USBKeyboard"); + } } diff --git a/KernelLand/Modules/USB/HID/main.c b/KernelLand/Modules/USB/HID/main.c index b6a477a3..8fcaa9e7 100644 --- a/KernelLand/Modules/USB/HID/main.c +++ b/KernelLand/Modules/USB/HID/main.c @@ -27,6 +27,7 @@ struct sHID_Device // === IMPORTS === extern tHID_ReportCallbacks gHID_Mouse_ReportCBs; extern tDevFS_Driver gHID_Mouse_DevFS; +extern tHID_ReportCallbacks gHID_Kb_ReportCBs; // === PROTOTYPES === int HID_Initialise(char **Arguments); @@ -79,7 +80,8 @@ void HID_InterruptCallback(tUSBInterface *Dev, int EndPt, int Length, void *Data Log_Error("USB HID", "Device %p doesn't have a data pointer.", Dev); return ; } - + + LOG("Data for %p", info->DataAvail); info->DataAvail(Dev, EndPt, Length, Data); } @@ -206,12 +208,12 @@ tHID_ReportCallbacks *HID_RootCollection( break; case 0x0006: // Keyboard LOG("Desktop->Keyboard"); - break; + return &gHID_Kb_ReportCBs; } break; case 0x0007: // Keyboard / Keypad LOG("Keyboard"); - break; + return &gHID_Kb_ReportCBs; } return NULL; } -- 2.20.1