Modules/Tegra2Vid - Fiddling!
[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;
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)        *nfds = giTerminalFD;
61         if(*nfds < giMouseFD)   *nfds = giMouseFD;
62         FD_SET(giTerminalFD, set);
63         FD_SET(giMouseFD, set);
64 }
65
66 void Input_HandleSelect(fd_set *set)
67 {
68         if(FD_ISSET(giTerminalFD, set))
69         {
70                 uint32_t        codepoint;
71                 static uint32_t scancode;
72                 #define KEY_CODEPOINT_MASK      0x3FFFFFFF
73                 
74                 if( read(giTerminalFD, &codepoint, sizeof(codepoint)) != sizeof(codepoint) )
75                 {
76                         // oops, error
77                         _SysDebug("Terminal read failed?");
78                 }
79         
80 //              _SysDebug("Keypress 0x%x", codepoint);
81         
82                 switch(codepoint & 0xC0000000)
83                 {
84                 case 0x00000000:        // Key pressed
85                         WM_Input_KeyDown(codepoint & KEY_CODEPOINT_MASK, scancode);
86                 case 0x80000000:        // Key release
87                         WM_Input_KeyFire(codepoint & KEY_CODEPOINT_MASK, scancode);
88                         scancode = 0;
89                         break;
90                 case 0x40000000:        // Key refire
91                         WM_Input_KeyUp(codepoint & KEY_CODEPOINT_MASK, scancode);
92                         scancode = 0;
93                         break;
94                 case 0xC0000000:        // Raw scancode
95                         scancode = codepoint & KEY_CODEPOINT_MASK;
96                         break;
97                 }
98         }
99
100         if(FD_ISSET(giMouseFD, set))
101         {
102                  int    i;
103                 struct sMouseAxis {
104                          int16_t        MinValue;
105                          int16_t        MaxValue;
106                          int16_t        CurValue;
107                         uint16_t        CursorPos;
108                 }       *axies;
109                 uint8_t *buttons;
110                 struct sMouseHdr {
111                         uint16_t        NAxies;
112                         uint16_t        NButtons;
113                 }       *mouseinfo;
114                 char    data[sizeof(*mouseinfo) + sizeof(*axies)*3 + 5];
115
116                 mouseinfo = (void*)data;
117
118                 seek(giMouseFD, 0, SEEK_SET);
119                 i = read(giMouseFD, data, sizeof(data));
120                 i -= sizeof(*mouseinfo);
121                 if( i < 0 )
122                         return ;
123                 if( i < sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons )
124                         return ;
125
126                 // What? No X/Y?
127                 if( mouseinfo->NAxies < 2 )
128                         return ;
129         
130                 axies = (void*)( mouseinfo + 1 );
131                 buttons = (void*)( axies + mouseinfo->NAxies );
132
133                 // Handle movement
134                 Video_SetCursorPos( axies[0].CursorPos, axies[1].CursorPos );
135
136                 WM_Input_MouseMoved(
137                         giInput_MouseX, giInput_MouseY,
138                         axies[0].CursorPos, axies[1].CursorPos
139                         );
140                 giInput_MouseX = axies[0].CursorPos;
141                 giInput_MouseY = axies[1].CursorPos;
142
143                 for( i = 0; i < mouseinfo->NButtons; i ++ )
144                 {
145                          int    bit = 1 << i;
146                          int    cur = buttons[i] > 128;
147
148                         if( !!(giInput_MouseButtonState & bit) != cur )
149                         {
150                                 WM_Input_MouseButton(giInput_MouseX, giInput_MouseY, i, cur);
151                                 // Flip button state
152                                 giInput_MouseButtonState ^= bit;
153                         }
154                 }
155         }
156 }

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