/* ** ClanLib SDK ** Copyright (c) 1997-2005 The ClanLib Team ** ** This software is provided 'as-is', without any express or implied ** warranty. In no event will the authors be held liable for any damages ** arising from the use of this software. ** ** Permission is granted to anyone to use this software for any purpose, ** including commercial applications, and to alter it and redistribute it ** freely, subject to the following restrictions: ** ** 1. The origin of this software must not be misrepresented; you must not ** claim that you wrote the original software. If you use this software ** in a product, an acknowledgment in the product documentation would be ** appreciated but is not required. ** 2. Altered source versions must be plainly marked as such, and must not be ** misrepresented as being the original software. ** 3. This notice may not be removed or altered from any source distribution. ** ** Note: Some of the libraries ClanLib may link to may have additional ** requirements or restrictions. ** ** File Author(s): ** ** Magnus Norddahl ** (if your name is missing here, please add it) */ #include #include #include #include #include #include "API/Core/System/error.h" #include "API/Display/keys.h" #include "API/Display/input_event.h" #include "API/Display/input_device.h" #include "display_window_opengl.h" #include "input_device_linuxusbmouse.h" CL_InputDevice_LinuxUSBMouse::CL_InputDevice_LinuxUSBMouse(CL_DisplayWindow_Generic* parent, const std::string& dev) : parent(parent), device(dev), buttons(5) { type = CL_InputDevice::mouse; fd = open (device.c_str (), O_RDWR | O_NONBLOCK); if (fd == -1) { throw CL_Error(strerror(errno)); } init_explorer_ps2(); char data[4]; read(fd, data, sizeof (data)); read(fd, data, sizeof (data)); read(fd, data, sizeof (data)); } CL_InputDevice_LinuxUSBMouse::~CL_InputDevice_LinuxUSBMouse() { close(fd); } void CL_InputDevice_LinuxUSBMouse::init_explorer_ps2() { // Microsoft init sequence for Explorer mouse (wheel + 5 buttons) static unsigned char data[] = { 0xF3, 0xC8, 0xF3, 0xC8, 0xF3, 0x50 }; write(fd, data, sizeof(data)); } bool CL_InputDevice_LinuxUSBMouse::get_keycode(int keycode) const { if (keycode > 0 && keycode < int(buttons.size())) return buttons[keycode]; else return false; } void CL_InputDevice_LinuxUSBMouse::keep_alive() { unsigned char data[4]; while (read(fd, data, sizeof (data)) > 0) { // Mouse Move: int delta_x = (data[0] & 0x10) ? data[1]-256 : data[1]; int delta_y = (data[0] & 0x20) ? data[2]-256 : data[2]; if (delta_x != 0 || delta_y != 0) { mouse_pos.x += delta_x; mouse_pos.y -= delta_y; // y-axis is reversed on-screen if (mouse_pos.x < 0) mouse_pos.x = 0; else if (mouse_pos.x > parent->get_width()) mouse_pos.x = parent->get_width() - 1; if (mouse_pos.y < 0) mouse_pos.y = 0; else if (mouse_pos.y > parent->get_height()) mouse_pos.y = parent->get_height() - 1; send_ball_move(delta_x, delta_y); send_pointer_move(mouse_pos); } // Scrollwheel move int delta_z = (data[3] & 0x08) ? (data[3] & 0x0F)-16 : (data[3] & 0x0F); if (delta_z > 0) { while (delta_z != 0) { --delta_z; send_key_event(CL_MOUSE_WHEEL_DOWN, true); send_key_event(CL_MOUSE_WHEEL_DOWN, false); } } else if (delta_z < 0) { while (delta_z != 0) { ++delta_z; send_key_event(CL_MOUSE_WHEEL_UP, true); send_key_event(CL_MOUSE_WHEEL_UP, false); } } // Button event std::vector new_state(5); new_state[0] = ((data[0] & 1)>0); new_state[1] = ((data[0] & 2)>0); new_state[2] = ((data[0] & 4)>0); new_state[3] = ((data[3] & 16)>0); new_state[4] = ((data[3] & 32)>0); for (int i = 0; i < 5; ++i) { if (new_state[i] != buttons[i]) { send_key_event(i<3?i:i+2, new_state[i]); } } buttons = new_state; } } void CL_InputDevice_LinuxUSBMouse::send_pointer_move(const CL_Point& pos) { CL_InputEvent event; event.type = CL_InputEvent::pointer_moved; event.device = CL_InputDevice(this); event.mouse_pos = pos; sig_pointer_move(event); } void CL_InputDevice_LinuxUSBMouse::send_ball_move(int delta_x, int delta_y) { CL_InputEvent event; event.type = CL_InputEvent::ball_moved; event.device = CL_InputDevice(this); event.mouse_pos = CL_Point(delta_x, delta_y); sig_ball_move(event); } void CL_InputDevice_LinuxUSBMouse::send_key_event(int key, bool press) { CL_InputEvent event; event.type = press ? CL_InputEvent::pressed : CL_InputEvent::released; event.id = key; event.device = CL_InputDevice(this); event.mouse_pos = mouse_pos; if (press) sig_key_down(event); else sig_key_up(event); } // Local Variables: *** // mode: clanlib *** // End: ***