2 * Acess2 Kernel - Mouse Mulitplexing Driver
3 * - By John Hodge (thePowersGang)
9 #define VERSION VER2(0,1)
13 #include <Input/Mouse/include/mouse.h>
14 #include "include/mouse_int.h"
17 int Mouse_Install(char **Arguments);
18 int Mouse_Cleanup(void);
20 int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
21 tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
22 int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
23 size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data, Uint Flags);
25 tMouse *Mouse_Register(const char *Name, int NumButtons, int NumAxies);
26 void Mouse_RemoveInstance(tMouse *Handle);
27 void Mouse_HandleEvent(tMouse *Handle, Uint32 ButtonState, int *AxisDeltas);
30 MODULE_DEFINE(0, VERSION, Mouse, Mouse_Install, Mouse_Cleanup, NULL);
31 tVFS_NodeType gMouse_RootNodeType = {
32 .ReadDir = Mouse_Root_ReadDir,
33 .FindDir = Mouse_Root_FindDir
35 tVFS_NodeType gMouse_DevNodeType = {
36 .IOCtl = Mouse_Dev_IOCtl,
37 .Read = Mouse_Dev_Read
39 tDevFS_Driver gMouse_DevInfo = {
41 { .Flags = VFS_FFLAG_DIRECTORY, .Type = &gMouse_RootNodeType, .Size = 1 }
43 tPointer gMouse_Pointer;
47 * \brief Initialise the keyboard driver
49 int Mouse_Install(char **Arguments)
51 /// - Register with DevFS
52 DevFS_AddDevice( &gMouse_DevInfo );
54 gMouse_Pointer.Node.Type = &gMouse_DevNodeType;
55 gMouse_Pointer.Node.ImplPtr = &gMouse_Pointer;
56 gMouse_Pointer.FileHeader = (void*)gMouse_Pointer.FileData;
57 gMouse_Pointer.Axies = (void*)( gMouse_Pointer.FileHeader + 1 );
63 * \brief Pre-unload cleanup function
65 int Mouse_Cleanup(void)
70 // --- VFS Interface ---
71 int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
75 strcpy(Dest, "system");
79 tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
81 if( strcmp(Name, "system") != 0 ) return NULL;
82 return &gMouse_Pointer.Node;
85 static const char *csaIOCTL_NAMES[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
87 * \brief IOCtl handler for the mouse
89 int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
91 tJoystick_NumValue *numval = Data;
92 tPointer *ptr = Node->ImplPtr;
95 BASE_IOCTLS(DRV_TYPE_MOUSE, "Mouse", VERSION, csaIOCTL_NAMES);
97 case JOY_IOCTL_GETSETAXISLIMIT:
98 if( !numval || !CheckMem(numval, sizeof(*numval)) )
100 LOG("GetSetAxisLimit %i = %i", numval->Num, numval->Value);
101 if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
103 if(numval->Value != -1)
104 ptr->AxisLimits[numval->Num] = numval->Value;
105 return ptr->AxisLimits[numval->Num];
107 case JOY_IOCTL_GETSETAXISPOSITION:
108 if( !numval || !CheckMem(numval, sizeof(*numval)) )
110 if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
112 if(numval->Value != -1)
113 ptr->Axies[numval->Num].CursorPos = numval->Value;
114 return ptr->Axies[numval->Num].CursorPos;
120 * \brief Read from a device
122 size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data, Uint Flags)
124 tPointer *ptr = Node->ImplPtr;
125 int n_buttons = ptr->FileHeader->NButtons;
126 int n_axies = ptr->FileHeader->NAxies;
128 ENTER("pNode iLength pData", Node, Length, Data);
130 // TODO: Locking (Acquire)
134 sizeof(tJoystick_FileHeader) + n_axies*sizeof(tJoystick_Axis) + n_buttons
138 VFS_MarkAvaliable( Node, 0 );
140 // Check if more than the header is requested
141 if( Length > sizeof(tJoystick_FileHeader) )
143 // Clear axis values and button states
144 for( int i = 0; i < n_axies; i ++ )
145 ptr->Axies[i].CurValue = 0;
146 for( int i = 0; i < n_buttons; i ++ )
149 // Rebuild from device list
150 for( tMouse *dev = ptr->FirstDev; dev; dev = dev->Next )
152 for( int i = 0; i < n_axies; i ++ )
153 ptr->Axies[i].CurValue += dev->LastAxisVal[i];
154 for( int i = 0; i < n_buttons; i ++ )
156 if( dev->ButtonState & (1 << i) )
157 ptr->Buttons[i] = 255;
162 memcpy( Data, ptr->FileData, Length );
164 // TODO: Locking (Release)
170 // --- Device Interface ---
172 * Register an input device
173 * - See Input/Mouse/include/mouse.h
175 tMouse *Mouse_Register(const char *Name, int NumButtons, int NumAxies)
180 // TODO: Multiple pointers?
181 target = &gMouse_Pointer;
183 if( NumButtons > MAX_BUTTONS )
184 NumButtons = MAX_BUTTONS;
185 if( NumAxies > MAX_AXIES )
186 NumAxies = MAX_AXIES;
188 ret = malloc( sizeof(tMouse) + sizeof(ret->LastAxisVal[0])*NumAxies );
190 Log_Error("Mouse", "malloc() failed");
194 ret->Pointer = target;
195 ret->NumAxies = NumAxies;
196 ret->NumButtons = NumButtons;
197 ret->ButtonState = 0;
198 memset(ret->LastAxisVal, 0, sizeof(ret->LastAxisVal[0])*NumAxies );
202 ret->Next = target->FirstDev;
203 target->FirstDev = ret;
204 if( ret->NumAxies > target->FileHeader->NAxies ) {
205 // Clear new axis data
207 target->Axies + target->FileHeader->NAxies,
209 (ret->NumAxies - target->FileHeader->NAxies)/sizeof(tJoystick_Axis)
211 target->FileHeader->NAxies = ret->NumAxies;
212 target->Buttons = (void*)( target->Axies + ret->NumAxies );
214 if( ret->NumButtons > target->FileHeader->NButtons ) {
215 // No need to move as buttons can expand out into space
216 target->FileHeader->NButtons = ret->NumButtons;
224 * Remove a mouse instance
225 * - See Input/Mouse/include/mouse.h
227 void Mouse_RemoveInstance(tMouse *Instance)
232 * Handle a mouse event (movement or button press/release)
233 * - See Input/Mouse/include/mouse.h
235 void Mouse_HandleEvent(tMouse *Handle, Uint32 ButtonState, int *AxisDeltas)
239 ENTER("pHandle xButtonState pAxisDeltas", Handle, ButtonState, AxisDeltas);
241 ptr = Handle->Pointer;
243 // Update device state
244 Handle->ButtonState = ButtonState;
245 memcpy(Handle->LastAxisVal, AxisDeltas, sizeof(*AxisDeltas)*Handle->NumAxies);
247 // Update cursor position
248 // TODO: Acceleration?
249 for( int i = 0; i < Handle->NumAxies; i ++ )
251 ptr->Axies[i].CursorPos = MIN(MAX(0, ptr->Axies[i].CursorPos+AxisDeltas[i]), ptr->AxisLimits[i]);
252 LOG("Axis %i: delta = %i, pos = %i", i, AxisDeltas[i], ptr->Axies[i].CursorPos);
255 VFS_MarkAvaliable( &ptr->Node, 1 );