Usermode/libaxwin4 - Handle demarshal failure
[tpg/acess2.git] / KernelLand / Modules / USB / HID / keyboard.c
index 90ad63f..6a473c6 100644 (file)
@@ -6,9 +6,139 @@
  * - Keyboard translation
  */
 #define DEBUG  0
+#include <acess.h>
 #include <fs_devfs.h>
+#include "hid_reports.h"
+#include <Input/Keyboard/include/keyboard.h>
+
+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 ===
+void   HID_Kb_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data);
+
+tHID_ReportCallbacks   *HID_Kb_Report_Collection(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
+void   HID_Kb_Report_EndCollection(tUSBInterface *Dev);
+void   HID_Kb_Report_Input(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
 
 // === GLOBALS ===
-tDevFS_Driver  gHID_DevFS_Keyboard = {
-       .Name = "USBKeyboard",
+tHID_ReportCallbacks   gHID_Kb_ReportCBs = {
+       .Collection = HID_Kb_Report_Collection,
+       .EndCollection = HID_Kb_Report_EndCollection,
+       .Input = HID_Kb_Report_Input
 };
+
+// === 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
+       }
+}
+
+// --- ---
+tHID_ReportCallbacks *HID_Kb_Report_Collection(
+       tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local,
+       Uint32 Value
+       )
+{
+       return &gHID_Kb_ReportCBs;
+}
+
+void HID_Kb_Report_EndCollection(tUSBInterface *Dev)
+{
+}
+
+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: Detect and handle non-boot keyboards!");
+               info->Info = Keyboard_CreateInstance(0, "USBKeyboard");
+       }
+}
+

UCC git Repository :: git.ucc.asn.au