forked from dolphin-emu/dolphin
		
	Small cleanup by using std::shared_ptr and getting rid of ciface.Devices() which just returned the m_devices (which defeats the point of making m_devices protected). Incidentally, this should make the code safer when we have different threads accessing devices in the future (for hotplug?). A lot of code use Device references directly so there is no easy way to remove FindDevice() and make those unique_ptrs.
		
			
				
	
	
		
			167 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2010 Dolphin Emulator Project
 | 
						|
// Licensed under GPLv2+
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#include <X11/XKBlib.h>
 | 
						|
#include <cstring>
 | 
						|
 | 
						|
#include "InputCommon/ControllerInterface/Xlib/Xlib.h"
 | 
						|
 | 
						|
namespace ciface
 | 
						|
{
 | 
						|
namespace Xlib
 | 
						|
{
 | 
						|
void Init(void* const hwnd)
 | 
						|
{
 | 
						|
  g_controller_interface.AddDevice(std::make_shared<KeyboardMouse>((Window)hwnd));
 | 
						|
}
 | 
						|
 | 
						|
KeyboardMouse::KeyboardMouse(Window window) : m_window(window)
 | 
						|
{
 | 
						|
  memset(&m_state, 0, sizeof(m_state));
 | 
						|
 | 
						|
  m_display = XOpenDisplay(nullptr);
 | 
						|
 | 
						|
  int min_keycode, max_keycode;
 | 
						|
  XDisplayKeycodes(m_display, &min_keycode, &max_keycode);
 | 
						|
 | 
						|
  // 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
 | 
						|
  AddInput(new Button(Button1Mask, m_state.buttons));
 | 
						|
  AddInput(new Button(Button2Mask, m_state.buttons));
 | 
						|
  AddInput(new Button(Button3Mask, m_state.buttons));
 | 
						|
  AddInput(new Button(Button4Mask, m_state.buttons));
 | 
						|
  AddInput(new Button(Button5Mask, m_state.buttons));
 | 
						|
 | 
						|
  // Mouse Cursor, X-/+ and Y-/+
 | 
						|
  for (int i = 0; i != 4; ++i)
 | 
						|
    AddInput(new Cursor(!!(i & 2), !!(i & 1), (&m_state.cursor.x)[!!(i & 2)]));
 | 
						|
}
 | 
						|
 | 
						|
KeyboardMouse::~KeyboardMouse()
 | 
						|
{
 | 
						|
  XCloseDisplay(m_display);
 | 
						|
}
 | 
						|
 | 
						|
void KeyboardMouse::UpdateInput()
 | 
						|
{
 | 
						|
  XQueryKeymap(m_display, m_state.keyboard);
 | 
						|
 | 
						|
  int root_x, root_y, win_x, win_y;
 | 
						|
  Window root, child;
 | 
						|
  XQueryPointer(m_display, m_window, &root, &child, &root_x, &root_y, &win_x, &win_y,
 | 
						|
                &m_state.buttons);
 | 
						|
 | 
						|
  // update mouse cursor
 | 
						|
  XWindowAttributes win_attribs;
 | 
						|
  XGetWindowAttributes(m_display, m_window, &win_attribs);
 | 
						|
 | 
						|
  // the mouse position as a range from -1 to 1
 | 
						|
  m_state.cursor.x = (float)win_x / (float)win_attribs.width * 2 - 1;
 | 
						|
  m_state.cursor.y = (float)win_y / (float)win_attribs.height * 2 - 1;
 | 
						|
}
 | 
						|
 | 
						|
std::string KeyboardMouse::GetName() const
 | 
						|
{
 | 
						|
  return "Keyboard Mouse";
 | 
						|
}
 | 
						|
 | 
						|
std::string KeyboardMouse::GetSource() const
 | 
						|
{
 | 
						|
  return "Xlib";
 | 
						|
}
 | 
						|
 | 
						|
int KeyboardMouse::GetId() const
 | 
						|
{
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* keyboard)
 | 
						|
    : 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));
 | 
						|
}
 | 
						|
 | 
						|
ControlState KeyboardMouse::Key::GetState() const
 | 
						|
{
 | 
						|
  return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0;
 | 
						|
}
 | 
						|
 | 
						|
ControlState KeyboardMouse::Button::GetState() const
 | 
						|
{
 | 
						|
  return ((m_buttons & m_index) != 0);
 | 
						|
}
 | 
						|
 | 
						|
ControlState KeyboardMouse::Cursor::GetState() const
 | 
						|
{
 | 
						|
  return std::max(0.0f, m_cursor / (m_positive ? 1.0f : -1.0f));
 | 
						|
}
 | 
						|
 | 
						|
std::string KeyboardMouse::Key::GetName() const
 | 
						|
{
 | 
						|
  return m_keyname;
 | 
						|
}
 | 
						|
 | 
						|
std::string KeyboardMouse::Cursor::GetName() const
 | 
						|
{
 | 
						|
  static char tmpstr[] = "Cursor ..";
 | 
						|
  tmpstr[7] = (char)('X' + m_index);
 | 
						|
  tmpstr[8] = (m_positive ? '+' : '-');
 | 
						|
  return tmpstr;
 | 
						|
}
 | 
						|
 | 
						|
std::string KeyboardMouse::Button::GetName() const
 | 
						|
{
 | 
						|
  char button = '0';
 | 
						|
  switch (m_index)
 | 
						|
  {
 | 
						|
  case Button1Mask:
 | 
						|
    button = '1';
 | 
						|
    break;
 | 
						|
  case Button2Mask:
 | 
						|
    button = '2';
 | 
						|
    break;
 | 
						|
  case Button3Mask:
 | 
						|
    button = '3';
 | 
						|
    break;
 | 
						|
  case Button4Mask:
 | 
						|
    button = '4';
 | 
						|
    break;
 | 
						|
  case Button5Mask:
 | 
						|
    button = '5';
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  static char tmpstr[] = "Click .";
 | 
						|
  tmpstr[6] = button;
 | 
						|
  return tmpstr;
 | 
						|
}
 | 
						|
}
 | 
						|
}
 |