Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / input.c
1 /*
2  * Acess2 GUI (AxWin) Version 3
3  * - By John Hodge (thePowersGang)
4  *
5  * input.c
6  * - Input abstraction
7  */
8 #include <common.h>
9 #include <acess/sys.h>
10 #include <wm_input.h>
11 #include <stddef.h>
12
13 // TODO: Move out to a common header
14 typedef struct
15 {
16         int Num;
17         int Value;
18 } tNumValue;
19 #define JOY_IOCTL_GETSETAXISLIMIT       6
20 #define JOY_IOCTL_GETSETAXISPOSITION    7
21
22 // === IMPORTS ===
23 extern void     Video_SetCursorPos(short X, short Y);
24 const char      *gsMouseDevice;
25 extern int      giTerminalFD_Input;
26 extern int      giScreenWidth;
27 extern int      giScreenHeight;
28
29 // === GLOBALS ===
30  int    giMouseFD;
31  int    giInput_MouseButtonState;
32  int    giInput_MouseX, giInput_MouseY;
33
34 // === CODE ===
35 int Input_Init(void)
36 {
37         tNumValue       num_value;
38
39         // Open mouse for RW
40         giMouseFD = _SysOpen(gsMouseDevice, 3);
41
42         // Set mouse limits
43         // TODO: Update these if the screen resolution changes
44         num_value.Num = 0;      num_value.Value = giScreenWidth;
45         _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
46         num_value.Value = giScreenWidth/2;
47         giInput_MouseX = giScreenWidth/2;
48         _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
49
50         num_value.Num = 1;      num_value.Value = giScreenHeight;
51         _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value);
52         num_value.Value = giScreenHeight/2;
53         giInput_MouseY = giScreenHeight/2;
54         _SysIOCtl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value);
55
56         return 0;
57 }
58
59 void Input_FillSelect(int *nfds, fd_set *set)
60 {
61         if(*nfds < giTerminalFD_Input)  *nfds = giTerminalFD_Input;
62         if(*nfds < giMouseFD)   *nfds = giMouseFD;
63         FD_SET(giTerminalFD_Input, set);
64         FD_SET(giMouseFD, set);
65 }
66
67 void Input_HandleSelect(fd_set *set)
68 {
69         if(FD_ISSET(giTerminalFD_Input, set))
70         {
71                 uint32_t        codepoint;
72                 static uint32_t scancode;
73                 #define KEY_CODEPOINT_MASK      0x3FFFFFFF
74                 
75                 size_t readlen = _SysRead(giTerminalFD_Input, &codepoint, sizeof(codepoint));
76                 if( readlen != sizeof(codepoint) )
77                 {
78                         // oops, error
79                         _SysDebug("Terminal read failed? (%i != %i)", readlen, sizeof(codepoint));
80                 }
81         
82 //              _SysDebug("Keypress 0x%x", codepoint);
83         
84                 switch(codepoint & 0xC0000000)
85                 {
86                 case 0x00000000:        // Key pressed
87                         WM_Input_KeyDown(codepoint & KEY_CODEPOINT_MASK, scancode);
88                 case 0x80000000:        // Key release
89                         WM_Input_KeyFire(codepoint & KEY_CODEPOINT_MASK, scancode);
90                         scancode = 0;
91                         break;
92                 case 0x40000000:        // Key refire
93                         WM_Input_KeyUp(codepoint & KEY_CODEPOINT_MASK, scancode);
94                         scancode = 0;
95                         break;
96                 case 0xC0000000:        // Raw scancode
97                         scancode = codepoint & KEY_CODEPOINT_MASK;
98                         break;
99                 }
100         }
101
102         if(FD_ISSET(giMouseFD, set))
103         {
104                 const int c_n_axies = 4;
105                 const int c_n_buttons = 5;
106                  int    i;
107                 struct sMouseAxis {
108                          int16_t        MinValue;
109                          int16_t        MaxValue;
110                          int16_t        CurValue;
111                         uint16_t        CursorPos;
112                 }       *axies;
113                 uint8_t *buttons;
114                 struct sMouseHdr {
115                         uint16_t        NAxies;
116                         uint16_t        NButtons;
117                 }       *mouseinfo;
118                 char    data[sizeof(*mouseinfo) + sizeof(*axies)*c_n_axies + c_n_buttons];
119
120                 mouseinfo = (void*)data;
121
122                 _SysSeek(giMouseFD, 0, SEEK_SET);
123                 i = _SysRead(giMouseFD, data, sizeof(data));
124                 i -= sizeof(*mouseinfo);
125                 if( i < 0 ) {
126                         _SysDebug("Mouse data undersized (no header)");
127                         return ;
128                 }
129                 if( mouseinfo->NAxies > c_n_axies || mouseinfo->NButtons > c_n_buttons ) {
130                         _SysDebug("%i axies, %i buttons above prealloc counts (%i, %i)",
131                                 mouseinfo->NAxies, mouseinfo->NButtons, c_n_axies, c_n_buttons
132                                 );
133                         return ;
134                 }
135                 if( i < sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons ) {
136                         _SysDebug("Mouse data undersized (body doesn't fit %i < %i)",
137                                 i, sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons
138                                 );
139                         return ;
140                 }
141
142                 // What? No X/Y?
143                 if( mouseinfo->NAxies < 2 )
144                         return ;
145         
146                 axies = (void*)( mouseinfo + 1 );
147                 buttons = (void*)( axies + mouseinfo->NAxies );
148
149                 // Handle movement
150                 Video_SetCursorPos( axies[0].CursorPos, axies[1].CursorPos );
151
152 //              _SysDebug("Mouse to %i,%i", axies[0].CursorPos, axies[1].CursorPos);
153
154                 WM_Input_MouseMoved(
155                         giInput_MouseX, giInput_MouseY,
156                         axies[0].CursorPos, axies[1].CursorPos
157                         );
158                 giInput_MouseX = axies[0].CursorPos;
159                 giInput_MouseY = axies[1].CursorPos;
160
161                 for( i = 0; i < mouseinfo->NButtons; i ++ )
162                 {
163                          int    bit = 1 << i;
164                          int    cur = buttons[i] > 128;
165
166                         if( !!(giInput_MouseButtonState & bit) != cur )
167                         {
168                                 WM_Input_MouseButton(giInput_MouseX, giInput_MouseY, i, cur);
169                                 // Flip button state
170                                 giInput_MouseButtonState ^= bit;
171                         }
172                 }
173         }
174 }

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