diff options
| author | Pierre Bourdon <delroth@gmail.com> | 2016-06-24 10:43:46 +0200 |
|---|---|---|
| committer | Pierre Bourdon <delroth@gmail.com> | 2016-06-24 10:43:46 +0200 |
| commit | 3570c7f03a2aa90aa634f96c0af1969af610f14d (patch) | |
| tree | 4252e03c0e853ba7cffe022937698c854ad0eaa9 /Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp | |
| parent | 2115e8a4a6814e32107b5205ff5c95bbd3c6e99c (diff) | |
Reformat all the things. Have fun with merge conflicts.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp')
| -rw-r--r-- | Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp | 470 |
1 files changed, 234 insertions, 236 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index 3d7a02a3a0..79b86a487d 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include <X11/XKBlib.h> #include <cmath> #include <cstdlib> #include <cstring> -#include <X11/XKBlib.h> #include "InputCommon/ControllerInterface/Xlib/XInput2.h" @@ -25,7 +25,6 @@ // * Key controls: these correspond to a limited subset of the keyboard // keys. - // Mouse axis control tuning. Unlike absolute mouse position, relative mouse // motion data needs to be tweaked and smoothed out a bit to be usable. @@ -46,325 +45,324 @@ namespace ciface { namespace XInput2 { - // This function will add zero or more KeyboardMouse objects to devices. void Init(std::vector<Core::Device*>& devices, void* const hwnd) { - Display* dpy = XOpenDisplay(nullptr); + Display* dpy = XOpenDisplay(nullptr); - // xi_opcode is important; it will be used to identify XInput events by - // the polling loop in UpdateInput. - int xi_opcode, event, error; + // xi_opcode is important; it will be used to identify XInput events by + // the polling loop in UpdateInput. + int xi_opcode, event, error; - // verify that the XInput extension is available - if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) - return; + // verify that the XInput extension is available + if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) + return; - // verify that the XInput extension is at at least version 2.0 - int major = 2, minor = 0; + // verify that the XInput extension is at at least version 2.0 + int major = 2, minor = 0; - if (XIQueryVersion(dpy, &major, &minor) != Success) - return; + if (XIQueryVersion(dpy, &major, &minor) != Success) + return; - // register all master devices with Dolphin + // register all master devices with Dolphin - XIDeviceInfo* all_masters; - XIDeviceInfo* current_master; - int num_masters; + XIDeviceInfo* all_masters; + XIDeviceInfo* current_master; + int num_masters; - all_masters = XIQueryDevice(dpy, XIAllMasterDevices, &num_masters); + all_masters = XIQueryDevice(dpy, XIAllMasterDevices, &num_masters); - for (int i = 0; i < num_masters; i++) - { - current_master = &all_masters[i]; - if (current_master->use == XIMasterPointer) - // Since current_master is a master pointer, its attachment must - // be a master keyboard. - devices.push_back(new KeyboardMouse((Window)hwnd, xi_opcode, current_master->deviceid, current_master->attachment)); - } + for (int i = 0; i < num_masters; i++) + { + current_master = &all_masters[i]; + if (current_master->use == XIMasterPointer) + // Since current_master is a master pointer, its attachment must + // be a master keyboard. + devices.push_back(new KeyboardMouse((Window)hwnd, xi_opcode, current_master->deviceid, + current_master->attachment)); + } - XCloseDisplay(dpy); + XCloseDisplay(dpy); - XIFreeDeviceInfo(all_masters); + XIFreeDeviceInfo(all_masters); } // Apply the event mask to the device and all its slaves. Only used in the // constructor. Remember, each KeyboardMouse has its own copy of the event // stream, which is how multiple event masks can "coexist." -void KeyboardMouse::SelectEventsForDevice(Window window, XIEventMask *mask, int deviceid) +void KeyboardMouse::SelectEventsForDevice(Window window, XIEventMask* mask, int deviceid) { - // Set the event mask for the master device. - mask->deviceid = deviceid; - XISelectEvents(m_display, window, mask, 1); - - // Query all the master device's slaves and set the same event mask for - // those too. There are two reasons we want to do this. For mouse devices, - // we want the raw motion events, and only slaves (i.e. physical hardware - // devices) emit those. For keyboard devices, selecting slaves avoids - // dealing with key focus. - - XIDeviceInfo* all_slaves; - XIDeviceInfo* current_slave; - int num_slaves; - - all_slaves = XIQueryDevice(m_display, XIAllDevices, &num_slaves); - - for (int i = 0; i < num_slaves; i++) - { - current_slave = &all_slaves[i]; - if ((current_slave->use != XISlavePointer && current_slave->use != XISlaveKeyboard) || current_slave->attachment != deviceid) - continue; - mask->deviceid = current_slave->deviceid; - XISelectEvents(m_display, window, mask, 1); - } - - XIFreeDeviceInfo(all_slaves); + // Set the event mask for the master device. + mask->deviceid = deviceid; + XISelectEvents(m_display, window, mask, 1); + + // Query all the master device's slaves and set the same event mask for + // those too. There are two reasons we want to do this. For mouse devices, + // we want the raw motion events, and only slaves (i.e. physical hardware + // devices) emit those. For keyboard devices, selecting slaves avoids + // dealing with key focus. + + XIDeviceInfo* all_slaves; + XIDeviceInfo* current_slave; + int num_slaves; + + all_slaves = XIQueryDevice(m_display, XIAllDevices, &num_slaves); + + for (int i = 0; i < num_slaves; i++) + { + current_slave = &all_slaves[i]; + if ((current_slave->use != XISlavePointer && current_slave->use != XISlaveKeyboard) || + current_slave->attachment != deviceid) + continue; + mask->deviceid = current_slave->deviceid; + XISelectEvents(m_display, window, mask, 1); + } + + XIFreeDeviceInfo(all_slaves); } KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboard) - : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard) + : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard) { - memset(&m_state, 0, sizeof(m_state)); - - // The cool thing about each KeyboardMouse object having its own Display - // is that each one gets its own separate copy of the X11 event stream, - // which it can individually filter to get just the events it's interested - // in. So be aware that each KeyboardMouse object actually has its own X11 - // "context." - m_display = XOpenDisplay(nullptr); - - int min_keycode, max_keycode; - XDisplayKeycodes(m_display, &min_keycode, &max_keycode); - - int unused; // should always be 1 - XIDeviceInfo* pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused); - name = std::string(pointer_device->name); - XIFreeDeviceInfo(pointer_device); - - XIEventMask mask; - unsigned char mask_buf[(XI_LASTEVENT + 7)/8]; - - mask.mask_len = sizeof(mask_buf); - mask.mask = mask_buf; - memset(mask_buf, 0, sizeof(mask_buf)); - - XISetMask(mask_buf, XI_ButtonPress); - XISetMask(mask_buf, XI_ButtonRelease); - XISetMask(mask_buf, XI_RawMotion); - XISetMask(mask_buf, XI_KeyPress); - XISetMask(mask_buf, XI_KeyRelease); - - SelectEventsForDevice(DefaultRootWindow(m_display), &mask, pointer_deviceid); - SelectEventsForDevice(DefaultRootWindow(m_display), &mask, keyboard_deviceid); - - // Keyboard Keys - for (int i = min_keycode; i <= max_keycode; ++i) - { - Key* temp_key = new Key(m_display, i, m_state.keyboard); - if (temp_key->m_keyname.length()) - AddInput(temp_key); - else - delete temp_key; - } - - // Mouse Buttons - for (int i = 0; i < 5; i++) - AddInput(new Button(i, &m_state.buttons)); - - // Mouse Cursor, X-/+ and Y-/+ - for (int i = 0; i != 4; ++i) - AddInput(new Cursor(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.cursor.y : &m_state.cursor.x)); - - // Mouse Axis, X-/+ and Y-/+ - for (int i = 0; i != 4; ++i) - AddInput(new Axis(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.axis.y : &m_state.axis.x)); + memset(&m_state, 0, sizeof(m_state)); + + // The cool thing about each KeyboardMouse object having its own Display + // is that each one gets its own separate copy of the X11 event stream, + // which it can individually filter to get just the events it's interested + // in. So be aware that each KeyboardMouse object actually has its own X11 + // "context." + m_display = XOpenDisplay(nullptr); + + int min_keycode, max_keycode; + XDisplayKeycodes(m_display, &min_keycode, &max_keycode); + + int unused; // should always be 1 + XIDeviceInfo* pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused); + name = std::string(pointer_device->name); + XIFreeDeviceInfo(pointer_device); + + XIEventMask mask; + unsigned char mask_buf[(XI_LASTEVENT + 7) / 8]; + + mask.mask_len = sizeof(mask_buf); + mask.mask = mask_buf; + memset(mask_buf, 0, sizeof(mask_buf)); + + XISetMask(mask_buf, XI_ButtonPress); + XISetMask(mask_buf, XI_ButtonRelease); + XISetMask(mask_buf, XI_RawMotion); + XISetMask(mask_buf, XI_KeyPress); + XISetMask(mask_buf, XI_KeyRelease); + + SelectEventsForDevice(DefaultRootWindow(m_display), &mask, pointer_deviceid); + SelectEventsForDevice(DefaultRootWindow(m_display), &mask, keyboard_deviceid); + + // Keyboard Keys + for (int i = min_keycode; i <= max_keycode; ++i) + { + Key* temp_key = new Key(m_display, i, m_state.keyboard); + if (temp_key->m_keyname.length()) + AddInput(temp_key); + else + delete temp_key; + } + + // Mouse Buttons + for (int i = 0; i < 5; i++) + AddInput(new Button(i, &m_state.buttons)); + + // Mouse Cursor, X-/+ and Y-/+ + for (int i = 0; i != 4; ++i) + AddInput(new Cursor(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.cursor.y : &m_state.cursor.x)); + + // Mouse Axis, X-/+ and Y-/+ + for (int i = 0; i != 4; ++i) + AddInput(new Axis(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.axis.y : &m_state.axis.x)); } KeyboardMouse::~KeyboardMouse() { - XCloseDisplay(m_display); + XCloseDisplay(m_display); } // Update the mouse cursor controls void KeyboardMouse::UpdateCursor() { - double root_x, root_y, win_x, win_y; - Window root, child; + double root_x, root_y, win_x, win_y; + Window root, child; - // unused-- we're not interested in button presses here, as those are - // updated using events - XIButtonState button_state; - XIModifierState mods; - XIGroupState group; + // unused-- we're not interested in button presses here, as those are + // updated using events + XIButtonState button_state; + XIModifierState mods; + XIGroupState group; - XIQueryPointer(m_display, pointer_deviceid, m_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &button_state, &mods, &group); + XIQueryPointer(m_display, pointer_deviceid, m_window, &root, &child, &root_x, &root_y, &win_x, + &win_y, &button_state, &mods, &group); - free (button_state.mask); + free(button_state.mask); - XWindowAttributes win_attribs; - XGetWindowAttributes(m_display, m_window, &win_attribs); + XWindowAttributes win_attribs; + XGetWindowAttributes(m_display, m_window, &win_attribs); - // the mouse position as a range from -1 to 1 - m_state.cursor.x = win_x / (float)win_attribs.width * 2 - 1; - m_state.cursor.y = win_y / (float)win_attribs.height * 2 - 1; + // the mouse position as a range from -1 to 1 + m_state.cursor.x = win_x / (float)win_attribs.width * 2 - 1; + m_state.cursor.y = win_y / (float)win_attribs.height * 2 - 1; } void KeyboardMouse::UpdateInput() { - XFlush(m_display); - - // Get the absolute position of the mouse pointer - UpdateCursor(); - - // for the axis controls - float delta_x = 0.0f, delta_y = 0.0f; - double delta_delta; - - // Iterate through the event queue - update the axis controls, mouse - // button controls, and keyboard controls. - XEvent event; - while (XPending(m_display)) - { - XNextEvent(m_display, &event); - - if (event.xcookie.type != GenericEvent) - continue; - if (event.xcookie.extension != xi_opcode) - continue; - if (!XGetEventData(m_display, &event.xcookie)) - continue; - - // only one of these will get used - XIDeviceEvent* dev_event = (XIDeviceEvent*)event.xcookie.data; - XIRawEvent* raw_event = (XIRawEvent*)event.xcookie.data; - - switch (event.xcookie.evtype) - { - case XI_ButtonPress: - m_state.buttons |= 1<<(dev_event->detail-1); - break; - case XI_ButtonRelease: - m_state.buttons &= ~(1<<(dev_event->detail-1)); - break; - case XI_KeyPress: - m_state.keyboard[dev_event->detail / 8] |= 1<<(dev_event->detail % 8); - break; - case XI_KeyRelease: - m_state.keyboard[dev_event->detail / 8] &= ~(1<<(dev_event->detail % 8)); - break; - case XI_RawMotion: - // always safe because there is always at least one byte in - // raw_event->valuators.mask, and if a bit is set in the mask, - // then the value in raw_values is also available. - if (XIMaskIsSet(raw_event->valuators.mask, 0)) - { - delta_delta = raw_event->raw_values[0]; - // test for inf and nan - if (delta_delta == delta_delta && 1+delta_delta != delta_delta) - delta_x += delta_delta; - } - if (XIMaskIsSet(raw_event->valuators.mask, 1)) - { - delta_delta = raw_event->raw_values[1]; - // test for inf and nan - if (delta_delta == delta_delta && 1+delta_delta != delta_delta) - delta_y += delta_delta; - } - break; - } - - XFreeEventData(m_display, &event.xcookie); - } - - // apply axis smoothing - m_state.axis.x *= MOUSE_AXIS_SMOOTHING; - m_state.axis.x += delta_x; - m_state.axis.x /= MOUSE_AXIS_SMOOTHING+1.0f; - m_state.axis.y *= MOUSE_AXIS_SMOOTHING; - m_state.axis.y += delta_y; - m_state.axis.y /= MOUSE_AXIS_SMOOTHING+1.0f; + XFlush(m_display); + + // Get the absolute position of the mouse pointer + UpdateCursor(); + + // for the axis controls + float delta_x = 0.0f, delta_y = 0.0f; + double delta_delta; + + // Iterate through the event queue - update the axis controls, mouse + // button controls, and keyboard controls. + XEvent event; + while (XPending(m_display)) + { + XNextEvent(m_display, &event); + + if (event.xcookie.type != GenericEvent) + continue; + if (event.xcookie.extension != xi_opcode) + continue; + if (!XGetEventData(m_display, &event.xcookie)) + continue; + + // only one of these will get used + XIDeviceEvent* dev_event = (XIDeviceEvent*)event.xcookie.data; + XIRawEvent* raw_event = (XIRawEvent*)event.xcookie.data; + + switch (event.xcookie.evtype) + { + case XI_ButtonPress: + m_state.buttons |= 1 << (dev_event->detail - 1); + break; + case XI_ButtonRelease: + m_state.buttons &= ~(1 << (dev_event->detail - 1)); + break; + case XI_KeyPress: + m_state.keyboard[dev_event->detail / 8] |= 1 << (dev_event->detail % 8); + break; + case XI_KeyRelease: + m_state.keyboard[dev_event->detail / 8] &= ~(1 << (dev_event->detail % 8)); + break; + case XI_RawMotion: + // always safe because there is always at least one byte in + // raw_event->valuators.mask, and if a bit is set in the mask, + // then the value in raw_values is also available. + if (XIMaskIsSet(raw_event->valuators.mask, 0)) + { + delta_delta = raw_event->raw_values[0]; + // test for inf and nan + if (delta_delta == delta_delta && 1 + delta_delta != delta_delta) + delta_x += delta_delta; + } + if (XIMaskIsSet(raw_event->valuators.mask, 1)) + { + delta_delta = raw_event->raw_values[1]; + // test for inf and nan + if (delta_delta == delta_delta && 1 + delta_delta != delta_delta) + delta_y += delta_delta; + } + break; + } + + XFreeEventData(m_display, &event.xcookie); + } + + // apply axis smoothing + m_state.axis.x *= MOUSE_AXIS_SMOOTHING; + m_state.axis.x += delta_x; + m_state.axis.x /= MOUSE_AXIS_SMOOTHING + 1.0f; + m_state.axis.y *= MOUSE_AXIS_SMOOTHING; + m_state.axis.y += delta_y; + m_state.axis.y /= MOUSE_AXIS_SMOOTHING + 1.0f; } std::string KeyboardMouse::GetName() const { - // This is the name string we got from the X server for this master - // pointer/keyboard pair. - return name; + // This is the name string we got from the X server for this master + // pointer/keyboard pair. + return name; } std::string KeyboardMouse::GetSource() const { - return "XInput2"; + return "XInput2"; } int KeyboardMouse::GetId() const { - return -1; + return -1; } KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* keyboard) - : m_display(display), m_keyboard(keyboard), m_keycode(keycode) + : m_display(display), m_keyboard(keyboard), m_keycode(keycode) { - int i = 0; - KeySym keysym = 0; - do - { - keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); - i++; - } - while (keysym == NoSymbol && i < 8); - - // Convert to upper case for the keyname - if (keysym >= 97 && keysym <= 122) - keysym -= 32; - - // 0x0110ffff is the top of the unicode character range according - // to keysymdef.h although it is probably more than we need. - if (keysym == NoSymbol || keysym > 0x0110ffff || - XKeysymToString(keysym) == nullptr) - m_keyname = std::string(); - else - m_keyname = std::string(XKeysymToString(keysym)); + int i = 0; + KeySym keysym = 0; + do + { + keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); + i++; + } while (keysym == NoSymbol && i < 8); + + // Convert to upper case for the keyname + if (keysym >= 97 && keysym <= 122) + keysym -= 32; + + // 0x0110ffff is the top of the unicode character range according + // to keysymdef.h although it is probably more than we need. + if (keysym == NoSymbol || keysym > 0x0110ffff || XKeysymToString(keysym) == nullptr) + m_keyname = std::string(); + else + m_keyname = std::string(XKeysymToString(keysym)); } ControlState KeyboardMouse::Key::GetState() const { - return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; + return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; } KeyboardMouse::Button::Button(unsigned int index, unsigned int* buttons) - : m_buttons(buttons), m_index(index) + : m_buttons(buttons), m_index(index) { - // this will be a problem if we remove the hardcoded five-button limit - name = std::string("Click ") + (char)('1' + m_index); + // this will be a problem if we remove the hardcoded five-button limit + name = std::string("Click ") + (char)('1' + m_index); } ControlState KeyboardMouse::Button::GetState() const { - return ((*m_buttons & (1 << m_index)) != 0); + return ((*m_buttons & (1 << m_index)) != 0); } KeyboardMouse::Cursor::Cursor(u8 index, bool positive, const float* cursor) - : m_cursor(cursor), m_index(index), m_positive(positive) + : m_cursor(cursor), m_index(index), m_positive(positive) { - name = std::string("Cursor ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); + name = std::string("Cursor ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); } ControlState KeyboardMouse::Cursor::GetState() const { - return std::max(0.0f, *m_cursor / (m_positive ? 1.0f : -1.0f)); + return std::max(0.0f, *m_cursor / (m_positive ? 1.0f : -1.0f)); } KeyboardMouse::Axis::Axis(u8 index, bool positive, const float* axis) - : m_axis(axis), m_index(index), m_positive(positive) + : m_axis(axis), m_index(index), m_positive(positive) { - name = std::string("Axis ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); + name = std::string("Axis ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); } ControlState KeyboardMouse::Axis::GetState() const { - return std::max(0.0f, *m_axis / (m_positive ? MOUSE_AXIS_SENSITIVITY : -MOUSE_AXIS_SENSITIVITY)); + return std::max(0.0f, *m_axis / (m_positive ? MOUSE_AXIS_SENSITIVITY : -MOUSE_AXIS_SENSITIVITY)); } - } } |
