Input system!

This commit is contained in:
oneechanhax 2018-06-23 07:45:55 -05:00
parent d29c4c1e8a
commit 310b6542fc
8 changed files with 300 additions and 3 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;

139
example-src/input.cpp Normal file
View File

@ -0,0 +1,139 @@
#include <X11/Xutil.h> // For xlibs keycodes, window geometry
#include <bitset> // 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<int, CatKey> 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<CATKEY_COUNT> pressed_buttons;
// Mouse info
static std::pair<int, int> mouse(-1, -1);
// Screen height and width
static std::pair<int, int> 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<int, int> GetMouse() {
return mouse;
}
std::pair<int, int> GetBounds() {
return bounds;
}
}

View File

@ -0,0 +1,9 @@
#include "../gui-mate/nekohook/input.hpp"
namespace input {
// Call to refresh states
void RefreshInput();
}

View File

@ -0,0 +1,55 @@
#pragma once
// an extended std lib
#include <vector>
#include <algorithm>
namespace cat {
// To handle calling of events
template<typename... args>
class Event {
public:
using FuncPtr = void(*)(args...);
private:
std::vector<FuncPtr> 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 Event>
class Listener {
Listener(Event::FuncPtr _callback) : callback(_callback) {
Event.Listen(_callback);
}
~Listener() { Event.Remove(callback); }
const Event::FuncPtr callback;
};*/
}

View File

@ -0,0 +1,12 @@
#include "functional.hpp"
#include "input.hpp"
namespace input {
cat::Event<std::pair<int, int>> bounds_event;
cat::Event<std::pair<int, int>> mouse_event;
cat::Event<CatKey, bool> key_event;
}

View File

@ -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 <utility>
#include "functional.hpp"
namespace input {
// Forward defines, meant to be defined by you
bool GetKey(CatKey k);
std::pair<int, int> GetMouse();
std::pair<int, int> GetBounds();
// These are already defined, just use them like normal
extern cat::Event<std::pair<int, int>> bounds_event;
extern cat::Event<std::pair<int, int>> mouse_event;
extern cat::Event<CatKey, bool> key_event;
}