// - 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);
--- /dev/null
+# Mouse Multiplexer
+
+OBJ = main.o
+NAME = Mouse
+
+-include ../Makefile.tpl
+
--- /dev/null
+/*
+ * Acess2 Kernel - Mouse Mulitplexing Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * include/mouse.h
+ * - Mouse mulitplexing interface header
+ */
+#ifndef _MOUSE__MOUSE_H_
+#define _MOUSE__MOUSE_H_
+
+typedef struct sMouse tMouse;
+
+tMouse *Mouse_Register(const char *Name, int NumButtons, int NumAxies);
+void Mouse_RemoveInstance(tMouse *Handle);
+void Mouse_HandleEvent(tMouse *Handle, Uint32 ButtonState, int AxisDeltas[4]);
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 Kernel - Mouse Mulitplexing Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * include/mouse_int.h
+ * - Mouse mulitplexing interface header
+ */
+#ifndef _MOUSE__MOUSE_INT_H_
+#define _MOUSE__MOUSE_INT_H_
+
+#include <api_drv_joystick.h>
+
+typedef struct sPointer tPointer;
+
+/*
+ * \brief Input device type (doesn't hold much)
+ */
+struct sMouse
+{
+ tMouse *Next;
+ tPointer *Pointer;
+ int NumButtons;
+ int NumAxies;
+ Uint32 ButtonState;
+ int LastAxisVal[];
+};
+
+#define MAX_BUTTONS 6
+#define MAX_AXIES 4
+#define MAX_FILESIZE (sizeof(tJoystick_FileHeader) + MAX_AXIES*sizeof(tJoystick_Axis) + MAX_BUTTONS)
+
+/**
+ */
+struct sPointer
+{
+ tPointer *Next;
+
+ tMouse *FirstDev;
+
+ // Node
+ tVFS_Node Node;
+
+ // Data
+ Uint8 FileData[MAX_FILESIZE];
+ tJoystick_FileHeader *FileHeader;
+ tJoystick_Axis *Axies;
+ Uint8 *Buttons;
+
+ // Limits for axis positions
+ Uint16 AxisLimits[MAX_AXIES];
+};
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 Kernel - Mouse Mulitplexing Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Mouse mulitplexing
+ */
+#define DEBUG 0
+#define VERSION VER2(0,1)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <Input/Mouse/include/mouse.h>
+#include "include/mouse_int.h"
+
+// === PROTOTYPES ===
+ int Mouse_Install(char **Arguments);
+void Mouse_Cleanup(void);
+// - "User" side
+char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
+ int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
+size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data);
+// - Device Side
+tMouse *Mouse_Register(const char *Name, int NumButtons, int NumAxies);
+void Mouse_RemoveInstance(tMouse *Handle);
+void Mouse_HandleEvent(tMouse *Handle, Uint32 ButtonState, int *AxisDeltas);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, Mouse, Mouse_Install, Mouse_Cleanup, NULL);
+tVFS_NodeType gMouse_RootNodeType = {
+ .ReadDir = Mouse_Root_ReadDir,
+ .FindDir = Mouse_Root_FindDir
+};
+tVFS_NodeType gMouse_DevNodeType = {
+ .IOCtl = Mouse_Dev_IOCtl,
+ .Read = Mouse_Dev_Read
+};
+tDevFS_Driver gMouse_DevInfo = {
+ NULL, "Mouse",
+ { .Flags = VFS_FFLAG_DIRECTORY, .Type = &gMouse_RootNodeType }
+};
+tPointer gMouse_Pointer;
+
+// === CODE ===
+/**
+ * \brief Initialise the keyboard driver
+ */
+int Mouse_Install(char **Arguments)
+{
+ /// - Register with DevFS
+ DevFS_AddDevice( &gMouse_DevInfo );
+
+ gMouse_Pointer.Node.Type = &gMouse_DevNodeType;
+ gMouse_Pointer.Node.ImplPtr = &gMouse_Pointer;
+
+ return 0;
+}
+
+/**
+ * \brief Pre-unload cleanup function
+ */
+void Mouse_Cleanup(void)
+{
+}
+
+// --- VFS Interface ---
+char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos)
+{
+ if( Pos != 0 ) return NULL;
+ return strdup("system");
+}
+
+tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
+{
+ if( strcmp(Name, "system") != 0 ) return NULL;
+ return &gMouse_Pointer.Node;
+}
+
+static const char *csaIOCTL_NAMES[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
+/**
+ * \brief IOCtl handler for the mouse
+ */
+int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+ tJoystick_NumValue *numval = Data;
+ tPointer *ptr = Node->ImplPtr;
+ switch(ID)
+ {
+ BASE_IOCTLS(DRV_TYPE_MOUSE, "Mouse", VERSION, csaIOCTL_NAMES);
+
+ case JOY_IOCTL_GETSETAXISLIMIT:
+ if( !numval || !CheckMem(numval, sizeof(*numval)) )
+ return -1;
+ if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
+ return 0;
+ if(numval->Value != -1)
+ ptr->AxisLimits[numval->Num] = numval->Value;
+ return ptr->AxisLimits[numval->Num];
+
+ case JOY_IOCTL_GETSETAXISPOSITION:
+ if( !numval || !CheckMem(numval, sizeof(*numval)) )
+ return -1;
+ if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
+ return 0;
+ if(numval->Value != -1)
+ ptr->Axies[numval->Num].CursorPos = numval->Value;
+ return ptr->Axies[numval->Num].CursorPos;
+ }
+ return -1;
+}
+
+/**
+ * \brief Read from a device
+ */
+size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data)
+{
+ tPointer *ptr = Node->ImplPtr;
+ int n_buttons = ptr->FileHeader->NButtons;
+ int n_axies = ptr->FileHeader->NAxies;
+
+ // TODO: Locking (Acquire)
+
+ Length = MIN(
+ Length,
+ sizeof(tJoystick_FileHeader) + n_axies*sizeof(tJoystick_Axis) + n_buttons
+ );
+
+ // Mark as checked
+ VFS_MarkAvaliable( Node, 0 );
+
+ // Check if more than the header is requested
+ if( Length > sizeof(tJoystick_FileHeader) )
+ {
+ // Clear axis values and button states
+ for( int i = 0; i < n_axies; i ++ )
+ ptr->Axies[i].CurValue = 0;
+ for( int i = 0; i < n_buttons; i ++ )
+ ptr->Buttons[i] = 0;
+
+ // Rebuild from device list
+ for( tMouse *dev = ptr->FirstDev; dev; dev = dev->Next )
+ {
+ for( int i = 0; i < n_axies; i ++ )
+ ptr->Axies[i].CurValue += dev->LastAxisVal[i];
+ for( int i = 0; i < n_buttons; i ++ )
+ {
+ if( dev->ButtonState & (1 << i) )
+ ptr->Buttons[i] = 255;
+ }
+ }
+ }
+
+ memcpy( Data, ptr->FileData, Length );
+
+ // TODO: Locking (Release)
+
+ return Length;
+}
+
+// --- Device Interface ---
+/*
+ * Register an input device
+ * - See Input/Mouse/include/mouse.h
+ */
+tMouse *Mouse_Register(const char *Name, int NumButtons, int NumAxies)
+{
+ tPointer *target;
+ tMouse *ret;
+
+ // TODO: Multiple pointers?
+ target = &gMouse_Pointer;
+
+ if( NumButtons > MAX_BUTTONS )
+ NumButtons = MAX_BUTTONS;
+ if( NumAxies > MAX_AXIES )
+ NumAxies = MAX_AXIES;
+
+ ret = malloc( sizeof(tMouse) + sizeof(ret->LastAxisVal[0])*NumAxies );
+ if(!ret) {
+ Log_Error("Mouse", "malloc() failed");
+ return NULL;
+ }
+ ret->Next = NULL;
+ ret->Pointer = target;
+ ret->NumAxies = NumAxies;
+ ret->NumButtons = NumButtons;
+ ret->ButtonState = 0;
+ memset(ret->LastAxisVal, 0, sizeof(ret->LastAxisVal[0])*NumAxies );
+
+ // Add
+ // TODO: Locking
+ ret->Next = target->FirstDev;
+ target->FirstDev = ret;
+ if( ret->NumAxies <= MAX_AXIES && ret->NumAxies > target->FileHeader->NAxies ) {
+ // Clear new axis data
+ memset(
+ target->Axies + target->FileHeader->NAxies,
+ 0,
+ (ret->NumAxies - target->FileHeader->NAxies)/sizeof(tJoystick_Axis)
+ );
+ target->FileHeader->NAxies = ret->NumAxies;
+ target->Buttons = (void*)( target->Axies + ret->NumAxies );
+ }
+ if( ret->NumButtons <= MAX_BUTTONS && ret->NumButtons > target->FileHeader->NButtons ) {
+ // No need to move as buttons can expand out into space
+ target->FileHeader->NButtons = ret->NumButtons;
+ }
+ // TODO: Locking
+
+ return ret;
+}
+
+/*
+ * Remove a mouse instance
+ * - See Input/Mouse/include/mouse.h
+ */
+void Mouse_RemoveInstance(tMouse *Instance)
+{
+}
+
+/*
+ * Handle a mouse event (movement or button press/release)
+ * - See Input/Mouse/include/mouse.h
+ */
+void Mouse_HandleEvent(tMouse *Handle, Uint32 ButtonState, int *AxisDeltas)
+{
+ tPointer *ptr = Handle->Pointer;
+
+ Handle->ButtonState = ButtonState;
+
+ memcpy(Handle->LastAxisVal, AxisDeltas, sizeof(*AxisDeltas)*Handle->NumAxies);
+
+ // TODO: Acceleration?
+
+ for( int i = 0; i < Handle->NumAxies; i ++ )
+ {
+ ptr->Axies[i].CursorPos = MIN(MAX(0, ptr->Axies[i].CursorPos+AxisDeltas[i]), ptr->AxisLimits[i]);
+ }
+ VFS_MarkAvaliable( &ptr->Node, 1 );
+}
+
* keyboard.c
* - Keyboard translation
*/
-#define DEBUG 1
+#define DEBUG 0
#include <acess.h>
#include <fs_devfs.h>
#include "hid_reports.h"
info->DataAvail = HID_Kb_DataAvail;
info->Info = NULL;
info->CollectionDepth = 1;
- info->bIsBoot = 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");
}
}
// === IMPORTS ===
extern tHID_ReportCallbacks gHID_Mouse_ReportCBs;
-extern tDevFS_Driver gHID_Mouse_DevFS;
extern tHID_ReportCallbacks gHID_Kb_ReportCBs;
// === PROTOTYPES ===
static void _FreeList(struct sHID_IntList *List);
// === GLOBALS ===
-MODULE_DEFINE(0, VERSION, USB_HID, HID_Initialise, NULL, "USB_Core", NULL);
+MODULE_DEFINE(0, VERSION, USB_HID, HID_Initialise, NULL, "USB_Core", "Keyboard", "Mouse", NULL);
tUSBDriver gHID_USBDriver = {
.Name = "HID",
.Match = {.Class = {0x030000, 0xFF0000}},
{
USB_RegisterDriver( &gHID_USBDriver );
- DevFS_AddDevice( &gHID_Mouse_DevFS );
-
return 0;
}
#include <acess.h>
#include "hid_reports.h"
#include <fs_devfs.h>
-#include <api_drv_joystick.h>
+#include <Input/Mouse/include/mouse.h>
// === CONSTANTS ===
#define MAX_AXIES 3 // X, Y, Scroll
#define MAX_BUTTONS 5 // Left, Right, Middle, ...
-#define FILE_SIZE (sizeof(tJoystick_FileHeader) + MAX_AXIES*sizeof(tJoystick_Axis) + MAX_BUTTONS)
// === TYPES ===
typedef struct sHID_Mouse tHID_Mouse;
tHID_Mouse *Next;
tUSB_DataCallback DataAvail;
- // VFS Node
- tVFS_Node Node;
+ tMouse *Handle;
- // Joystick Spec data
- Uint8 FileData[ FILE_SIZE ];
- tJoystick_FileHeader *FileHeader;
- tJoystick_Axis *Axies;
- Uint8 *Buttons;
-
- // Limits for axis positions
- Uint16 AxisLimits[MAX_AXIES];
-
// - Report parsing
int nMappings;
struct {
};
// === PROTOTYES ===
-char *HID_Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node *HID_Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
-size_t HID_Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
- int HID_Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
-void HID_Mouse_Dev_Reference(tVFS_Node *Node);
-void HID_Mouse_Dev_Close(tVFS_Node *Node);
-
+Sint32 _ReadBits(void *Data, int Offset, int Length);
void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data);
tHID_ReportCallbacks *HID_Mouse_Report_Collection(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
void HID_Mouse_Report_Input(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
// === GLOBALS ===
-tVFS_NodeType gHID_Mouse_RootNodeType = {
- .TypeName = "HID Mouse Root",
- .ReadDir = HID_Mouse_Root_ReadDir,
- .FindDir = HID_Mouse_Root_FindDir
-};
-tVFS_NodeType gHID_Mouse_DevNodeType = {
- .TypeName = "HID Mouse Dev",
- .Read = HID_Mouse_Dev_Read,
- .IOCtl = HID_Mouse_Dev_IOCtl,
- .Reference = HID_Mouse_Dev_Reference,
- .Close = HID_Mouse_Dev_Close,
-};
-tDevFS_Driver gHID_Mouse_DevFS = {
- .Name = "USBMouse",
- .RootNode = {
- .Type = &gHID_Mouse_RootNodeType,
- .Flags = VFS_FFLAG_DIRECTORY
- }
-};
tHID_ReportCallbacks gHID_Mouse_ReportCBs = {
.Collection = HID_Mouse_Report_Collection,
.EndCollection = HID_Mouse_Report_EndCollection,
tHID_Mouse *gpHID_LastMouse = (tHID_Mouse*)&gpHID_FirstMouse;
// === CODE ===
-// ----------------------------------------------------------------------------
-// VFS Interface
-// ----------------------------------------------------------------------------
-char *HID_Mouse_Root_ReadDir(tVFS_Node *Node, int Pos)
-{
- char data[3];
- if(Pos < 0 || Pos >= Node->Size) return NULL;
-
- snprintf(data, 3, "%i", Pos);
- return strdup(data);
-}
-
-tVFS_Node *HID_Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
-{
- int ID;
- int ofs;
- tHID_Mouse *mouse;
-
- if( Name[0] == '\0' )
- return NULL;
-
- ofs = ParseInt(Name, &ID);
- if( ofs == 0 || Name[ofs] != '\0' )
- return NULL;
-
- // Scan list, locate item
- Mutex_Acquire(&glHID_MouseListLock);
- for( mouse = gpHID_FirstMouse; mouse && ID --; mouse = mouse->Next ) ;
- if( mouse )
- mouse->Node.ReferenceCount ++;
- Mutex_Release(&glHID_MouseListLock);
-
- if( mouse )
- return &mouse->Node;
- else
- return NULL;
-}
-
-size_t HID_Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
-{
- tHID_Mouse *info = Node->ImplPtr;
-
- if( Offset > FILE_SIZE ) return 0;
-
- if( Length > FILE_SIZE ) Length = FILE_SIZE;
- if( Offset + Length > FILE_SIZE ) Length = FILE_SIZE - Offset;
-
- memcpy( Buffer, info->FileData + Offset, Length );
-
- VFS_MarkAvaliable( &info->Node, 0 );
-
- return Length;
-}
-
-static const char *csaDevIOCtls[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
-int HID_Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
-{
- tJoystick_NumValue *numval = Data;
- tHID_Mouse *info = Node->ImplPtr;
- switch(ID)
- {
- BASE_IOCTLS(DRV_TYPE_JOYSTICK, "USBMouse", 0x050, csaDevIOCtls);
-
- case JOY_IOCTL_GETSETAXISLIMIT:
- if( !numval || !CheckMem(numval, sizeof(*numval)) )
- return -1;
- if(numval->Num < 0 || numval->Num >= MAX_AXIES)
- return 0;
- if(numval->Value != -1)
- info->AxisLimits[numval->Num] = numval->Value;
- return info->AxisLimits[numval->Num];
-
- case JOY_IOCTL_GETSETAXISPOSITION:
- if( !numval || !CheckMem(numval, sizeof(*numval)) )
- return -1;
- if(numval->Num < 0 || numval->Num >= MAX_AXIES)
- return 0;
- if(numval->Value != -1)
- info->Axies[numval->Num].CursorPos = numval->Value;
- return info->Axies[numval->Num].CursorPos;
- }
- return -1;
-}
-void HID_Mouse_Dev_Reference(tVFS_Node *Node)
-{
- Node->ReferenceCount ++;
-}
-void HID_Mouse_Dev_Close(tVFS_Node *Node)
-{
- Node->ReferenceCount --;
-}
-
// ----------------------------------------------------------------------------
// Data input / Update
// ----------------------------------------------------------------------------
{
tHID_Mouse *info;
int ofs;
+ Uint32 button_value = 0;
+ int axis_values[MAX_AXIES] = {0};
info = USB_GetDeviceDataPtr(Dev);
if( !info ) return ;
if( dest & 0x80 )
{
// Axis
- info->Axies[ dest & 0x7F ].CurValue = value;
- LOG("Axis %i = %i", dest & 0x7F, info->Axies[dest & 0x7F].CurValue);
+ axis_values[ dest & 0x7F ] = value;
+ LOG("Axis %i = %i", dest & 0x7F, value);
}
else
{
// Button
- info->Buttons[ dest & 0x7F ] = (value == 0) ? 0 : 0xFF;
- LOG("Button %i = %x", dest & 0x7F, info->Buttons[dest & 0x7F]);
+ if( value == 0 )
+ ;
+ else
+ button_value |= 1 << (dest & 0x7F);
}
}
- // Update axis positions
- for( int i = 0; i < MAX_AXIES; i ++ )
- {
- int newpos;
-
- // TODO: Scaling
- newpos = info->Axies[i].CursorPos + info->Axies[i].CurValue;
-
- if(newpos < 0) newpos = 0;
- if(newpos > info->AxisLimits[i]) newpos = info->AxisLimits[i];
-
- info->Axies[i].CursorPos = newpos;
- }
-// Log_Debug("USBMouse", "New Pos (%i,%i,%i)",
-// info->Axies[0].CursorPos, info->Axies[1].CursorPos, info->Axies[2].CursorPos
-// );
- VFS_MarkAvaliable( &info->Node, 1 );
+ Mouse_HandleEvent(info->Handle, button_value, axis_values);
}
// ----------------------------------------------------------------------------
// New device!
info = calloc( sizeof(tHID_Mouse), 1 );
info->DataAvail = HID_Mouse_DataAvail;
- info->Node.ImplPtr = info;
- info->Node.Type = &gHID_Mouse_DevNodeType;
-
- info->FileHeader = (void*)info->FileData;
- info->Axies = (void*)(info->FileHeader + 1);
- info->Buttons = (void*)(info->Axies + MAX_AXIES);
- info->FileHeader->NAxies = MAX_AXIES;
- info->FileHeader->NButtons = MAX_BUTTONS;
-
- for( int i = 0; i < MAX_AXIES; i ++ ) {
- info->Axies[i].MinValue = -10;
- info->Axies[i].MaxValue = 10;
- }
-
+
+ info->Handle = Mouse_Register("USBMouse", MAX_BUTTONS, MAX_AXIES);
LOG("Initialised new mouse at %p", info);
Mutex_Acquire(&glHID_MouseListLock);
gpHID_LastMouse->Next = info;
gpHID_LastMouse = info;
- gHID_Mouse_DevFS.RootNode.Size ++;
Mutex_Release(&glHID_MouseListLock);
}
else
// --- Update Min/Max for Axies ---
// TODO: DPI too
- if( tag != 0xFF && (tag & 0x80) )
- {
- info->Axies[ tag & 0x7F ].MinValue = Min;
- info->Axies[ tag & 0x7F ].MaxValue = Max;
- }
+ // TODO: Pass to mouse multiplexer
+// if( tag != 0xFF && (tag & 0x80) )
+// {
+// info->Axies[ tag & 0x7F ].MinValue = Min;
+// info->Axies[ tag & 0x7F ].MaxValue = Max;
+// }
}
/**
include $(ACESSDIR)/BuildConf/$(ARCH)/$(PLATFORM).mk
-MODULES += Input/Keyboard
+MODULES += Input/Keyboard Input/Mouse
MODULES += IPStack # So the other modules are loaded before it
#DYNMODS := USB/Core
#DYNMODS += Filesystems/InitRD