Modules - Use short command annotation in makefile ([CC] not $(CC))
[tpg/acess2.git] / AcessNative / acesskernel_src / mouse.c
1 /*
2  * Acess2 Kernel - Mouse Mulitplexing Driver
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - Mouse mulitplexing
7  */
8 #define DEBUG   0
9 #define VERSION VER2(0,1)
10 #include <acess.h>
11 #include <modules.h>
12 #include <fs_devfs.h>
13 #include "include/mouse_int.h"
14
15 // === PROTOTYPES ===
16  int    Mouse_Install(char **Arguments);
17  int    Mouse_Cleanup(void);
18 // - "User" side
19  int    Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
20 tVFS_Node       *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
21  int    Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
22 size_t  Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data, Uint Flags);
23 // - Device Side
24 void    Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
25
26 // === GLOBALS ===
27 tVFS_NodeType   gMouse_RootNodeType = {
28         .ReadDir = Mouse_Root_ReadDir,
29         .FindDir = Mouse_Root_FindDir
30 };
31 tVFS_NodeType   gMouse_DevNodeType = {
32         .IOCtl = Mouse_Dev_IOCtl,
33         .Read = Mouse_Dev_Read
34 };
35 tDevFS_Driver   gMouse_DevInfo = {
36         NULL, "Mouse",
37         { .Flags = VFS_FFLAG_DIRECTORY, .Type = &gMouse_RootNodeType, .Size = 1 }
38 };
39 tPointer        gMouse_Pointer;
40
41 // === CODE ===
42 /**
43  * \brief Initialise the keyboard driver
44  */
45 int Mouse_Install(char **Arguments)
46 {
47         /// - Register with DevFS
48         DevFS_AddDevice( &gMouse_DevInfo );
49
50         gMouse_Pointer.Node.Type = &gMouse_DevNodeType;
51         gMouse_Pointer.Node.ImplPtr = &gMouse_Pointer;
52         gMouse_Pointer.FileHeader = (void*)gMouse_Pointer.FileData;
53         gMouse_Pointer.Axies = (void*)( gMouse_Pointer.FileHeader + 1 );
54         gMouse_Pointer.Buttons = (void*)( gMouse_Pointer.Axies + MAX_AXIES );
55         gMouse_Pointer.FileHeader->NAxies = MAX_AXIES;
56         gMouse_Pointer.FileHeader->NButtons = MAX_BUTTONS;
57
58         return 0;
59 }
60
61 /**
62  * \brief Pre-unload cleanup function
63  */
64 int Mouse_Cleanup(void)
65 {
66         return 0;
67 }
68
69 // --- VFS Interface ---
70 int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
71 {
72         if( Pos != 0 )
73                 return -EINVAL;
74         strcpy(Dest, "system");
75         return 0;
76 }
77
78 tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
79 {
80         if( strcmp(Name, "system") != 0 )       return NULL;
81         return &gMouse_Pointer.Node;
82 }
83
84 static const char *csaIOCTL_NAMES[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
85 /**
86  * \brief IOCtl handler for the mouse
87  */
88 int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
89 {
90         tJoystick_NumValue      *numval = Data;
91         tPointer        *ptr = Node->ImplPtr;
92         switch(ID)
93         {
94         BASE_IOCTLS(DRV_TYPE_MOUSE, "Mouse", VERSION, csaIOCTL_NAMES);
95
96         case JOY_IOCTL_GETSETAXISLIMIT:
97                 if( !numval || !CheckMem(numval, sizeof(*numval)) )
98                         return -1;
99                 LOG("GetSetAxisLimit %i = %i", numval->Num, numval->Value);
100                 if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
101                         return 0;
102                 if(numval->Value != -1)
103                         ptr->AxisLimits[numval->Num] = numval->Value;
104                 return ptr->AxisLimits[numval->Num];
105
106         case JOY_IOCTL_GETSETAXISPOSITION:
107                 if( !numval || !CheckMem(numval, sizeof(*numval)) )
108                         return -1;
109                 if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
110                         return 0;
111                 if(numval->Value != -1)
112                         ptr->Axies[numval->Num].CursorPos = numval->Value;
113                 return ptr->Axies[numval->Num].CursorPos;
114         }
115         return -1;
116 }
117
118 /**
119  * \brief Read from a device
120  */
121 size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data, Uint Flags)
122 {
123         tPointer *ptr = Node->ImplPtr;
124          int    n_buttons = ptr->FileHeader->NButtons;
125          int    n_axies = ptr->FileHeader->NAxies;
126
127         ENTER("pNode iLength pData", Node, Length, Data);
128
129         // TODO: Locking (Acquire)
130
131         Length = MIN(
132                 Length, 
133                 sizeof(tJoystick_FileHeader) + n_axies*sizeof(tJoystick_Axis) + n_buttons
134                 );
135
136         // Mark as checked
137         VFS_MarkAvaliable( Node, 0 );
138
139         memcpy( Data, ptr->FileData, Length );
140
141         // TODO: Locking (Release)
142
143         LEAVE('i', Length);
144         return Length;
145 }
146
147 // --- Device Interface ---
148 /*
149  * Handle a mouse event (movement or button press/release)
150  * - See Input/Mouse/include/mouse.h
151  */
152 void Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues)
153 {
154         tPointer *ptr = &gMouse_Pointer;
155         
156         ENTER("pHandle xButtonState pAxisDeltas", Handle, ButtonState, AxisDeltas);
157
158         // Update cursor position
159         for( int i = 0; i < 2; i ++ )
160         {
161                 ptr->Axies[i].CursorPos = AxisValues[i];
162                 ptr->Axies[i].CurValue = AxisDeltas ? AxisDeltas[i] : 0;
163         }
164         for( int i = 0; i < 5; i ++ )
165                 ptr->Buttons[i] = ButtonState & (1 << i) ? 255 : 0;
166
167         VFS_MarkAvaliable( &ptr->Node, 1 );
168         LEAVE('-');
169 }
170

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