Usermode/AxWin4 - Mouse input in progress
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / input.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * input.cpp
6  * - Input
7  */
8 #include <CConfigInput.hpp>
9 #include <input.hpp>
10 #include <CCompositor.hpp>
11 #include <algorithm>
12 #include <acess/devices/joystick.h>
13 #include <cerrno>
14 #include <system_error>
15
16 namespace AxWin {
17
18 CInput::CInput(const ::AxWin::CConfigInput& config, CCompositor& compositor):
19         m_compositor(compositor),
20         m_keyboardFD(0),
21         m_mouseFD(-1)
22 {
23         m_mouseFD = _SysOpen(config.mouse_device.c_str(), OPENFLAG_READ|OPENFLAG_WRITE);
24         if( m_mouseFD == -1 )
25                 throw ::std::system_error(errno, ::std::system_category());
26 }
27
28 int CInput::FillSelect(::fd_set& rfds)
29 {
30         FD_SET(m_keyboardFD, &rfds);
31         if( m_mouseFD != -1 )
32                 FD_SET(m_mouseFD, &rfds);
33         return ::std::max(m_keyboardFD, m_mouseFD)+1;
34 }
35
36 void CInput::HandleSelect(::fd_set& rfds)
37 {
38         if( FD_ISSET(m_keyboardFD, &rfds) )
39         {
40                 uint32_t        codepoint;
41                 static uint32_t scancode;
42                 #define KEY_CODEPOINT_MASK      0x3FFFFFFF
43                 
44                 size_t readlen = _SysRead(m_keyboardFD, &codepoint, sizeof(codepoint));
45                 if( readlen != sizeof(codepoint) )
46                 {
47                         // oops, error
48                         _SysDebug("Terminal read failed? (%i != %i)", readlen, sizeof(codepoint));
49                 }
50         
51 //              _SysDebug("Keypress 0x%x", codepoint);
52         
53                 switch(codepoint & 0xC0000000)
54                 {
55                 case 0x00000000:        // Key pressed
56                         //WM_Input_KeyDown(codepoint & KEY_CODEPOINT_MASK, scancode);
57                 case 0x80000000:        // Key release
58                         //WM_Input_KeyFire(codepoint & KEY_CODEPOINT_MASK, scancode);
59                         scancode = 0;
60                         break;
61                 case 0x40000000:        // Key refire
62                         //WM_Input_KeyUp(codepoint & KEY_CODEPOINT_MASK, scancode);
63                         scancode = 0;
64                         break;
65                 case 0xC0000000:        // Raw scancode
66                         scancode = codepoint & KEY_CODEPOINT_MASK;
67                         break;
68                 }
69         }
70         
71         if( m_mouseFD != -1 && FD_ISSET(m_mouseFD, &rfds) )
72         {
73                 // TODO: Read mouse event and handle
74                 const int c_n_axies = 4;
75                 const int c_n_buttons = 5;
76                 struct mouse_axis       *axies;
77                 uint8_t *buttons;
78
79                 char data[sizeof(struct mouse_header) + sizeof(*axies)*c_n_axies + c_n_buttons];
80                 struct mouse_header     *mouseinfo = (struct mouse_header*)data;
81
82                 _SysSeek(m_mouseFD, 0, SEEK_SET);
83                 int len = _SysRead(m_mouseFD, data, sizeof(data));
84                 if( len < 0 )
85                         throw ::std::system_error(errno, ::std::system_category());
86                 
87                 len -= sizeof(*mouseinfo);
88                 if( len < 0 ) {
89                         _SysDebug("Mouse data undersized (%i bytes short on header)", len);
90                         return ;
91                 }
92                 if( mouseinfo->NAxies > c_n_axies || mouseinfo->NButtons > c_n_buttons ) {
93                         _SysDebug("%i axies, %i buttons above prealloc counts (%i, %i)",
94                                 mouseinfo->NAxies, mouseinfo->NButtons, c_n_axies, c_n_buttons
95                                 );
96                         return ;
97                 }
98                 if( len < sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons ) {
99                         _SysDebug("Mouse data undersized (body doesn't fit %i < %i)",
100                                 len, sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons
101                                 );
102                         return ;
103                 }
104
105                 // What? No X/Y?
106                 if( mouseinfo->NAxies < 2 ) {
107                         _SysDebug("Mouse data lacks X/Y");
108                         return ;
109                 }
110         
111                 axies = (struct mouse_axis*)( mouseinfo + 1 );
112                 buttons = (uint8_t*)( axies + mouseinfo->NAxies );
113
114                 m_compositor.MouseMove(0,
115                         m_mouseX, m_mouseY,
116                         axies[0].CursorPos - m_mouseX, axies[1].CursorPos - m_mouseY
117                         );
118                 m_mouseX = axies[0].CursorPos;
119                 m_mouseY = axies[1].CursorPos;
120
121                 for( int i = 0; i < mouseinfo->NButtons; i ++ )
122                 {
123                          int    bit = 1 << i;
124                          int    cur = buttons[i] > 128;
125                         if( !!(m_mouseBtns & bit) != cur )
126                         {
127                                 m_compositor.MouseButton(0, m_mouseX, m_mouseY, (eMouseButton)i, cur);
128                                 // Flip button state
129                                 m_mouseBtns ^= bit;
130                         }
131                 }
132         }
133 }
134
135 };      // namespace AxWin
136

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