X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FUSB%2FHID%2Fkeyboard.c;h=380518d76df38c68b31f7f1b0311a675908f0e1c;hb=849329d50395b44ac97c5b5145fc2df0749eace2;hp=839bb1e75a3ecfe6d6cbe74ebf5de7bb0eeb46a0;hpb=6f86206a210b05fcbe971b5650a1a179fa0330f5;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/USB/HID/keyboard.c b/KernelLand/Modules/USB/HID/keyboard.c index 839bb1e7..380518d7 100644 --- a/KernelLand/Modules/USB/HID/keyboard.c +++ b/KernelLand/Modules/USB/HID/keyboard.c @@ -6,7 +6,9 @@ * - Keyboard translation */ #define DEBUG 0 +#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,29 @@ 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; // TODO: Detect non-boot keyboards and parse descriptor + Log_Warning("USB HID", "TODO: Handle non-boot keyboards!"); + info->Info = Keyboard_CreateInstance(0, "USBKeyboard"); + } }