X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin4_src%2FServer%2Finput.cpp;h=a0ab64663b197446e9216a2b92f25d7be5b9dccb;hb=ba78deafcc3016555469ed263d7a0370fa99db4b;hp=7519b877fec848b9d8a9937208f5293f60911395;hpb=f0ca31bc3f9c66a7fced9afcab9a6cacc8d1d647;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin4_src/Server/input.cpp b/Usermode/Applications/axwin4_src/Server/input.cpp index 7519b877..a0ab6466 100644 --- a/Usermode/Applications/axwin4_src/Server/input.cpp +++ b/Usermode/Applications/axwin4_src/Server/input.cpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include namespace AxWin { @@ -17,13 +20,33 @@ CInput::CInput(const ::AxWin::CConfigInput& config, CCompositor& compositor): m_keyboardFD(0), m_mouseFD(-1) { + m_mouseFD = _SysOpen(config.mouse_device.c_str(), OPENFLAG_READ|OPENFLAG_WRITE); + if( m_mouseFD == -1 ) + throw ::std::system_error(errno, ::std::system_category()); + m_mouseX = 640/2; + m_mouseY = 480/2; + + struct mouse_attribute attr; + // X : Limit + Position + attr.Num = 0; + attr.Value = 640; + _SysIOCtl(m_mouseFD, JOY_IOCTL_GETSETAXISLIMIT, &attr); + attr.Value = m_mouseX; + _SysIOCtl(m_mouseFD, JOY_IOCTL_GETSETAXISPOSITION, &attr); + // Y: Limit + Position + attr.Num = 1; + attr.Value = 480; + _SysIOCtl(m_mouseFD, JOY_IOCTL_GETSETAXISLIMIT, &attr); + attr.Value = m_mouseY; + _SysIOCtl(m_mouseFD, JOY_IOCTL_GETSETAXISPOSITION, &attr); } int CInput::FillSelect(::fd_set& rfds) { FD_SET(m_keyboardFD, &rfds); - FD_SET(m_mouseFD, &rfds); + if( m_mouseFD != -1 ) + FD_SET(m_mouseFD, &rfds); return ::std::max(m_keyboardFD, m_mouseFD)+1; } @@ -31,12 +54,99 @@ void CInput::HandleSelect(::fd_set& rfds) { if( FD_ISSET(m_keyboardFD, &rfds) ) { - // TODO: Read keystroke and handle + uint32_t codepoint; + static uint32_t scancode; + #define KEY_CODEPOINT_MASK 0x3FFFFFFF + + size_t readlen = _SysRead(m_keyboardFD, &codepoint, sizeof(codepoint)); + if( readlen != sizeof(codepoint) ) + { + // oops, error + _SysDebug("Terminal read failed? (%i != %i)", readlen, sizeof(codepoint)); + } + +// _SysDebug("Keypress 0x%x", codepoint); + + switch(codepoint & 0xC0000000) + { + case 0x00000000: // Key pressed + m_compositor.KeyState(0, scancode, true, codepoint & KEY_CODEPOINT_MASK); + break; + case 0x40000000: // Key release + m_compositor.KeyState(0, scancode, false, codepoint & KEY_CODEPOINT_MASK); + scancode = 0; + break; + case 0x80000000: // Key refire + m_compositor.KeyState(0, scancode, true, codepoint & KEY_CODEPOINT_MASK); + scancode = 0; + break; + case 0xC0000000: // Raw scancode + scancode = codepoint & KEY_CODEPOINT_MASK; + break; + } } - if( FD_ISSET(m_mouseFD, &rfds) ) + if( m_mouseFD != -1 && FD_ISSET(m_mouseFD, &rfds) ) { - // TODO: Read mouse event and handle + const int c_n_axies = 4; + const int c_n_buttons = 5; + struct mouse_axis *axies; + uint8_t *buttons; + + char data[sizeof(struct mouse_header) + sizeof(*axies)*c_n_axies + c_n_buttons]; + struct mouse_header *mouseinfo = (struct mouse_header*)data; + + _SysSeek(m_mouseFD, 0, SEEK_SET); + int len = _SysRead(m_mouseFD, data, sizeof(data)); + if( len < 0 ) + throw ::std::system_error(errno, ::std::system_category()); + + len -= sizeof(*mouseinfo); + if( len < 0 ) { + _SysDebug("Mouse data undersized (%i bytes short on header)", len); + return ; + } + if( mouseinfo->NAxies > c_n_axies || mouseinfo->NButtons > c_n_buttons ) { + _SysDebug("%i axies, %i buttons above prealloc counts (%i, %i)", + mouseinfo->NAxies, mouseinfo->NButtons, c_n_axies, c_n_buttons + ); + return ; + } + if( len < sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons ) { + _SysDebug("Mouse data undersized (body doesn't fit %i < %i)", + len, sizeof(*axies)*mouseinfo->NAxies + mouseinfo->NButtons + ); + return ; + } + + // What? No X/Y? + if( mouseinfo->NAxies < 2 ) { + _SysDebug("Mouse data lacks X/Y"); + return ; + } + + axies = (struct mouse_axis*)( mouseinfo + 1 ); + buttons = (uint8_t*)( axies + mouseinfo->NAxies ); + + // TODO: Use cursor range only to caputre motion (ignore reported position) + m_compositor.MouseMove(0, + m_mouseX, m_mouseY, + axies[0].CursorPos - m_mouseX, axies[1].CursorPos - m_mouseY + ); + m_mouseX = axies[0].CursorPos; + m_mouseY = axies[1].CursorPos; + + for( int i = 0; i < mouseinfo->NButtons; i ++ ) + { + int bit = 1 << i; + int cur = buttons[i] > 128; + if( !!(m_mouseBtns & bit) != cur ) + { + m_compositor.MouseButton(0, m_mouseX, m_mouseY, (eMouseButton)i, cur); + // Flip button state + m_mouseBtns ^= bit; + } + } } }