From 310b6542fcef2766fbff1aacae31f890fbc1cd71 Mon Sep 17 00:00:00 2001 From: oneechanhax Date: Sat, 23 Jun 2018 07:45:55 -0500 Subject: [PATCH] Input system! --- CMakeLists.txt | 2 +- README.MD | 3 + example-src/example.cpp | 10 ++- example-src/input.cpp | 139 +++++++++++++++++++++++++++++++ example-src/input.hpp | 9 ++ gui-mate/nekohook/functional.hpp | 55 ++++++++++++ gui-mate/nekohook/input.cpp | 12 +++ gui-mate/nekohook/input.hpp | 73 ++++++++++++++++ 8 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 example-src/input.cpp create mode 100644 gui-mate/nekohook/functional.hpp create mode 100644 gui-mate/nekohook/input.cpp create mode 100644 gui-mate/nekohook/input.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fa5c97d..96db4b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ if(PNG_FOUND AND GLEW_FOUND AND OPENGL_FOUND AND X11_FOUND AND FREETYPE_FOUND) target_link_libraries(example gui-mate "${CMAKE_CURRENT_SOURCE_DIR}/example-src/lib/libxoverlay.a" "${CMAKE_CURRENT_SOURCE_DIR}/example-src/lib/libglez.a" - ${PNG_LIBRARIES} ${GLEW_LIBRARIES} ${OPENGL_gl_LIBRARY} ${FREETYPE_LIBRARIES} + ${PNG_LIBRARIES} GL GLU GLEW ${FREETYPE_LIBRARIES} ${X11_X11_LIB} ${X11_Xext_LIB} ${X11_Xfixes_LIB}) endif() # Wow ez diff --git a/README.MD b/README.MD index 7ba0812..ed2a2f1 100644 --- a/README.MD +++ b/README.MD @@ -5,3 +5,6 @@ Written in C++ ## Note~ This application and api is only for making and getting a gui working and running for nekohook, sorry if you cant port it easily to your platform. Also, should this even be called an api :thinking: + +## Another Note~ +Dont yell at me for shitty code base, only stuff actually kept clean is in the gui code itself not in the stuff supporting it. diff --git a/example-src/example.cpp b/example-src/example.cpp index f3eaafb..93dce7e 100644 --- a/example-src/example.cpp +++ b/example-src/example.cpp @@ -2,17 +2,23 @@ #include "lib/xoverlay.h" #include "lib/glez.h" +#include "input.hpp" + int main() { xoverlay_init(); glez_init(xoverlay_library.width, xoverlay_library.height); xoverlay_show(); while (1) { + input::RefreshInput(); // Must be called in that order. xoverlay_draw_begin(); - glez_begin(); + glez_begin(); { + glez_rect(100, 300, 200, 100, glez_rgba(255, 0, 128, 255)); - glez_end(); + auto mouse = input::GetMouse(); + glez_rect(mouse.first - 6, mouse.second - 6, 12, 12, glez_rgba(255, 0, 128, 255)); + } glez_end(); xoverlay_draw_end(); } return 0; diff --git a/example-src/input.cpp b/example-src/input.cpp new file mode 100644 index 0000000..5028bb8 --- /dev/null +++ b/example-src/input.cpp @@ -0,0 +1,139 @@ + +#include // For xlibs keycodes, window geometry +#include // For caching pressed keys + +#include "lib/xoverlay.h" + +#include "input.hpp" + +namespace input { + +// Stores potential conversions between xlib's keycodes and cathooks catkeys. Add more as nessesary! /usr/include/X11/keysymdef.h +static const std::pair xlibToCatVar[] = { + {XK_0, CATKEY_0}, {XK_1, CATKEY_1}, {XK_2, CATKEY_2}, + {XK_3, CATKEY_3}, {XK_4, CATKEY_4}, {XK_5, CATKEY_5}, + {XK_6, CATKEY_6}, {XK_7, CATKEY_7}, {XK_8, CATKEY_8}, + {XK_9, CATKEY_9}, {XK_A, CATKEY_A}, {XK_B, CATKEY_B}, + {XK_C, CATKEY_C}, {XK_D, CATKEY_D}, {XK_E, CATKEY_E}, + {XK_F, CATKEY_F}, {XK_G, CATKEY_G}, {XK_H, CATKEY_H}, + {XK_I, CATKEY_I}, {XK_J, CATKEY_J}, {XK_K, CATKEY_K}, + {XK_L, CATKEY_L}, {XK_M, CATKEY_M}, {XK_N, CATKEY_N}, + {XK_O, CATKEY_O}, {XK_P, CATKEY_P}, {XK_Q, CATKEY_Q}, + {XK_R, CATKEY_R}, {XK_S, CATKEY_S}, {XK_T, CATKEY_T}, + {XK_U, CATKEY_U}, {XK_V, CATKEY_V}, {XK_W, CATKEY_W}, + {XK_X, CATKEY_X}, {XK_Y, CATKEY_Y}, {XK_Z, CATKEY_Z}, + + {XK_Escape, CATKEY_ESCAPE}, {XK_bracketleft, CATKEY_LBRACKET}, + {XK_bracketright, CATKEY_RBRACKET}, {XK_semicolon, CATKEY_SEMICOLON}, + {XK_apostrophe, CATKEY_APOSTROPHE}, {XK_apostrophe, CATKEY_COMMA}, + {XK_period, CATKEY_PERIOD}, {XK_slash, CATKEY_SLASH}, + {XK_backslash, CATKEY_BACKSLASH}, {XK_minus, CATKEY_MINUS}, + {XK_equal, CATKEY_EQUAL}, {XK_Return, CATKEY_ENTER}, + {XK_space, CATKEY_SPACE}, {XK_BackSpace, CATKEY_BACKSPACE}, + {XK_Tab, CATKEY_TAB}, {XK_Caps_Lock, CATKEY_CAPSLOCK}, + + {XK_Insert, CATKEY_INSERT}, {XK_Delete, CATKEY_DELETE}, + {XK_Home, CATKEY_HOME}, {XK_End, CATKEY_END}, + {XK_Page_Up, CATKEY_PAGEUP}, {XK_Page_Down, CATKEY_PAGEDOWN}, + + {XK_Shift_L, CATKEY_LSHIFT}, {XK_Shift_R, CATKEY_RSHIFT}, + {XK_Alt_L, CATKEY_LALT}, {XK_Alt_R, CATKEY_RALT}, + {XK_Control_L, CATKEY_LCONTROL}, {XK_Control_R, CATKEY_RCONTROL}, + + {XK_KP_0, CATKEY_PAD_0}, {XK_KP_1, CATKEY_PAD_1}, {XK_KP_2, CATKEY_PAD_2}, + {XK_KP_3, CATKEY_PAD_3}, {XK_KP_4, CATKEY_PAD_4}, {XK_KP_5, CATKEY_PAD_5}, + {XK_KP_6, CATKEY_PAD_6}, {XK_KP_7, CATKEY_PAD_7}, {XK_KP_8, CATKEY_PAD_8}, + {XK_KP_9, CATKEY_PAD_9}, + + {XK_KP_Divide, CATKEY_PAD_DIVIDE}, {XK_KP_Multiply, CATKEY_PAD_MULTIPLY}, + {XK_KP_Subtract, CATKEY_PAD_MINUS}, {XK_KP_Add, CATKEY_PAD_PLUS}, + {XK_KP_Enter, CATKEY_PAD_ENTER}, {XK_KP_Decimal, CATKEY_PAD_DECIMAL}, + + {XK_Up, CATKEY_UP}, {XK_Left, CATKEY_LEFT}, + {XK_Down, CATKEY_DOWN}, {XK_Right, CATKEY_RIGHT}, + + {XK_F1, CATKEY_F1}, {XK_F2, CATKEY_F2}, {XK_F3, CATKEY_F3}, + {XK_F4, CATKEY_F4}, {XK_F5, CATKEY_F5}, {XK_F6, CATKEY_F6}, + {XK_F7, CATKEY_F7}, {XK_F8, CATKEY_F8}, {XK_F9, CATKEY_F9}, + {XK_F10, CATKEY_F10}, {XK_F11, CATKEY_F11}, {XK_F12, CATKEY_F12}, + + {XK_Pointer_DfltBtnPrev, CATKEY_M_WHEEL_UP}, {XK_Pointer_DfltBtnNext, CATKEY_M_WHEEL_DOWN} +}; + +// Used to store depressed keys +static std::bitset pressed_buttons; + +// Mouse info +static std::pair mouse(-1, -1); + +// Screen height and width +static std::pair bounds(-1, -1); + +// Request this to update the input system on button, mouse, and window info +void RefreshInput() { + if (!xoverlay_library.display || !xoverlay_library.window) return; + + // Get window bounds + if (xoverlay_library.width != bounds.first || xoverlay_library.height != bounds.second) { // Activate on change + bounds = std::make_pair(xoverlay_library.width, xoverlay_library.height); + input::bounds_event.Emit(bounds); + } + + // Update mouse position + Window root_return, child_return; int root_x, root_y, mousex, mousey; unsigned int mask_return; + if (XQueryPointer(xoverlay_library.display, xoverlay_library.window, &root_return, &child_return, &root_x, &root_y, &mousex, &mousey, &mask_return)) { // only update the cursor if this returns true + if ((mousex != mouse.first || mousey != mouse.second) // Activate on change + && (mousex >= 0 && mousey >= 0 && mousex <= bounds.first && mousey <= bounds.second)) { // Clamp positions to the window + mouse = std::make_pair(mousex, mousey); + input::mouse_event.Emit(mouse); + } + // We did a pointer query so check our buttons too! + bool s = (mask_return & (Button1Mask)); + if (s != pressed_buttons[CATKEY_MOUSE_1]){ + pressed_buttons[CATKEY_MOUSE_1] = s; + input::key_event.Emit(CATKEY_MOUSE_1, s); + } + s = (mask_return & (Button2Mask)); + if (s != pressed_buttons[CATKEY_MOUSE_2]){ + pressed_buttons[CATKEY_MOUSE_2] = s; + input::key_event.Emit(CATKEY_MOUSE_2, s); + } + s = (mask_return & (Button3Mask)); + if (s != pressed_buttons[CATKEY_MOUSE_3]){ + pressed_buttons[CATKEY_MOUSE_3] = s; + input::key_event.Emit(CATKEY_MOUSE_3, s); + } + // Mouse 4-5 dont work for some reason. XLib doesnt like them... + } + + // Find depressed keys and save them to the stored map + char keys[32]; + XQueryKeymap(xoverlay_library.display, keys); + // Recurse through the map looking for depressed keys + for (const auto& current : xlibToCatVar) { + + // Get the keycode for the key we are looking for... + int current_key = XKeysymToKeycode(xoverlay_library.display, current.first); + + // Use the keymap with bitwise logic to get state, oof this took forever to make + bool pressed = (keys[current_key / 8] & (1 << (current_key % 8))); + if (pressed != pressed_buttons[current.second]){ + pressed_buttons[current.second] = pressed; + input::key_event.Emit(current.second, pressed); + } + } +} + + +bool GetKey(CatKey k) { + return pressed_buttons[k]; +} +std::pair GetMouse() { + return mouse; +} +std::pair GetBounds() { + return bounds; +} + + +} diff --git a/example-src/input.hpp b/example-src/input.hpp index e69de29..966844d 100644 --- a/example-src/input.hpp +++ b/example-src/input.hpp @@ -0,0 +1,9 @@ + +#include "../gui-mate/nekohook/input.hpp" + +namespace input { + +// Call to refresh states +void RefreshInput(); + +} diff --git a/gui-mate/nekohook/functional.hpp b/gui-mate/nekohook/functional.hpp new file mode 100644 index 0000000..6508c2d --- /dev/null +++ b/gui-mate/nekohook/functional.hpp @@ -0,0 +1,55 @@ + +#pragma once + +// an extended std lib + +#include +#include + +namespace cat { + +// To handle calling of events +template +class Event { +public: + using FuncPtr = void(*)(args...); +private: + std::vector func_pool; + bool in_event = false; + auto find(FuncPtr in) { + return std::find(this->func_pool.begin(), this->func_pool.end(), in); + } +public: + inline bool GetInEvent(){ return in_event; } + inline void Emit(args... a) { + in_event = true; + for (const auto& func : this->func_pool) + func(a...); + in_event = false; + } + void Listen(FuncPtr in) { + auto find = this->find(in); + if (find != this->func_pool.end()) + throw "Listener already exists"; + this->func_pool.push_back(in); + } + void Remove(FuncPtr in) { + auto find = this->find(in); + if (find != this->func_pool.end()) + this->func_pool.erase(find); + else + throw "Listener doesnt exist"; + } +}; + +// Managed listener, adds on construct and removes on destruct +/*template +class Listener { + Listener(Event::FuncPtr _callback) : callback(_callback) { + Event.Listen(_callback); + } + ~Listener() { Event.Remove(callback); } + const Event::FuncPtr callback; +};*/ + +} diff --git a/gui-mate/nekohook/input.cpp b/gui-mate/nekohook/input.cpp new file mode 100644 index 0000000..ad8152f --- /dev/null +++ b/gui-mate/nekohook/input.cpp @@ -0,0 +1,12 @@ + +#include "functional.hpp" + +#include "input.hpp" + +namespace input { + +cat::Event> bounds_event; +cat::Event> mouse_event; +cat::Event key_event; + +} diff --git a/gui-mate/nekohook/input.hpp b/gui-mate/nekohook/input.hpp new file mode 100644 index 0000000..093d519 --- /dev/null +++ b/gui-mate/nekohook/input.hpp @@ -0,0 +1,73 @@ + +enum CatKey { + CATKEY_NONE, + CATKEY_0, CATKEY_1, CATKEY_2, + CATKEY_3, CATKEY_4, CATKEY_5, + CATKEY_6, CATKEY_7, CATKEY_8, + CATKEY_9, CATKEY_A, CATKEY_B, + CATKEY_C, CATKEY_D, CATKEY_E, + CATKEY_F, CATKEY_G, CATKEY_H, + CATKEY_I, CATKEY_J, CATKEY_K, + CATKEY_L, CATKEY_M, CATKEY_N, + CATKEY_O, CATKEY_P, CATKEY_Q, + CATKEY_R, CATKEY_S, CATKEY_T, + CATKEY_U, CATKEY_V, CATKEY_W, + CATKEY_X, CATKEY_Y, CATKEY_Z, + + CATKEY_ESCAPE, CATKEY_LBRACKET, + CATKEY_RBRACKET, CATKEY_SEMICOLON, + CATKEY_APOSTROPHE, CATKEY_BACKQUOTE, + CATKEY_COMMA, CATKEY_PERIOD, CATKEY_SLASH, + CATKEY_BACKSLASH, CATKEY_MINUS, CATKEY_EQUAL, + CATKEY_ENTER, CATKEY_SPACE, CATKEY_BACKSPACE, + CATKEY_TAB, CATKEY_CAPSLOCK, + + CATKEY_INSERT, CATKEY_DELETE, + CATKEY_HOME, CATKEY_END, + CATKEY_PAGEUP, CATKEY_PAGEDOWN, + + CATKEY_LSHIFT, CATKEY_RSHIFT, + CATKEY_LALT, CATKEY_RALT, + CATKEY_LCONTROL, CATKEY_RCONTROL, + + CATKEY_PAD_0, CATKEY_PAD_1, CATKEY_PAD_2, + CATKEY_PAD_3, CATKEY_PAD_4, CATKEY_PAD_5, + CATKEY_PAD_6, CATKEY_PAD_7, CATKEY_PAD_8, + CATKEY_PAD_9, + + CATKEY_PAD_DIVIDE, CATKEY_PAD_MULTIPLY, + CATKEY_PAD_MINUS, CATKEY_PAD_PLUS, + CATKEY_PAD_ENTER, CATKEY_PAD_DECIMAL, + + CATKEY_UP, CATKEY_LEFT, + CATKEY_DOWN, CATKEY_RIGHT, + + CATKEY_F1, CATKEY_F2, CATKEY_F3, + CATKEY_F4, CATKEY_F5, CATKEY_F6, + CATKEY_F7, CATKEY_F8, CATKEY_F9, + CATKEY_F10, CATKEY_F11, CATKEY_F12, + + CATKEY_MOUSE_1, CATKEY_MOUSE_2, + CATKEY_MOUSE_3, CATKEY_MOUSE_4, + CATKEY_MOUSE_5, + CATKEY_M_WHEEL_UP, CATKEY_M_WHEEL_DOWN, + CATKEY_COUNT +}; + +#include + +#include "functional.hpp" + +namespace input { + +// Forward defines, meant to be defined by you +bool GetKey(CatKey k); +std::pair GetMouse(); +std::pair GetBounds(); + +// These are already defined, just use them like normal +extern cat::Event> bounds_event; +extern cat::Event> mouse_event; +extern cat::Event key_event; + +}