mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-16 20:13:58 +02:00
Update to v093r12 release.
byuu says: I've completely redone the ethos InputManager and ruby to work on HID::Device objects instead of one giant scancode pool. Currently only the udev driver supports the changes to ruby, so only Linux users will be able to compile and run this WIP build. The nice thing about the new system is that it's now possible to uniquely identify controllers, so if you swap out gamepads, you won't end up with it working but with all the mappings all screwed up. Since higan lets you map multiple physical inputs to one emulated input, you can now configure your keyboard and multiple gamepads to the same emulated input, and then just use whatever controller you want. Because USB gamepad makers failed to provide unique serial#s with each controller, we have to limit the mapping to specific USB ports. Otherwise, we couldn't distinguish two otherwise identical gamepads. So basically your computer USB ports act like real game console input port numbers. Which is kind of neat, I guess. And the really nice thing about the new system is that we now have the capability to support hotplugging input devices. I haven't yet added this to any drivers, but I'm definitely going to add it to udev for v094 official. Finally, with the device ID (vendor ID + product ID) exposed, we gain one last really cool feature that we may be able to develop more in the future. Say we created a joypad.bml file to include with higan. In it, we'd store the Xbox 360 controller, and pre-defined button mappings for each emulated system. So if higan detects you have an Xbox 360 controller, you can just plug it in and use it. Even better, we can clearly specify the difference between triggers and analog axes, and name each individual input. So you'd see "Xbox 360 Gamepad #1: Left Trigger" instead of higan v093's "JP0::Axis2.Hi" Note: for right now, ethos' input manager isn't filtering the device IDs to look pretty. So you're going to see a 64-bit hex value for a device ID right now instead of something like Joypad#N for now.
This commit is contained in:
66
ruby/input/joypad/sdl.cpp
Normal file
66
ruby/input/joypad/sdl.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef RUBY_INPUT_JOYPAD_SDL
|
||||
#define RUBY_INPUT_JOYPAD_SDL
|
||||
|
||||
namespace ruby {
|
||||
|
||||
struct InputJoypadSDL {
|
||||
struct Joystick {
|
||||
unsigned id = 0;
|
||||
SDL_Joystick* handle = nullptr;
|
||||
};
|
||||
vector<Joystick> joysticks;
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
SDL_JoystickUpdate();
|
||||
for(auto& js : joysticks) {
|
||||
unsigned axes = min((unsigned)Joypad::Axes, SDL_JoystickNumAxes(js.handle));
|
||||
for(unsigned axis = 0; axis < axes; axis++) {
|
||||
table[joypad(js.id).axis(axis)] = (int16_t)SDL_JoystickGetAxis(js.handle, axis);
|
||||
}
|
||||
|
||||
unsigned hats = min((unsigned)Joypad::Hats, SDL_JoystickNumHats(js.handle));
|
||||
for(unsigned hat = 0; hat < hats; hat++) {
|
||||
uint8_t state = SDL_JoystickGetHat(js.handle, hat);
|
||||
int16_t value = 0;
|
||||
if(state & SDL_HAT_UP ) value |= Joypad::HatUp;
|
||||
if(state & SDL_HAT_DOWN ) value |= Joypad::HatDown;
|
||||
if(state & SDL_HAT_LEFT ) value |= Joypad::HatLeft;
|
||||
if(state & SDL_HAT_RIGHT) value |= Joypad::HatRight;
|
||||
table[joypad(js.id).hat(hat)] = value;
|
||||
}
|
||||
|
||||
//there is no SDL_JoystickNumButtons function
|
||||
for(unsigned button = 0; button < Joypad::Buttons; button++) {
|
||||
table[joypad(js.id).button(button)] = (bool)SDL_JoystickGetButton(js.handle, button);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool init() {
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
|
||||
unsigned joystickCount = SDL_NumJoysticks();
|
||||
for(unsigned id = 0; id < joystickCount; id++) {
|
||||
Joystick joystick;
|
||||
joystick.id = id;
|
||||
joystick.handle = SDL_JoystickOpen(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
for(auto& js : joysticks) {
|
||||
SDL_JoystickClose(js.handle);
|
||||
}
|
||||
joysticks.reset();
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,3 +1,6 @@
|
||||
#ifndef RUBY_INPUT_JOYPAD_UDEV
|
||||
#define RUBY_INPUT_JOYPAD_UDEV
|
||||
|
||||
namespace ruby {
|
||||
|
||||
struct InputJoypadUdev {
|
||||
@@ -21,9 +24,13 @@ struct InputJoypadUdev {
|
||||
};
|
||||
|
||||
struct Joystick {
|
||||
string path;
|
||||
dev_t device = 0;
|
||||
HID::Joypad hid;
|
||||
|
||||
int fd = -1;
|
||||
dev_t device = 0;
|
||||
string deviceName;
|
||||
string devicePath;
|
||||
|
||||
uint8_t evbit[(EV_MAX + 7) / 8] = {0};
|
||||
uint8_t keybit[(KEY_MAX + 7) / 8] = {0};
|
||||
uint8_t absbit[(ABS_MAX + 7) / 8] = {0};
|
||||
@@ -45,6 +52,48 @@ struct InputJoypadUdev {
|
||||
};
|
||||
vector<Joystick> joysticks;
|
||||
|
||||
void assign(HID::Joypad& hid, unsigned groupID, unsigned inputID, int16_t value) {
|
||||
auto& group = hid.group[groupID];
|
||||
if(group.input[inputID].value == value) return;
|
||||
if(input.onChange) input.onChange(hid, groupID, inputID, group.input[inputID].value, value);
|
||||
group.input[inputID].value = value;
|
||||
}
|
||||
|
||||
void poll(vector<HID::Device*>& devices) {
|
||||
for(auto& js : joysticks) {
|
||||
input_event events[32];
|
||||
signed length = 0;
|
||||
while((length = read(js.fd, events, sizeof(events))) > 0) {
|
||||
length /= sizeof(input_event);
|
||||
for(unsigned i = 0; i < length; i++) {
|
||||
signed code = events[i].code;
|
||||
signed type = events[i].type;
|
||||
signed value = events[i].value;
|
||||
|
||||
if(type == EV_ABS) {
|
||||
if(auto input = js.axes.find({code})) {
|
||||
signed range = input().info.maximum - input().info.minimum;
|
||||
value = (value - input().info.minimum) * 65535ll / range - 32767;
|
||||
assign(js.hid, HID::Joypad::GroupID::Axis, input().id, sclamp<16>(value));
|
||||
} else if(auto input = js.hats.find({code})) {
|
||||
signed range = input().info.maximum - input().info.minimum;
|
||||
value = (value - input().info.minimum) * 65535ll / range - 32767;
|
||||
assign(js.hid, HID::Joypad::GroupID::Hat, input().id, sclamp<16>(value));
|
||||
}
|
||||
} else if(type == EV_KEY) {
|
||||
if(code >= BTN_MISC) {
|
||||
if(auto input = js.buttons.find({code})) {
|
||||
assign(js.hid, HID::Joypad::GroupID::Button, input().id, (bool)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devices.append(&js.hid);
|
||||
}
|
||||
}
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
unsigned i = 0;
|
||||
for(auto& js : joysticks) {
|
||||
@@ -121,18 +170,18 @@ struct InputJoypadUdev {
|
||||
return true;
|
||||
}
|
||||
|
||||
void rumble(unsigned id, bool enable) {
|
||||
if(id >= joysticks.size()) return;
|
||||
void rumble(uint64_t id, bool enable) {
|
||||
for(auto& js : joysticks) {
|
||||
if(js.hid.id != id) continue;
|
||||
if(js.hid.rumble == false) continue;
|
||||
|
||||
Joystick& js = joysticks[id];
|
||||
if(js.rumble == false) return;
|
||||
|
||||
input_event play;
|
||||
memset(&play, 0, sizeof(input_event));
|
||||
play.type = EV_FF;
|
||||
play.code = js.effectID;
|
||||
play.value = enable;
|
||||
write(js.fd, &play, sizeof(input_event));
|
||||
input_event play;
|
||||
memset(&play, 0, sizeof(input_event));
|
||||
play.type = EV_FF;
|
||||
play.code = js.effectID;
|
||||
play.value = enable;
|
||||
write(js.fd, &play, sizeof(input_event));
|
||||
}
|
||||
}
|
||||
|
||||
bool init() {
|
||||
@@ -167,15 +216,15 @@ struct InputJoypadUdev {
|
||||
}
|
||||
|
||||
private:
|
||||
void createJoystick(udev_device* device, const char* path) {
|
||||
void createJoystick(udev_device* device, const char* devicePath) {
|
||||
Joystick js;
|
||||
js.path = path;
|
||||
js.devicePath = devicePath;
|
||||
|
||||
struct stat st;
|
||||
if(stat(path, &st) < 0) return;
|
||||
if(stat(devicePath, &st) < 0) return;
|
||||
js.device = st.st_rdev;
|
||||
|
||||
js.fd = open(path, O_RDWR | O_NONBLOCK);
|
||||
js.fd = open(devicePath, O_RDWR | O_NONBLOCK);
|
||||
if(js.fd < 0) return;
|
||||
|
||||
uint8_t evbit[(EV_MAX + 7) / 8] = {0};
|
||||
@@ -199,6 +248,7 @@ private:
|
||||
if(js.vendorID == udev_device_get_sysattr_value(root, "idVendor")
|
||||
&& js.productID == udev_device_get_sysattr_value(root, "idProduct")
|
||||
) {
|
||||
js.deviceName = udev_device_get_devpath(root);
|
||||
js.manufacturer = udev_device_get_sysattr_value(root, "manufacturer");
|
||||
js.product = udev_device_get_sysattr_value(root, "product");
|
||||
js.serial = udev_device_get_sysattr_value(root, "serial");
|
||||
@@ -244,11 +294,24 @@ private:
|
||||
js.effectID = effect.id;
|
||||
}
|
||||
|
||||
createJoystickHID(js);
|
||||
joysticks.append(js);
|
||||
}
|
||||
|
||||
#undef testBit
|
||||
}
|
||||
|
||||
void createJoystickHID(Joystick& js) {
|
||||
uint64_t pathID = crc32_calculate((const uint8_t*)js.deviceName.data(), js.deviceName.size());
|
||||
js.hid.id = pathID << 32 | hex(js.vendorID) << 16 | hex(js.productID) << 0;
|
||||
|
||||
for(unsigned n = 0; n < js.axes.size(); n++) js.hid.axis.append({n});
|
||||
for(unsigned n = 0; n < js.hats.size(); n++) js.hid.hat.append({n});
|
||||
for(unsigned n = 0; n < js.buttons.size(); n++) js.hid.button.append({n});
|
||||
js.hid.rumble = js.rumble;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,3 +1,6 @@
|
||||
#ifndef RUBY_INPUT_JOYPAD_XINPUT
|
||||
#define RUBY_INPUT_JOYPAD_XINPUT
|
||||
|
||||
#include <xinput.h>
|
||||
|
||||
namespace ruby {
|
||||
@@ -99,3 +102,5 @@ struct InputJoypadXInput {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,9 +1,21 @@
|
||||
#ifndef RUBY_INPUT_KEYBOARD_XLIB
|
||||
#define RUBY_INPUT_KEYBOARD_XLIB
|
||||
|
||||
namespace ruby {
|
||||
|
||||
struct InputKeyboardXlib {
|
||||
HID::Keyboard hid;
|
||||
|
||||
Display* display = nullptr;
|
||||
uint8_t scancode[256] = {0};
|
||||
|
||||
struct Key {
|
||||
string name;
|
||||
unsigned keysym;
|
||||
unsigned keycode;
|
||||
};
|
||||
vector<Key> keys;
|
||||
|
||||
enum XScancode : unsigned {
|
||||
Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
ScrollLock, Pause, Tilde,
|
||||
@@ -18,8 +30,28 @@ struct InputKeyboardXlib {
|
||||
Up, Down, Left, Right,
|
||||
Tab, Return, Spacebar, Menu,
|
||||
LeftShift, RightShift, LeftControl, RightControl, LeftAlt, RightAlt, LeftSuper, RightSuper,
|
||||
Limit,
|
||||
};
|
||||
|
||||
void assign(unsigned inputID, bool value) {
|
||||
auto& group = hid.group[HID::Keyboard::GroupID::Button];
|
||||
if(group.input[inputID].value == value) return;
|
||||
if(input.onChange) input.onChange(hid, HID::Keyboard::GroupID::Button, inputID, group.input[inputID].value, value);
|
||||
group.input[inputID].value = value;
|
||||
}
|
||||
|
||||
void poll(vector<HID::Device*>& devices) {
|
||||
char state[32];
|
||||
XQueryKeymap(display, state);
|
||||
|
||||
for(unsigned n = 0; n < keys.size(); n++) {
|
||||
bool value = state[keys[n].keycode >> 3] & (1 << (keys[n].keycode & 7));
|
||||
assign(n, value);
|
||||
}
|
||||
|
||||
devices.append(&hid);
|
||||
}
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
char state[32];
|
||||
XQueryKeymap(display, state);
|
||||
@@ -146,6 +178,127 @@ struct InputKeyboardXlib {
|
||||
bool init() {
|
||||
display = XOpenDisplay(0);
|
||||
|
||||
keys.append({"Escape", XK_Escape});
|
||||
|
||||
keys.append({"F1", XK_F1});
|
||||
keys.append({"F2", XK_F2});
|
||||
keys.append({"F3", XK_F3});
|
||||
keys.append({"F4", XK_F4});
|
||||
keys.append({"F5", XK_F5});
|
||||
keys.append({"F6", XK_F6});
|
||||
keys.append({"F7", XK_F7});
|
||||
keys.append({"F8", XK_F8});
|
||||
keys.append({"F9", XK_F9});
|
||||
keys.append({"F10", XK_F10});
|
||||
keys.append({"F11", XK_F11});
|
||||
keys.append({"F12", XK_F12});
|
||||
|
||||
keys.append({"ScrollLock", XK_Scroll_Lock});
|
||||
keys.append({"Pause", XK_Pause});
|
||||
|
||||
keys.append({"Tilde", XK_asciitilde});
|
||||
|
||||
keys.append({"Num0", XK_0});
|
||||
keys.append({"Num1", XK_1});
|
||||
keys.append({"Num2", XK_2});
|
||||
keys.append({"Num3", XK_3});
|
||||
keys.append({"Num4", XK_4});
|
||||
keys.append({"Num5", XK_5});
|
||||
keys.append({"Num6", XK_6});
|
||||
keys.append({"Num7", XK_7});
|
||||
keys.append({"Num8", XK_8});
|
||||
keys.append({"Num9", XK_9});
|
||||
|
||||
keys.append({"Dash", XK_minus});
|
||||
keys.append({"Equal", XK_equal});
|
||||
keys.append({"Backspace", XK_BackSpace});
|
||||
|
||||
keys.append({"Insert", XK_Insert});
|
||||
keys.append({"Delete", XK_Delete});
|
||||
keys.append({"Home", XK_Home});
|
||||
keys.append({"End", XK_End});
|
||||
keys.append({"PageUp", XK_Prior});
|
||||
keys.append({"PageDown", XK_Next});
|
||||
|
||||
keys.append({"A", XK_A});
|
||||
keys.append({"B", XK_B});
|
||||
keys.append({"C", XK_C});
|
||||
keys.append({"D", XK_D});
|
||||
keys.append({"E", XK_E});
|
||||
keys.append({"F", XK_F});
|
||||
keys.append({"G", XK_G});
|
||||
keys.append({"H", XK_H});
|
||||
keys.append({"I", XK_I});
|
||||
keys.append({"J", XK_J});
|
||||
keys.append({"K", XK_K});
|
||||
keys.append({"L", XK_L});
|
||||
keys.append({"M", XK_M});
|
||||
keys.append({"N", XK_N});
|
||||
keys.append({"O", XK_O});
|
||||
keys.append({"P", XK_P});
|
||||
keys.append({"Q", XK_Q});
|
||||
keys.append({"R", XK_R});
|
||||
keys.append({"S", XK_S});
|
||||
keys.append({"T", XK_T});
|
||||
keys.append({"U", XK_U});
|
||||
keys.append({"V", XK_V});
|
||||
keys.append({"W", XK_W});
|
||||
keys.append({"X", XK_X});
|
||||
keys.append({"Y", XK_Y});
|
||||
keys.append({"Z", XK_Z});
|
||||
|
||||
keys.append({"LeftBracket", XK_bracketleft});
|
||||
keys.append({"RightBracket", XK_bracketright});
|
||||
keys.append({"Backslash", XK_backslash});
|
||||
keys.append({"Semicolon", XK_semicolon});
|
||||
keys.append({"Apostrophe", XK_apostrophe});
|
||||
keys.append({"Comma", XK_comma});
|
||||
keys.append({"Period", XK_period});
|
||||
keys.append({"Slash", XK_slash});
|
||||
|
||||
keys.append({"Keypad0", XK_KP_0});
|
||||
keys.append({"Keypad1", XK_KP_1});
|
||||
keys.append({"Keypad2", XK_KP_2});
|
||||
keys.append({"Keypad3", XK_KP_3});
|
||||
keys.append({"Keypad4", XK_KP_4});
|
||||
keys.append({"Keypad5", XK_KP_5});
|
||||
keys.append({"Keypad6", XK_KP_6});
|
||||
keys.append({"Keypad7", XK_KP_7});
|
||||
keys.append({"Keypad8", XK_KP_8});
|
||||
keys.append({"Keypad9", XK_KP_9});
|
||||
|
||||
keys.append({"Add", XK_KP_Add});
|
||||
keys.append({"Subtract", XK_KP_Subtract});
|
||||
keys.append({"Multiply", XK_KP_Multiply});
|
||||
keys.append({"Divide", XK_KP_Divide});
|
||||
keys.append({"Enter", XK_KP_Enter});
|
||||
|
||||
keys.append({"Up", XK_Up});
|
||||
keys.append({"Down", XK_Down});
|
||||
keys.append({"Left", XK_Left});
|
||||
keys.append({"Right", XK_Right});
|
||||
|
||||
keys.append({"Tab", XK_Tab});
|
||||
keys.append({"Return", XK_Return});
|
||||
keys.append({"Spacebar", XK_space});
|
||||
|
||||
keys.append({"LeftControl", XK_Control_L});
|
||||
keys.append({"RightControl", XK_Control_R});
|
||||
keys.append({"LeftAlt", XK_Alt_L});
|
||||
keys.append({"RightAlt", XK_Alt_R});
|
||||
keys.append({"LeftShift", XK_Shift_L});
|
||||
keys.append({"RightShift", XK_Shift_R});
|
||||
keys.append({"LeftSuper", XK_Super_L});
|
||||
keys.append({"RightSuper", XK_Super_R});
|
||||
keys.append({"Menu", XK_Menu});
|
||||
|
||||
hid.id = 1;
|
||||
|
||||
for(unsigned n = 0; n < keys.size(); n++) {
|
||||
hid.button.append(keys[n].name);
|
||||
keys[n].keycode = XKeysymToKeycode(display, keys[n].keysym);
|
||||
}
|
||||
|
||||
#define assign(x, y) scancode[x] = XKeysymToKeycode(display, y)
|
||||
assign(Escape, XK_Escape);
|
||||
|
||||
@@ -275,3 +428,5 @@ struct InputKeyboardXlib {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,11 @@
|
||||
#ifndef RUBY_INPUT_MOUSE_XLIB
|
||||
#define RUBY_INPUT_MOUSE_XLIB
|
||||
|
||||
namespace ruby {
|
||||
|
||||
struct InputMouseXlib {
|
||||
HID::Mouse hid;
|
||||
|
||||
uintptr_t handle = 0;
|
||||
|
||||
Display* display = nullptr;
|
||||
@@ -51,6 +56,52 @@ struct InputMouseXlib {
|
||||
return ms.acquired;
|
||||
}
|
||||
|
||||
void assign(unsigned groupID, unsigned inputID, int16_t value) {
|
||||
auto& group = hid.group[groupID];
|
||||
if(group.input[inputID].value == value) return;
|
||||
if(input.onChange) input.onChange(hid, groupID, inputID, group.input[inputID].value, value);
|
||||
group.input[inputID].value = value;
|
||||
}
|
||||
|
||||
void poll(vector<HID::Device*>& devices) {
|
||||
Window rootReturn;
|
||||
Window childReturn;
|
||||
signed rootXReturn = 0;
|
||||
signed rootYReturn = 0;
|
||||
signed windowXReturn = 0;
|
||||
signed windowYReturn = 0;
|
||||
unsigned maskReturn = 0;
|
||||
XQueryPointer(display, handle, &rootReturn, &childReturn, &rootXReturn, &rootYReturn, &windowXReturn, &windowYReturn, &maskReturn);
|
||||
|
||||
if(acquired()) {
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(display, handle, &attributes);
|
||||
|
||||
//absolute -> relative conversion
|
||||
assign(HID::Mouse::GroupID::Axis, 0, (int16_t)(rootXReturn - screenWidth / 2));
|
||||
assign(HID::Mouse::GroupID::Axis, 1, (int16_t)(rootYReturn - screenHeight / 2));
|
||||
|
||||
if(hid.axis.input[0].value != 0 || hid.axis.input[1].value != 0) {
|
||||
//if mouse moved, re-center mouse for next poll
|
||||
XWarpPointer(display, None, rootWindow, 0, 0, 0, 0, screenWidth / 2, screenHeight / 2);
|
||||
}
|
||||
} else {
|
||||
assign(HID::Mouse::GroupID::Axis, 0, (int16_t)(rootXReturn - ms.relativeX));
|
||||
assign(HID::Mouse::GroupID::Axis, 1, (int16_t)(rootYReturn - ms.relativeY));
|
||||
|
||||
ms.relativeX = rootXReturn;
|
||||
ms.relativeY = rootYReturn;
|
||||
}
|
||||
|
||||
assign(HID::Mouse::GroupID::Button, 0, (bool)(maskReturn & Button1Mask));
|
||||
assign(HID::Mouse::GroupID::Button, 1, (bool)(maskReturn & Button2Mask));
|
||||
assign(HID::Mouse::GroupID::Button, 2, (bool)(maskReturn & Button3Mask));
|
||||
assign(HID::Mouse::GroupID::Button, 3, (bool)(maskReturn & Button4Mask));
|
||||
assign(HID::Mouse::GroupID::Button, 4, (bool)(maskReturn & Button5Mask));
|
||||
|
||||
devices.append(&hid);
|
||||
}
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
Window rootReturn;
|
||||
Window childReturn;
|
||||
@@ -115,6 +166,17 @@ struct InputMouseXlib {
|
||||
ms.relativeX = 0;
|
||||
ms.relativeY = 0;
|
||||
|
||||
hid.id = 2;
|
||||
|
||||
hid.axis.append({"X"});
|
||||
hid.axis.append({"Y"});
|
||||
|
||||
hid.button.append({"Left"});
|
||||
hid.button.append({"Middle"});
|
||||
hid.button.append({"Right"});
|
||||
hid.button.append({"Up"});
|
||||
hid.button.append({"Down"});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,3 +188,5 @@ struct InputMouseXlib {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,37 +1,20 @@
|
||||
//================
|
||||
//SDL input driver
|
||||
//================
|
||||
//Keyboard and mouse are controlled directly via Xlib,
|
||||
//as SDL cannot capture input from windows it does not create itself.
|
||||
//SDL is used only to handle joysticks / gamepads.
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include "keyboard/xlib.cpp"
|
||||
#include "mouse/xlib.cpp"
|
||||
#include "joypad/sdl.cpp"
|
||||
|
||||
namespace ruby {
|
||||
|
||||
struct pInputSDL {
|
||||
#include "xlibkeys.hpp"
|
||||
InputKeyboardXlib xlibKeyboard;
|
||||
InputMouseXlib xlibMouse;
|
||||
InputJoypadSDL sdl;
|
||||
|
||||
struct {
|
||||
Display* display;
|
||||
Window rootwindow;
|
||||
Cursor InvisibleCursor;
|
||||
SDL_Joystick* gamepad[Joypad::Count];
|
||||
|
||||
unsigned screenwidth, screenheight;
|
||||
unsigned relativex, relativey;
|
||||
bool mouseacquired;
|
||||
|
||||
//mouse device settings
|
||||
int accel_numerator;
|
||||
int accel_denominator;
|
||||
int threshold;
|
||||
} device;
|
||||
|
||||
struct {
|
||||
uintptr_t handle;
|
||||
struct Settings {
|
||||
uintptr_t handle = 0;
|
||||
} settings;
|
||||
|
||||
bool cap(const string& name) {
|
||||
@@ -57,117 +40,21 @@ struct pInputSDL {
|
||||
}
|
||||
|
||||
bool acquire() {
|
||||
if(acquired()) return true;
|
||||
|
||||
if(XGrabPointer(device.display, settings.handle, True, 0, GrabModeAsync, GrabModeAsync,
|
||||
device.rootwindow, device.InvisibleCursor, CurrentTime) == GrabSuccess) {
|
||||
//backup existing cursor acceleration settings
|
||||
XGetPointerControl(device.display, &device.accel_numerator, &device.accel_denominator, &device.threshold);
|
||||
|
||||
//disable cursor acceleration
|
||||
XChangePointerControl(device.display, True, False, 1, 1, 0);
|
||||
|
||||
//center cursor (so that first relative poll returns 0, 0 if mouse has not moved)
|
||||
XWarpPointer(device.display, None, device.rootwindow, 0, 0, 0, 0, device.screenwidth / 2, device.screenheight / 2);
|
||||
|
||||
return device.mouseacquired = true;
|
||||
} else {
|
||||
return device.mouseacquired = false;
|
||||
}
|
||||
return xlibMouse.acquire();
|
||||
}
|
||||
|
||||
bool unacquire() {
|
||||
if(acquired()) {
|
||||
//restore cursor acceleration and release cursor
|
||||
XChangePointerControl(device.display, True, True, device.accel_numerator, device.accel_denominator, device.threshold);
|
||||
XUngrabPointer(device.display, CurrentTime);
|
||||
device.mouseacquired = false;
|
||||
}
|
||||
return true;
|
||||
return xlibMouse.unacquire();
|
||||
}
|
||||
|
||||
bool acquired() {
|
||||
return device.mouseacquired;
|
||||
return xlibMouse.acquired();
|
||||
}
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
memset(table, 0, Scancode::Limit * sizeof(int16_t));
|
||||
|
||||
//========
|
||||
//Keyboard
|
||||
//========
|
||||
|
||||
x_poll(device.display, table);
|
||||
|
||||
//=====
|
||||
//Mouse
|
||||
//=====
|
||||
|
||||
Window root_return, child_return;
|
||||
int root_x_return = 0, root_y_return = 0;
|
||||
int win_x_return = 0, win_y_return = 0;
|
||||
unsigned int mask_return = 0;
|
||||
XQueryPointer(device.display, settings.handle,
|
||||
&root_return, &child_return, &root_x_return, &root_y_return,
|
||||
&win_x_return, &win_y_return, &mask_return);
|
||||
|
||||
if(acquired()) {
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(device.display, settings.handle, &attributes);
|
||||
|
||||
//absolute -> relative conversion
|
||||
table[mouse(0).axis(0)] = (int16_t)(root_x_return - device.screenwidth / 2);
|
||||
table[mouse(0).axis(1)] = (int16_t)(root_y_return - device.screenheight / 2);
|
||||
|
||||
if(table[mouse(0).axis(0)] != 0 || table[mouse(0).axis(1)] != 0) {
|
||||
//if mouse movement occurred, re-center mouse for next poll
|
||||
XWarpPointer(device.display, None, device.rootwindow, 0, 0, 0, 0, device.screenwidth / 2, device.screenheight / 2);
|
||||
}
|
||||
} else {
|
||||
table[mouse(0).axis(0)] = (int16_t)(root_x_return - device.relativex);
|
||||
table[mouse(0).axis(1)] = (int16_t)(root_y_return - device.relativey);
|
||||
|
||||
device.relativex = root_x_return;
|
||||
device.relativey = root_y_return;
|
||||
}
|
||||
|
||||
//manual device polling is limited to only five buttons ...
|
||||
table[mouse(0).button(0)] = (bool)(mask_return & Button1Mask);
|
||||
table[mouse(0).button(1)] = (bool)(mask_return & Button2Mask);
|
||||
table[mouse(0).button(2)] = (bool)(mask_return & Button3Mask);
|
||||
table[mouse(0).button(3)] = (bool)(mask_return & Button4Mask);
|
||||
table[mouse(0).button(4)] = (bool)(mask_return & Button5Mask);
|
||||
|
||||
//=========
|
||||
//Joypad(s)
|
||||
//=========
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
for(unsigned i = 0; i < Joypad::Count; i++) {
|
||||
if(!device.gamepad[i]) continue;
|
||||
|
||||
//POV hats
|
||||
unsigned hats = min((unsigned)Joypad::Hats, SDL_JoystickNumHats(device.gamepad[i]));
|
||||
for(unsigned hat = 0; hat < hats; hat++) {
|
||||
uint8_t state = SDL_JoystickGetHat(device.gamepad[i], hat);
|
||||
if(state & SDL_HAT_UP ) table[joypad(i).hat(hat)] |= Joypad::HatUp;
|
||||
if(state & SDL_HAT_RIGHT) table[joypad(i).hat(hat)] |= Joypad::HatRight;
|
||||
if(state & SDL_HAT_DOWN ) table[joypad(i).hat(hat)] |= Joypad::HatDown;
|
||||
if(state & SDL_HAT_LEFT ) table[joypad(i).hat(hat)] |= Joypad::HatLeft;
|
||||
}
|
||||
|
||||
//axes
|
||||
unsigned axes = min((unsigned)Joypad::Axes, SDL_JoystickNumAxes(device.gamepad[i]));
|
||||
for(unsigned axis = 0; axis < axes; axis++) {
|
||||
table[joypad(i).axis(axis)] = (int16_t)SDL_JoystickGetAxis(device.gamepad[i], axis);
|
||||
}
|
||||
|
||||
//buttons
|
||||
for(unsigned button = 0; button < Joypad::Buttons; button++) {
|
||||
table[joypad(i).button(button)] = (bool)SDL_JoystickGetButton(device.gamepad[i], button);
|
||||
}
|
||||
}
|
||||
|
||||
xlibKeyboard.poll(table);
|
||||
xlibMouse.poll(table);
|
||||
sdl.poll(table);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -175,56 +62,16 @@ struct pInputSDL {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
|
||||
device.display = XOpenDisplay(0);
|
||||
device.rootwindow = DefaultRootWindow(device.display);
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(device.display, device.rootwindow, &attributes);
|
||||
device.screenwidth = attributes.width;
|
||||
device.screenheight = attributes.height;
|
||||
x_init(device.display);
|
||||
|
||||
//Xlib: "because XShowCursor(false) would be too easy."
|
||||
//create a fully transparent cursor named InvisibleCursor,
|
||||
//for use while acquire() / XGrabPointer() is active.
|
||||
Pixmap pixmap;
|
||||
XColor black, unused;
|
||||
static char invisible_data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Colormap colormap = DefaultColormap(device.display, DefaultScreen(device.display));
|
||||
XAllocNamedColor(device.display, colormap, "black", &black, &unused);
|
||||
pixmap = XCreateBitmapFromData(device.display, settings.handle, invisible_data, 8, 8);
|
||||
device.InvisibleCursor = XCreatePixmapCursor(device.display, pixmap, pixmap, &black, &black, 0, 0);
|
||||
XFreePixmap(device.display, pixmap);
|
||||
XFreeColors(device.display, colormap, &black.pixel, 1, 0);
|
||||
|
||||
device.mouseacquired = false;
|
||||
device.relativex = 0;
|
||||
device.relativey = 0;
|
||||
|
||||
unsigned joypads = min((unsigned)Joypad::Count, SDL_NumJoysticks());
|
||||
for(unsigned i = 0; i < joypads; i++) device.gamepad[i] = SDL_JoystickOpen(i);
|
||||
|
||||
if(xlibKeyboard.init() == false) return false;
|
||||
if(xlibMouse.init(settings.handle) == false) return false;
|
||||
if(sdl.init() == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
unacquire();
|
||||
XFreeCursor(device.display, device.InvisibleCursor);
|
||||
|
||||
for(unsigned i = 0; i < Joypad::Count; i++) {
|
||||
if(device.gamepad[i]) SDL_JoystickClose(device.gamepad[i]);
|
||||
device.gamepad[i] = 0;
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
XCloseDisplay(device.display);
|
||||
}
|
||||
|
||||
pInputSDL() {
|
||||
for(unsigned i = 0; i < Joypad::Count; i++) device.gamepad[i] = 0;
|
||||
settings.handle = 0;
|
||||
xlibKeyboard.term();
|
||||
xlibMouse.term();
|
||||
sdl.term();
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -57,13 +57,22 @@ struct pInputUdev {
|
||||
return xlibMouse.acquired();
|
||||
}
|
||||
|
||||
vector<HID::Device*> poll() {
|
||||
vector<HID::Device*> devices;
|
||||
xlibKeyboard.poll(devices);
|
||||
xlibMouse.poll(devices);
|
||||
udev.poll(devices);
|
||||
return devices;
|
||||
}
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
xlibKeyboard.poll(table);
|
||||
xlibMouse.poll(table);
|
||||
udev.poll(table);
|
||||
return true;
|
||||
}
|
||||
|
||||
void rumble(unsigned id, bool enable) {
|
||||
void rumble(uint64_t id, bool enable) {
|
||||
udev.rumble(id, enable);
|
||||
}
|
||||
|
||||
|
@@ -1,53 +0,0 @@
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
namespace ruby {
|
||||
|
||||
class pInputX {
|
||||
public:
|
||||
Display *display;
|
||||
#include "xlibkeys.hpp"
|
||||
|
||||
bool cap(const string& name) {
|
||||
if(name == Input::KeyboardSupport) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set(const string& name, const any &value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool acquire() { return false; }
|
||||
bool unacquire() { return false; }
|
||||
bool acquired() { return false; }
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
memset(table, 0, Scancode::Limit * sizeof(int16_t));
|
||||
x_poll(display, table);
|
||||
return true;
|
||||
}
|
||||
|
||||
void rumble(unsigned id, bool enable) {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
display = XOpenDisplay(0);
|
||||
x_init(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
};
|
||||
|
||||
DeclareInput(X)
|
||||
|
||||
}
|
75
ruby/input/xlib.cpp
Normal file
75
ruby/input/xlib.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "keyboard/xlib.cpp"
|
||||
#include "mouse/xlib.cpp"
|
||||
|
||||
namespace ruby {
|
||||
|
||||
struct pInputXlib {
|
||||
InputKeyboardXlib xlibKeyboard;
|
||||
InputMouseXlib xlibMouse;
|
||||
|
||||
struct Settings {
|
||||
uintptr_t handle = 0;
|
||||
} settings;
|
||||
|
||||
bool cap(const string& name) {
|
||||
if(name == Input::KeyboardSupport) return true;
|
||||
if(name == Input::MouseSupport) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
if(name == Input::Handle) return (uintptr_t)settings.handle;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set(const string& name, const any &value) {
|
||||
if(name == Input::Handle) {
|
||||
settings.handle = any_cast<uintptr_t>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool acquire() {
|
||||
return xlibMouse.acquire();
|
||||
}
|
||||
|
||||
bool unacquire() {
|
||||
return xlibMouse.unacquire();
|
||||
}
|
||||
|
||||
bool acquired() {
|
||||
return xlibMouse.acquired();
|
||||
}
|
||||
|
||||
bool poll(int16_t* table) {
|
||||
xlibKeyboard.poll(table);
|
||||
xlibMouse.poll(table);
|
||||
return true;
|
||||
}
|
||||
|
||||
void rumble(unsigned id, bool enable) {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
if(xlibKeyboard.init() == false) return false;
|
||||
if(xlibMouse.init(settings.handle) == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
xlibKeyboard.term();
|
||||
xlibMouse.term();
|
||||
}
|
||||
};
|
||||
|
||||
DeclareInput(Xlib)
|
||||
|
||||
}
|
@@ -1,263 +0,0 @@
|
||||
uint8_t scancode[256];
|
||||
|
||||
enum XScancode {
|
||||
Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
ScrollLock, Pause, Tilde,
|
||||
Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Num0,
|
||||
Dash, Equal, Backspace,
|
||||
Insert, Delete, Home, End, PageUp, PageDown,
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M,
|
||||
N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
|
||||
LeftBracket, RightBracket, Backslash, Semicolon, Apostrophe, Comma, Period, Slash,
|
||||
Keypad1, Keypad2, Keypad3, Keypad4, Keypad5, Keypad6, Keypad7, Keypad8, Keypad9, Keypad0,
|
||||
Point, Enter, Add, Subtract, Multiply, Divide,
|
||||
Up, Down, Left, Right,
|
||||
Tab, Return, Spacebar, Menu,
|
||||
LeftShift, RightShift, LeftControl, RightControl, LeftAlt, RightAlt, LeftSuper, RightSuper,
|
||||
};
|
||||
|
||||
void x_poll(Display* display, int16_t* table) {
|
||||
if(!display) return;
|
||||
|
||||
char state[32];
|
||||
XQueryKeymap(display, state);
|
||||
|
||||
#define key(id) table[keyboard(0)[id]]
|
||||
#define pressed(id) (bool)(state[scancode[id] >> 3] & (1 << (scancode[id] & 7)))
|
||||
|
||||
key(Keyboard::Escape) = pressed(Escape);
|
||||
|
||||
key(Keyboard::F1) = pressed(F1);
|
||||
key(Keyboard::F2) = pressed(F2);
|
||||
key(Keyboard::F3) = pressed(F3);
|
||||
key(Keyboard::F4) = pressed(F4);
|
||||
key(Keyboard::F5) = pressed(F5);
|
||||
key(Keyboard::F6) = pressed(F6);
|
||||
key(Keyboard::F7) = pressed(F7);
|
||||
key(Keyboard::F8) = pressed(F8);
|
||||
key(Keyboard::F9) = pressed(F9);
|
||||
key(Keyboard::F10) = pressed(F10);
|
||||
key(Keyboard::F11) = pressed(F11);
|
||||
key(Keyboard::F12) = pressed(F12);
|
||||
|
||||
key(Keyboard::ScrollLock) = pressed(ScrollLock);
|
||||
key(Keyboard::Pause) = pressed(Pause);
|
||||
key(Keyboard::Tilde) = pressed(Tilde);
|
||||
|
||||
key(Keyboard::Num1) = pressed(Num1);
|
||||
key(Keyboard::Num2) = pressed(Num2);
|
||||
key(Keyboard::Num3) = pressed(Num3);
|
||||
key(Keyboard::Num4) = pressed(Num4);
|
||||
key(Keyboard::Num5) = pressed(Num5);
|
||||
key(Keyboard::Num6) = pressed(Num6);
|
||||
key(Keyboard::Num7) = pressed(Num7);
|
||||
key(Keyboard::Num8) = pressed(Num8);
|
||||
key(Keyboard::Num9) = pressed(Num9);
|
||||
key(Keyboard::Num0) = pressed(Num0);
|
||||
|
||||
key(Keyboard::Dash) = pressed(Dash);
|
||||
key(Keyboard::Equal) = pressed(Equal);
|
||||
key(Keyboard::Backspace) = pressed(Backspace);
|
||||
|
||||
key(Keyboard::Insert) = pressed(Insert);
|
||||
key(Keyboard::Delete) = pressed(Delete);
|
||||
key(Keyboard::Home) = pressed(Home);
|
||||
key(Keyboard::End) = pressed(End);
|
||||
key(Keyboard::PageUp) = pressed(PageUp);
|
||||
key(Keyboard::PageDown) = pressed(PageDown);
|
||||
|
||||
key(Keyboard::A) = pressed(A);
|
||||
key(Keyboard::B) = pressed(B);
|
||||
key(Keyboard::C) = pressed(C);
|
||||
key(Keyboard::D) = pressed(D);
|
||||
key(Keyboard::E) = pressed(E);
|
||||
key(Keyboard::F) = pressed(F);
|
||||
key(Keyboard::G) = pressed(G);
|
||||
key(Keyboard::H) = pressed(H);
|
||||
key(Keyboard::I) = pressed(I);
|
||||
key(Keyboard::J) = pressed(J);
|
||||
key(Keyboard::K) = pressed(K);
|
||||
key(Keyboard::L) = pressed(L);
|
||||
key(Keyboard::M) = pressed(M);
|
||||
key(Keyboard::N) = pressed(N);
|
||||
key(Keyboard::O) = pressed(O);
|
||||
key(Keyboard::P) = pressed(P);
|
||||
key(Keyboard::Q) = pressed(Q);
|
||||
key(Keyboard::R) = pressed(R);
|
||||
key(Keyboard::S) = pressed(S);
|
||||
key(Keyboard::T) = pressed(T);
|
||||
key(Keyboard::U) = pressed(U);
|
||||
key(Keyboard::V) = pressed(V);
|
||||
key(Keyboard::W) = pressed(W);
|
||||
key(Keyboard::X) = pressed(X);
|
||||
key(Keyboard::Y) = pressed(Y);
|
||||
key(Keyboard::Z) = pressed(Z);
|
||||
|
||||
key(Keyboard::LeftBracket) = pressed(LeftBracket);
|
||||
key(Keyboard::RightBracket) = pressed(RightBracket);
|
||||
key(Keyboard::Backslash) = pressed(Backslash);
|
||||
key(Keyboard::Semicolon) = pressed(Semicolon);
|
||||
key(Keyboard::Apostrophe) = pressed(Apostrophe);
|
||||
key(Keyboard::Comma) = pressed(Comma);
|
||||
key(Keyboard::Period) = pressed(Period);
|
||||
key(Keyboard::Slash) = pressed(Slash);
|
||||
|
||||
key(Keyboard::Keypad1) = pressed(Keypad1);
|
||||
key(Keyboard::Keypad2) = pressed(Keypad2);
|
||||
key(Keyboard::Keypad3) = pressed(Keypad3);
|
||||
key(Keyboard::Keypad4) = pressed(Keypad4);
|
||||
key(Keyboard::Keypad5) = pressed(Keypad5);
|
||||
key(Keyboard::Keypad6) = pressed(Keypad6);
|
||||
key(Keyboard::Keypad7) = pressed(Keypad7);
|
||||
key(Keyboard::Keypad8) = pressed(Keypad8);
|
||||
key(Keyboard::Keypad9) = pressed(Keypad9);
|
||||
key(Keyboard::Keypad0) = pressed(Keypad0);
|
||||
|
||||
key(Keyboard::Point) = pressed(Point);
|
||||
key(Keyboard::Enter) = pressed(Enter);
|
||||
key(Keyboard::Add) = pressed(Add);
|
||||
key(Keyboard::Subtract) = pressed(Subtract);
|
||||
key(Keyboard::Multiply) = pressed(Multiply);
|
||||
key(Keyboard::Divide) = pressed(Divide);
|
||||
|
||||
key(Keyboard::Up) = pressed(Up);
|
||||
key(Keyboard::Down) = pressed(Down);
|
||||
key(Keyboard::Left) = pressed(Left);
|
||||
key(Keyboard::Right) = pressed(Right);
|
||||
|
||||
key(Keyboard::Tab) = pressed(Tab);
|
||||
key(Keyboard::Return) = pressed(Return);
|
||||
key(Keyboard::Spacebar) = pressed(Spacebar);
|
||||
key(Keyboard::Menu) = pressed(Menu);
|
||||
|
||||
key(Keyboard::Shift) = pressed(LeftShift) || pressed(RightShift);
|
||||
key(Keyboard::Control) = pressed(LeftControl) || pressed(RightControl);
|
||||
key(Keyboard::Alt) = pressed(LeftAlt) || pressed(RightAlt);
|
||||
key(Keyboard::Super) = pressed(LeftSuper) || pressed(RightSuper);
|
||||
|
||||
#undef key
|
||||
#undef pressed
|
||||
}
|
||||
|
||||
void x_init(Display* display) {
|
||||
if(!display) return;
|
||||
|
||||
memset(&scancode, 0, sizeof scancode);
|
||||
|
||||
#define assign(x, y) scancode[x] = XKeysymToKeycode(display, y)
|
||||
assign(Escape, XK_Escape);
|
||||
|
||||
assign(F1, XK_F1);
|
||||
assign(F2, XK_F2);
|
||||
assign(F3, XK_F3);
|
||||
assign(F4, XK_F4);
|
||||
assign(F5, XK_F5);
|
||||
assign(F6, XK_F6);
|
||||
assign(F7, XK_F7);
|
||||
assign(F8, XK_F8);
|
||||
assign(F9, XK_F9);
|
||||
assign(F10, XK_F10);
|
||||
assign(F11, XK_F11);
|
||||
assign(F12, XK_F12);
|
||||
|
||||
assign(ScrollLock, XK_Scroll_Lock);
|
||||
assign(Pause, XK_Pause);
|
||||
|
||||
assign(Tilde, XK_asciitilde);
|
||||
|
||||
assign(Num0, XK_0);
|
||||
assign(Num1, XK_1);
|
||||
assign(Num2, XK_2);
|
||||
assign(Num3, XK_3);
|
||||
assign(Num4, XK_4);
|
||||
assign(Num5, XK_5);
|
||||
assign(Num6, XK_6);
|
||||
assign(Num7, XK_7);
|
||||
assign(Num8, XK_8);
|
||||
assign(Num9, XK_9);
|
||||
|
||||
assign(Dash, XK_minus);
|
||||
assign(Equal, XK_equal);
|
||||
assign(Backspace, XK_BackSpace);
|
||||
|
||||
assign(Insert, XK_Insert);
|
||||
assign(Delete, XK_Delete);
|
||||
assign(Home, XK_Home);
|
||||
assign(End, XK_End);
|
||||
assign(PageUp, XK_Prior);
|
||||
assign(PageDown, XK_Next);
|
||||
|
||||
assign(A, XK_A);
|
||||
assign(B, XK_B);
|
||||
assign(C, XK_C);
|
||||
assign(D, XK_D);
|
||||
assign(E, XK_E);
|
||||
assign(F, XK_F);
|
||||
assign(G, XK_G);
|
||||
assign(H, XK_H);
|
||||
assign(I, XK_I);
|
||||
assign(J, XK_J);
|
||||
assign(K, XK_K);
|
||||
assign(L, XK_L);
|
||||
assign(M, XK_M);
|
||||
assign(N, XK_N);
|
||||
assign(O, XK_O);
|
||||
assign(P, XK_P);
|
||||
assign(Q, XK_Q);
|
||||
assign(R, XK_R);
|
||||
assign(S, XK_S);
|
||||
assign(T, XK_T);
|
||||
assign(U, XK_U);
|
||||
assign(V, XK_V);
|
||||
assign(W, XK_W);
|
||||
assign(X, XK_X);
|
||||
assign(Y, XK_Y);
|
||||
assign(Z, XK_Z);
|
||||
|
||||
assign(LeftBracket, XK_bracketleft);
|
||||
assign(RightBracket, XK_bracketright);
|
||||
assign(Backslash, XK_backslash);
|
||||
assign(Semicolon, XK_semicolon);
|
||||
assign(Apostrophe, XK_apostrophe);
|
||||
assign(Comma, XK_comma);
|
||||
assign(Period, XK_period);
|
||||
assign(Slash, XK_slash);
|
||||
|
||||
assign(Keypad0, XK_KP_0);
|
||||
assign(Keypad1, XK_KP_1);
|
||||
assign(Keypad2, XK_KP_2);
|
||||
assign(Keypad3, XK_KP_3);
|
||||
assign(Keypad4, XK_KP_4);
|
||||
assign(Keypad5, XK_KP_5);
|
||||
assign(Keypad6, XK_KP_6);
|
||||
assign(Keypad7, XK_KP_7);
|
||||
assign(Keypad8, XK_KP_8);
|
||||
assign(Keypad9, XK_KP_9);
|
||||
|
||||
assign(Add, XK_KP_Add);
|
||||
assign(Subtract, XK_KP_Subtract);
|
||||
assign(Multiply, XK_KP_Multiply);
|
||||
assign(Divide, XK_KP_Divide);
|
||||
assign(Enter, XK_KP_Enter);
|
||||
|
||||
assign(Up, XK_Up);
|
||||
assign(Down, XK_Down);
|
||||
assign(Left, XK_Left);
|
||||
assign(Right, XK_Right);
|
||||
|
||||
assign(Tab, XK_Tab);
|
||||
assign(Return, XK_Return);
|
||||
assign(Spacebar, XK_space);
|
||||
|
||||
assign(LeftControl, XK_Control_L);
|
||||
assign(RightControl, XK_Control_R);
|
||||
assign(LeftAlt, XK_Alt_L);
|
||||
assign(RightAlt, XK_Alt_R);
|
||||
assign(LeftShift, XK_Shift_L);
|
||||
assign(RightShift, XK_Shift_R);
|
||||
assign(LeftSuper, XK_Super_L);
|
||||
assign(RightSuper, XK_Super_R);
|
||||
assign(Menu, XK_Menu);
|
||||
|
||||
#undef assign
|
||||
}
|
Reference in New Issue
Block a user