Mouse driver and AxWin
authorJohn Hodge <[email protected]>
Sat, 28 May 2011 13:10:31 +0000 (21:10 +0800)
committerJohn Hodge <[email protected]>
Sat, 28 May 2011 13:10:31 +0000 (21:10 +0800)
- Mouse driver implemented, only had very basic testing
- Decided to use select() and sockets for the AxWin IPC framework
 > Allows the use of select() on the keyboard and mouse for input

Kernel/include/tpl_drv_joystick.h
Modules/Input/PS2KbMouse/main.c
Modules/Input/PS2KbMouse/ps2mouse.c
Usermode/Applications/axwin2_src/WM/main.c
Usermode/Applications/axwin2_src/WM/messages.c

index dd22001..3ba441a 100644 (file)
@@ -28,7 +28,7 @@
  */\r
 enum eTplJoystick_IOCtl {\r
        /**\r
-        * ioctl(..., struct{int Ident;tJoystickCallback *Callback})\r
+        * ioctl(..., tJoystickCallback *Callback)\r
         * \brief Sets the callback\r
         * \note Can be called from kernel mode only\r
         *\r
@@ -39,33 +39,64 @@ enum eTplJoystick_IOCtl {
        JOY_IOCTL_SETCALLBACK = 4,\r
 \r
        /**\r
-        * ioctl(..., struct{int AxisNum;int Value})\r
+        * ioctl(..., int *Argument)\r
+        * \brief Set the argument passed as the first parameter to the callback\r
+        * \note Kernel mode only\r
+        */\r
+       JOY_IOCTL_SETCALLBACKARG,\r
+\r
+       /**\r
+        * ioctl(..., tJoystickNumValue *)\r
         * \brief Set maximum value for sJoystick_Axis.CurState\r
         * \note If \a Value is equal to -1 (all bits set), the value is not changed\r
         */\r
        JOY_IOCTL_GETSETAXISLIMIT,\r
+\r
+       /**\r
+        * ioctl(..., tJoystickNumValue *)\r
+        * \brief Set the value of sJoystick_Axis.CurState\r
+        * \note If \a Value is equal to -1 (all bits set), the value is not changed\r
+        */\r
+       JOY_IOCTL_GETSETAXISPOSITION,\r
        \r
        /**\r
-        * ioctl(..., struct{int AxisNum;int Value})\r
+        * ioctl(..., tJoystickNumValue *)\r
         * \brief Set axis flags\r
         * \note If \a Value is equal to -1 (all bits set), the value is not changed\r
         */\r
        JOY_IOCTL_GETSETAXISFLAGS,\r
 \r
        /**\r
-        * ioctl(..., struct{int ButtonNum;int Value})\r
+        * ioctl(..., tJoystickNumValue *)\r
         * \brief Set Button Flags\r
         * \note If \a Value is equal to -1 (all bits set), the value is not changed\r
         */\r
        JOY_IOCTL_GETSETBUTTONFLAGS,\r
 };\r
 \r
+#define        DRV_JOY_IOCTLNAMES      "set_callback", "set_callback_arg", "getset_axis_limit", "getset_axis_position", \\r
+       "getset_axis_flags", "getset_button_flags"\r
+\r
+// === TYPES ===\r
+typedef struct sJoystick_NumValue      tJoystick_NumValue;\r
+typedef struct sJoystick_FileHeader    tJoystick_FileHeader;\r
+typedef struct sJoystick_Axis  tJoystick_Axis;\r
+\r
+/**\r
+ * \brief Number/Value pair for joystick IOCtls\r
+ */\r
+struct sJoystick_NumValue\r
+{\r
+        int    Num;    //!< Axis/Button number\r
+        int    Value;  //!< Value (see IOCtl defs for meaning)\r
+};\r
+\r
 /**\r
  * \brief Callback type for JOY_IOCTL_SETCALLBACK\r
  * \param Ident        Ident value passed to JOY_IOCTL_SETCALLBACK\r
  * \r
  */\r
-typedef void (*tJoystickCallback)(int Ident, int bIsAxis, int Num, int Delta);\r
+typedef void (*tJoystick_Callback)(int Ident, int bIsAxis, int Num, int Delta);\r
 \r
 /**\r
  * \struct sJoystick_FileHeader\r
@@ -77,7 +108,7 @@ struct sJoystick_FileHeader
 };\r
 \r
 /**\r
- * \brief Axis Definition\r
+ * \brief Axis Definition in file data\r
  *\r
  * Describes the current state of an axis on the joystick.\r
  * \a MinValue and \a MaxValue describe the valid range for \a CurValue\r
@@ -87,7 +118,7 @@ struct sJoystick_FileHeader
 struct sJoystick_Axis\r
 {\r
        Sint16  MinValue;       //!< Minumum value for \a CurValue\r
-       Sint16  MaxValue;       //!< Maximum value for \a MaxValue\r
+       Sint16  MaxValue;       //!< Maximum value for \a CurValue\r
        Sint16  CurValue;       //!< Current value (joystick position)\r
        Uint16  CurState;       //!< Current state (cursor position)\r
 };\r
index 353befb..344c59e 100644 (file)
@@ -8,14 +8,15 @@
 
 // === IMPORTS ===
 extern int     KB_Install(char **Arguments);
-extern int     Mouse_Install(char **Arguments);
+extern int     PS2Mouse_Install(char **Arguments);
 
 // === PROTOTYPES ===
  int   PS2_Install(char **Arguments);
 
 // === GLOBALS ===
-MODULE_DEFINE(0, 0x0100, Input_PS2KbMouse, PS2_Install, NULL, NULL);
+MODULE_DEFINE(0, 0x0100, Input_PS2KbMouse, PS2_Install, NULL, NULL);   // Shuts the makefile up
 MODULE_DEFINE(0, 0x0100, PS2Keyboard, KB_Install, NULL, NULL);
+MODULE_DEFINE(0, 0x0100, PS2Mouse, PS2Mouse_Install, NULL, NULL);
 
 // === CODE ===
 int PS2_Install(char **Arguments)
index e87292a..7ccf461 100644 (file)
@@ -9,33 +9,39 @@
 #include <tpl_drv_common.h>\r
 #include <tpl_drv_joystick.h>\r
 \r
+static inline int MIN(int a, int b) { return (a < b) ? a : b; }\r
+static inline int MAX(int a, int b) { return (a > b) ? a : b; }\r
+\r
 // == CONSTANTS ==\r
+#define NUM_AXIES      2       // X+Y\r
+#define NUM_BUTTONS    5       // Left, Right, Scroll Click, Scroll Up, Scroll Down\r
 #define PS2_IO_PORT    0x60\r
-#define MOUSE_BUFFER_SIZE      (sizeof(t_mouse_fsdata))\r
-#define MOUSE_SENS_BASE        5\r
 \r
 // == PROTOTYPES ==\r
 // - Internal -\r
  int   PS2Mouse_Install(char **Arguments);\r
 void   PS2Mouse_IRQ(int Num);\r
 static void    mouseSendCommand(Uint8 cmd);\r
-static void    enableMouse();\r
+void   PS2Mouse_Enable();\r
 // - Filesystem -\r
-static Uint64  PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
-static int     PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
-\r
-typedef struct {\r
-       int x, y, buttons, unk;\r
-}      t_mouse_fsdata;\r
+Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
+int    PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
 \r
 // == GLOBALS ==\r
+// - Settings\r
  int   giMouse_Sensitivity = 1;\r
-t_mouse_fsdata gMouse_Data = {0, 0, 0, 0};\r
- int giMouse_MaxX = 640, giMouse_MaxY = 480;\r
+ int   giMouse_MaxX = 640, giMouse_MaxY = 480;\r
+// - File Data\r
+Uint8  gMouse_FileData[sizeof(tJoystick_FileHeader) + NUM_AXIES*sizeof(tJoystick_Axis) + NUM_BUTTONS];\r
+tJoystick_FileHeader   *gMouse_FileHeader = (void *)gMouse_FileData;\r
+tJoystick_Axis *gMouse_Axies;\r
+Uint8  *gMouse_Buttons;\r
+// - Internal State\r
  int   giMouse_Cycle = 0;      // IRQ Position\r
 Uint8  gaMouse_Bytes[4] = {0,0,0,0};\r
+// - Driver definition\r
 tDevFS_Driver  gMouse_DriverStruct = {\r
-       NULL, "ps2mouse",\r
+       NULL, "PS2Mouse",\r
        {\r
        .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX,\r
        .Read = PS2Mouse_Read, .IOCtl = PS2Mouse_IOCtl\r
@@ -43,12 +49,16 @@ tDevFS_Driver       gMouse_DriverStruct = {
 };\r
 \r
 // == CODE ==\r
-int Mouse_Install(char **Arguments)\r
+int PS2Mouse_Install(char **Arguments)\r
 {\r
+       // Set up variables\r
+       gMouse_Axies = (void*)&gMouse_FileData[1];\r
+       gMouse_Buttons = (void*)&gMouse_Axies[NUM_AXIES];\r
+       \r
        // Initialise Mouse Controller\r
        IRQ_AddHandler(12, PS2Mouse_IRQ);       // Set IRQ\r
        giMouse_Cycle = 0;      // Set Current Cycle position\r
-       enableMouse();          // Enable the mouse\r
+       PS2Mouse_Enable();              // Enable the mouse\r
        \r
        DevFS_AddDevice(&gMouse_DriverStruct);\r
        \r
@@ -60,99 +70,102 @@ int Mouse_Install(char **Arguments)
 void PS2Mouse_IRQ(int Num)\r
 {\r
        Uint8   flags;\r
-       int     dx, dy;\r
-       //int   log2x, log2y;\r
+        int    dx, dy;\r
+        int    dx_accel, dy_accel;\r
+\r
        \r
+       // Gather mouse data\r
        gaMouse_Bytes[giMouse_Cycle] = inb(0x60);\r
-       if(giMouse_Cycle == 0 && !(gaMouse_Bytes[giMouse_Cycle] & 0x8))\r
-               return;\r
+       LOG("gaMouse_Bytes[%i] = 0x%02x", gMouse_Axies[0].MaxValue);\r
+       // - If bit 3 of the first byte is not set, it's not a valid packet?\r
+       if(giMouse_Cycle == 0 && !(gaMouse_Bytes[0] & 0x08) )\r
+               return ;\r
        giMouse_Cycle++;\r
-       if(giMouse_Cycle == 3)\r
-               giMouse_Cycle = 0;\r
-       else\r
-               return;\r
-       \r
-       if(giMouse_Cycle > 0)\r
-               return;\r
-       \r
-       // Read Flags\r
+       if(giMouse_Cycle < 3)\r
+               return ;\r
+\r
+       giMouse_Cycle = 0;\r
+\r
+       // Actual Processing (once we have all bytes)   \r
        flags = gaMouse_Bytes[0];\r
-       if(flags & 0xC0)        // X/Y Overflow\r
-               return;\r
-               \r
-       #if DEBUG\r
-       //LogF(" PS2Mouse_Irq: flags = 0x%x\n", flags);\r
-       #endif\r
+\r
+       LOG("flags = 0x%x", flags);\r
        \r
+       // Check for X/Y Overflow\r
+       if(flags & 0xC0)        return;\r
+               \r
        // Calculate dX and dY\r
-       dx = (int) ( gaMouse_Bytes[1] | (flags & 0x10 ? ~0x00FF : 0) );\r
-       dy = (int) ( gaMouse_Bytes[2] | (flags & 0x20 ? ~0x00FF : 0) );\r
+       dx = gaMouse_Bytes[1];  if(flags & 0x10) dx = -(256-dx);\r
+       dy = gaMouse_Bytes[2];  if(flags & 0x20) dy = -(256-dy);\r
        dy = -dy;       // Y is negated\r
        LOG("RAW dx=%i, dy=%i\n", dx, dy);\r
-       dx = dx*MOUSE_SENS_BASE/giMouse_Sensitivity;\r
-       dy = dy*MOUSE_SENS_BASE/giMouse_Sensitivity;\r
+       // Apply scaling\r
+       // TODO: Apply a form of curve to the mouse movement (dx*log(dx), dx^k?)\r
+       // TODO: Independent sensitivities?\r
+       // TODO: Disable acceleration via a flag?\r
+       dx_accel = dx*giMouse_Sensitivity;\r
+       dy_accel = dy*giMouse_Sensitivity;\r
        \r
-       //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2x) : "a" ((Uint)gaMouse_Bytes[1]));\r
-       //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2y) : "a" ((Uint)gaMouse_Bytes[2]));\r
-       //LogF(" PS2Mouse_Irq: dx=%i, log2x = %i\n", dx, log2x);\r
-       //LogF(" PS2Mouse_Irq: dy=%i, log2y = %i\n", dy, log2y);\r
-       //dx *= log2x;\r
-       //dy *= log2y;\r
-       \r
-       // Set Buttons\r
-       gMouse_Data.buttons = flags & 0x7;      //Buttons (3 only)\r
+       // Set Buttons (Primary)\r
+       gMouse_Buttons[0] = (flags & 1) ? 0xFF : 0;\r
+       gMouse_Buttons[1] = (flags & 2) ? 0xFF : 0;\r
+       gMouse_Buttons[2] = (flags & 4) ? 0xFF : 0;\r
        \r
        // Update X and Y Positions\r
-       gMouse_Data.x += (int)dx;\r
-       gMouse_Data.y += (int)dy;\r
-       \r
-       // Constrain Positions\r
-       if(gMouse_Data.x < 0)   gMouse_Data.x = 0;\r
-       if(gMouse_Data.y < 0)   gMouse_Data.y = 0;\r
-       if(gMouse_Data.x >= giMouse_MaxX)       gMouse_Data.x = giMouse_MaxX-1;\r
-       if(gMouse_Data.y >= giMouse_MaxY)       gMouse_Data.y = giMouse_MaxY-1; \r
+       gMouse_Axies[0].CurValue = MIN( MAX(gMouse_Axies[0].MinValue, gMouse_Axies[0].CurValue + dx_accel), gMouse_Axies[0].MaxValue );\r
+       gMouse_Axies[1].CurValue = MIN( MAX(gMouse_Axies[1].MinValue, gMouse_Axies[1].CurValue + dy_accel), gMouse_Axies[1].MaxValue );\r
 }\r
 \r
 /* Read mouse state (coordinates)\r
  */\r
-static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
 {\r
-       if(Length < MOUSE_BUFFER_SIZE)\r
-               return -1;\r
+       if(Offset > sizeof(gMouse_FileData))    return 0;\r
+       if(Length > sizeof(gMouse_FileData))    Length = sizeof(gMouse_FileData);\r
+       if(Offset + Length > sizeof(gMouse_FileData))   Length = sizeof(gMouse_FileData) - Offset;\r
 \r
-       memcpy(Buffer, &gMouse_Data, MOUSE_BUFFER_SIZE);\r
+       memcpy(Buffer, &gMouse_FileData[Offset], Length);\r
                \r
-       return MOUSE_BUFFER_SIZE;\r
+       return Length;\r
 }\r
 \r
-static const char *csaIOCtls[] = {DRV_IOCTLNAMES, NULL};\r
+static const char *csaIOCtls[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};\r
 /* Handle messages to the device\r
  */\r
-static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
+int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
 {\r
-       struct {\r
-                int    Num;\r
-                int    Value;\r
-       }       *info = Data;\r
+       tJoystick_NumValue      *info = Data;\r
+\r
        switch(ID)\r
        {\r
        BASE_IOCTLS(DRV_TYPE_JOYSTICK, "PS2Mouse", 0x100, csaIOCtls);\r
+\r
+       case JOY_IOCTL_SETCALLBACK:     // TODO: Implement\r
+               return -1;\r
+       \r
+       case JOY_IOCTL_SETCALLBACKARG:  // TODO: Implement\r
+               return -1;\r
        \r
        case JOY_IOCTL_GETSETAXISLIMIT:\r
                if(!info)       return 0;\r
-               switch(info->Num)\r
-               {\r
-               case 0: // X\r
-                       if(info->Value != -1)\r
-                               giMouse_MaxX = info->Value;\r
-                       return giMouse_MaxX;\r
-               case 1: // Y\r
-                       if(info->Value != -1)\r
-                               giMouse_MaxY = info->Value;\r
-                       return giMouse_MaxY;\r
-               }\r
-               return 0;\r
-               \r
+               if(info->Num < 0 || info->Num >= 2)     return 0;\r
+               if(info->Value != -1)\r
+                       gMouse_Axies[info->Num].MaxValue = info->Value;\r
+               return gMouse_Axies[info->Num].MaxValue;\r
+       \r
+       case JOY_IOCTL_GETSETAXISPOSITION:\r
+               if(!info)       return 0;\r
+               if(info->Num < 0 || info->Num >= 2)     return 0;\r
+               if(info->Value != -1)\r
+                       gMouse_Axies[info->Num].CurValue = info->Value;\r
+               return gMouse_Axies[info->Num].CurValue;\r
+\r
+       case JOY_IOCTL_GETSETAXISFLAGS:\r
+               return -1;\r
+       \r
+       case JOY_IOCTL_GETSETBUTTONFLAGS:\r
+               return -1;\r
+\r
        default:\r
                return 0;\r
        }\r
@@ -171,22 +184,22 @@ static inline void mouseOut60(Uint8 data)
        while( timeout-- && inb(0x64) & 2 );    // Wait for Flag to clear\r
        outb(0x60, data);       // Send Command\r
 }\r
-static inline Uint8 mouseIn60()\r
+static inline Uint8 mouseIn60(void)\r
 {\r
        int timeout=100000;\r
        while( timeout-- && (inb(0x64) & 1) == 0);      // Wait for Flag to set\r
        return inb(0x60);\r
 }\r
-static void mouseSendCommand(Uint8 cmd)\r
+static inline void mouseSendCommand(Uint8 cmd)\r
 {\r
        mouseOut64(0xD4);\r
        mouseOut60(cmd);\r
 }\r
 \r
-static void enableMouse()\r
+void PS2Mouse_Enable(void)\r
 {\r
        Uint8   status;\r
-       Log_Log("PS2 Mouse", "Enabling Mouse...");\r
+       Log_Log("PS2Mouse", "Enabling Mouse...");\r
        \r
        // Enable AUX PS/2\r
        mouseOut64(0xA8);\r
@@ -194,7 +207,8 @@ static void enableMouse()
        // Enable AUX PS/2 (Compaq Status Byte)\r
        mouseOut64(0x20);       // Send Command\r
        status = mouseIn60();   // Get Status\r
-       status &= 0xDF; status |= 0x02; // Alter Flags (Set IRQ12 (2) and Clear Disable Mouse Clock (20))\r
+       status &= ~0x20;        // Clear "Disable Mouse Clock"\r
+       status |= 0x02;         // Set IRQ12 Enable\r
        mouseOut64(0x60);       // Send Command\r
        mouseOut60(status);     // Set Status\r
        \r
index 7b42562..67ceb63 100644 (file)
@@ -9,8 +9,12 @@
 extern void    ParseCommandline(int argc, char *argv[]);
 extern void    Video_Setup(void);
 extern void    WM_Update(void);
-extern void    Messages_PollIPC(void);
 extern void    Interface_Init(void);
+extern void    IPC_Init(void);
+extern void    IPC_FillSelect(int *nfds, fd_set *set);
+extern void    IPC_HandleSelect(fd_set *set);
+extern void    Input_FillSelect(int *nfds, fd_set *set);
+extern void    Input_HandleSelect(fd_set *set);
 
 // === GLOBALS ===
 char   *gsTerminalDevice = NULL;
@@ -35,17 +39,31 @@ int main(int argc, char *argv[])
        if( gsTerminalDevice == NULL ) {
                gsTerminalDevice = "/Devices/VTerm/6";
        }
+       if( gsMouseDevice == NULL ) {
+               gsMouseDevice = "/Devices/PS2Mouse";
+       }
        
        Video_Setup();
        Interface_Init();
+       IPC_Init();
        
        WM_Update();
        
        // Main Loop
        for(;;)
        {
-               Messages_PollIPC();
-               //yield();
+               fd_set  fds;
+                int    nfds = 0;
+               FD_ZERO(&fds);
+       
+               Input_FillSelect(&nfds, &fds);
+               IPC_FillSelect(&nfds, &fds);
+
+               select(nfds, &fds, NULL, NULL, NULL);
+
+               Input_HandleSelect(&fds);
+               IPC_HandleSelect(&fds);
        }
        return 0;
 }
+
index 92137f0..c4bed7a 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include "common.h"
 #include <acess/sys.h>
+#include <net.h>
 #include <axwin/messages.h>
 
 #define STATICBUF_SIZE 64
@@ -17,8 +18,16 @@ void Messages_RespondIPC(int ID, size_t Length, void *Data);
 void   Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, int ID);
 
 // === GLOBALS ===
+ int   giIPCFileHandle;
 
 // === CODE ===
+void IPC_Init(void)
+{
+       // TODO: Check this
+       giIPCFileHandle = open("/Devices/ip/loop/udpc", OPENFLAG_READ|OPENFLAG_EXEC);
+//     ioctl(giIPCFileHandle, );
+}
+
 void Messages_PollIPC()
 {
         int    len;

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