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

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