summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvaxerski <43317083+vaxerski@users.noreply.github.com>2022-03-17 15:53:45 +0100
committervaxerski <43317083+vaxerski@users.noreply.github.com>2022-03-17 16:19:10 +0100
commitcf51ab71a25cbb60ebcf13edd4b7413c23264128 (patch)
tree18b649470346c8815a156b5599ee7be1c4135a79 /src
parent52090853dafb75dd99969a0cecdd291c109210f8 (diff)
input basics
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp48
-rw-r--r--src/Compositor.hpp3
-rw-r--r--src/ManagerThread.cpp22
-rw-r--r--src/ManagerThread.hpp19
-rw-r--r--src/config/ConfigManager.cpp201
-rw-r--r--src/config/ConfigManager.hpp43
-rw-r--r--src/debug/Log.cpp4
-rw-r--r--src/defines.hpp2
-rw-r--r--src/events/Events.cpp65
-rw-r--r--src/helpers/Vector2D.cpp4
-rw-r--r--src/helpers/Vector2D.hpp11
-rw-r--r--src/includes.hpp8
-rw-r--r--src/input/InputManager.cpp17
-rw-r--r--src/input/InputManager.hpp17
-rw-r--r--src/main.cpp1
15 files changed, 447 insertions, 18 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index cc6f6d41..552b58bd 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -40,16 +40,16 @@ CCompositor::CCompositor() {
m_sWLRXDGActivation - wlr_xdg_activation_v1_create(m_sWLDisplay);
m_sWLROutputLayout = wlr_output_layout_create();
- wl_signal_add(&m_sWLRXDGActivation->events.request_activate, &Events::listener_activate);
- wl_signal_add(&m_sWLROutputLayout->events.change, &Events::listener_change);
- wl_signal_add(&m_sWLRBackend->events.new_output, &Events::listener_newOutput);
+ wl_signal_add(&m_sWLRXDGActivation->events.request_activate, &Events::listen_activate);
+ wl_signal_add(&m_sWLROutputLayout->events.change, &Events::listen_change);
+ wl_signal_add(&m_sWLRBackend->events.new_output, &Events::listen_newOutput);
m_sWLRIdle = wlr_idle_create(m_sWLDisplay);
m_sWLRLayerShell = wlr_layer_shell_v1_create(m_sWLDisplay);
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay);
- wl_signal_add(&m_sWLRLayerShell->events.new_surface, &Events::listener_newLayerSurface);
- wl_signal_add(&m_sWLRXDGShell->events.new_surface, &Events::listener_newXDGSurface);
+ wl_signal_add(&m_sWLRLayerShell->events.new_surface, &Events::listen_newLayerSurface);
+ wl_signal_add(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGSurface);
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(m_sWLDisplay), WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
wlr_xdg_decoration_manager_v1_create(m_sWLDisplay);
@@ -67,22 +67,26 @@ CCompositor::CCompositor() {
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
- wl_signal_add(&m_sWLRCursor->events.motion, &Events::listener_mouseMove);
- wl_signal_add(&m_sWLRCursor->events.motion_absolute, &Events::listener_mouseMoveAbsolute);
- wl_signal_add(&m_sWLRCursor->events.button, &Events::listener_mouseButton);
- wl_signal_add(&m_sWLRCursor->events.axis, &Events::listener_mouseAxis);
- wl_signal_add(&m_sWLRCursor->events.frame, &Events::listener_mouseFrame);
- wl_signal_add(&m_sWLRBackend->events.new_input, &Events::listener_newInput);
- wl_signal_add(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listener_newKeyboard);
- wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listener_requestMouse);
- wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listener_requestSetSel);
- wl_signal_add(&m_sWLRSeat->events.request_set_primary_selection, &Events::listener_requestSetPrimarySel);
- wl_signal_add(&m_sWLROutputMgr->events.apply, &Events::listener_outputMgrApply);
- wl_signal_add(&m_sWLROutputMgr->events.test, &Events::listener_outputMgrTest);
+ wl_signal_add(&m_sWLRCursor->events.motion, &Events::listen_mouseMove);
+ wl_signal_add(&m_sWLRCursor->events.motion_absolute, &Events::listen_mouseMoveAbsolute);
+ wl_signal_add(&m_sWLRCursor->events.button, &Events::listen_mouseButton);
+ wl_signal_add(&m_sWLRCursor->events.axis, &Events::listen_mouseAxis);
+ wl_signal_add(&m_sWLRCursor->events.frame, &Events::listen_mouseFrame);
+ wl_signal_add(&m_sWLRBackend->events.new_input, &Events::listen_newInput);
+ wl_signal_add(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listen_newKeyboard);
+ wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listen_requestMouse);
+ wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listen_requestSetSel);
+ wl_signal_add(&m_sWLRSeat->events.request_set_primary_selection, &Events::listen_requestSetPrimarySel);
+ wl_signal_add(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply);
+ wl_signal_add(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest);
// TODO: XWayland
}
+CCompositor::~CCompositor() {
+
+}
+
void CCompositor::startCompositor() {
m_szWLDisplaySocket = wl_display_add_socket_auto(m_sWLDisplay);
@@ -95,6 +99,7 @@ void CCompositor::startCompositor() {
signal(SIGPIPE, SIG_IGN);
+ Debug::log(LOG, "Running on WAYLAND_DISPLAY: %s", m_szWLDisplaySocket);
if (!wlr_backend_start(m_sWLRBackend)) {
Debug::log(CRIT, "Backend did not start!");
@@ -103,6 +108,15 @@ void CCompositor::startCompositor() {
wlr_xcursor_manager_set_cursor_image(m_sWLRXCursorMgr, "left_ptr", m_sWLRCursor);
+ Debug::log(LOG, "Creating the config manager!");
+ g_pConfigManager = std::make_unique<CConfigManager>();
+
+ Debug::log(LOG, "Creating the ManagerThread!");
+ g_pManagerThread = std::make_unique<CManagerThread>();
+
+ Debug::log(LOG, "Creating the InputManager!");
+ g_pInputManager = std::make_unique<CInputManager>();
+
// This blocks until we are done.
Debug::log(LOG, "Hyprland is ready, running the event loop!");
wl_display_run(m_sWLDisplay);
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 2e724804..b2ec10a2 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -5,6 +5,9 @@
#include "defines.hpp"
#include "debug/Log.hpp"
#include "events/Events.hpp"
+#include "config/ConfigManager.hpp"
+#include "ManagerThread.hpp"
+#include "input/InputManager.hpp"
class CCompositor {
public:
diff --git a/src/ManagerThread.cpp b/src/ManagerThread.cpp
new file mode 100644
index 00000000..8ddb3b53
--- /dev/null
+++ b/src/ManagerThread.cpp
@@ -0,0 +1,22 @@
+#include "ManagerThread.hpp"
+
+CManagerThread::CManagerThread() {
+ m_tMainThread = new std::thread([=]() {
+ // Call the handle method.
+ this->handle();
+ });
+
+ m_tMainThread->detach(); // detach and continue.
+}
+
+CManagerThread::~CManagerThread() {
+ //
+}
+
+void CManagerThread::handle() {
+ while (3.1415f) {
+ g_pConfigManager->tick();
+
+ std::this_thread::sleep_for(std::chrono::microseconds(1000000 / g_pConfigManager->getInt("max_fps")));
+ }
+} \ No newline at end of file
diff --git a/src/ManagerThread.hpp b/src/ManagerThread.hpp
new file mode 100644
index 00000000..80856fe4
--- /dev/null
+++ b/src/ManagerThread.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "defines.hpp"
+#include <thread>
+#include "Compositor.hpp"
+
+class CManagerThread {
+public:
+ CManagerThread();
+ ~CManagerThread();
+
+private:
+
+ void handle();
+
+ std::thread* m_tMainThread;
+};
+
+inline std::unique_ptr<CManagerThread> g_pManagerThread; \ No newline at end of file
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
new file mode 100644
index 00000000..eccad341
--- /dev/null
+++ b/src/config/ConfigManager.cpp
@@ -0,0 +1,201 @@
+#include "ConfigManager.hpp"
+
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+CConfigManager::CConfigManager() {
+ configValues["general:max_fps"].intValue = 240;
+
+ configValues["general:border_size"].intValue = 1;
+ configValues["general:gaps_in"].intValue = 5;
+ configValues["general:gaps_out"].intValue = 20;
+
+ loadConfigLoadVars();
+
+ isFirstLaunch = false;
+}
+
+void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) {
+ if (configValues.find(COMMAND) == configValues.end()) {
+ parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
+ return;
+ }
+
+ auto& CONFIGENTRY = configValues.at(COMMAND);
+ if (CONFIGENTRY.intValue != -1) {
+ try {
+ if (VALUE.find("0x") == 0) {
+ // Values with 0x are hex
+ const auto VALUEWITHOUTHEX = VALUE.substr(2);
+ CONFIGENTRY.intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
+ } else
+ CONFIGENTRY.intValue = stol(VALUE);
+ } catch (...) {
+ Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
+ parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
+ }
+ } else if (CONFIGENTRY.floatValue != -1) {
+ try {
+ CONFIGENTRY.floatValue = stof(VALUE);
+ } catch (...) {
+ Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
+ parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
+ }
+ } else if (CONFIGENTRY.strValue != "") {
+ try {
+ CONFIGENTRY.strValue = VALUE;
+ } catch (...) {
+ Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
+ parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
+ }
+ }
+}
+
+void CConfigManager::handleRawExec(const std::string& command, const std::string& args) {
+ // Exec in the background dont wait for it.
+ if (fork() == 0) {
+ execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
+
+ _exit(0);
+ }
+}
+
+void CConfigManager::parseLine(std::string& line) {
+ // first check if its not a comment
+ const auto COMMENTSTART = line.find_first_of('#');
+ if (COMMENTSTART == 0)
+ return;
+
+ // now, cut the comment off
+ if (COMMENTSTART != std::string::npos)
+ line = line.substr(0, COMMENTSTART);
+
+ // remove shit at the beginning
+ while (line[0] == ' ' || line[0] == '\t') {
+ line = line.substr(1);
+ }
+
+ if (line.find(" {") != std::string::npos) {
+ auto cat = line.substr(0, line.find(" {"));
+ transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
+ currentCategory = cat;
+ return;
+ }
+
+ if (line.find("}") != std::string::npos && currentCategory != "") {
+ currentCategory = "";
+ return;
+ }
+
+ // And parse
+ // check if command
+ const auto EQUALSPLACE = line.find_first_of('=');
+
+ if (EQUALSPLACE == std::string::npos)
+ return;
+
+ const auto COMMAND = line.substr(0, EQUALSPLACE);
+ const auto VALUE = line.substr(EQUALSPLACE + 1);
+
+ if (COMMAND == "exec") {
+ handleRawExec(COMMAND, VALUE);
+ return;
+ } else if (COMMAND == "exec-once") {
+ if (isFirstLaunch) {
+ handleRawExec(COMMAND, VALUE);
+ return;
+ }
+ }
+
+ configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
+}
+
+void CConfigManager::loadConfigLoadVars() {
+ Debug::log(LOG, "Reloading the config!");
+ parseError = ""; // reset the error
+ currentCategory = ""; // reset the category
+
+ const char* const ENVHOME = getenv("HOME");
+ const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
+
+ std::ifstream ifs;
+ ifs.open(CONFIGPATH.c_str());
+
+ if (!ifs.good()) {
+ Debug::log(WARN, "Config reading error. (No file?)");
+ parseError = "The config could not be read. (No file?)";
+
+ ifs.close();
+ return;
+ }
+
+ std::string line = "";
+ int linenum = 1;
+ if (ifs.is_open()) {
+ while (std::getline(ifs, line)) {
+ // Read line by line.
+ try {
+ parseLine(line);
+ } catch (...) {
+ Debug::log(ERR, "Error reading line from config. Line:");
+ Debug::log(NONE, "%s", line.c_str());
+
+ parseError = "Config error at line " + std::to_string(linenum) + ": Line parsing error.";
+ }
+
+ if (parseError != "" && parseError.find("Config error at line") != 0) {
+ parseError = "Config error at line " + std::to_string(linenum) + ": " + parseError;
+ }
+
+ ++linenum;
+ }
+
+ ifs.close();
+ }
+}
+
+void CConfigManager::tick() {
+ const char* const ENVHOME = getenv("HOME");
+
+ const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprd.conf" : (std::string) "/.config/hypr/hypr.conf");
+
+ struct stat fileStat;
+ int err = stat(CONFIGPATH.c_str(), &fileStat);
+ if (err != 0) {
+ Debug::log(WARN, "Error at ticking config, error %i", errno);
+ }
+
+ // check if we need to reload cfg
+ if (fileStat.st_mtime != lastModifyTime) {
+ lastModifyTime = fileStat.st_mtime;
+
+ loadConfigLoadVars();
+ }
+}
+
+std::mutex configmtx;
+SConfigValue CConfigManager::getConfigValueSafe(std::string val) {
+ std::lock_guard<std::mutex> lg(configmtx);
+
+ SConfigValue copy = configValues[val];
+
+ return copy;
+}
+
+int CConfigManager::getInt(std::string v) {
+ return getConfigValueSafe(v).intValue;
+}
+
+float CConfigManager::getFloat(std::string v) {
+ return getConfigValueSafe(v).floatValue;
+}
+
+std::string CConfigManager::getString(std::string v) {
+ return getConfigValueSafe(v).strValue;
+}
diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp
new file mode 100644
index 00000000..5e58173a
--- /dev/null
+++ b/src/config/ConfigManager.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <map>
+#include "../debug/Log.hpp"
+#include <unordered_map>
+#include "../defines.hpp"
+#include <vector>
+
+struct SConfigValue {
+ int64_t intValue = -1;
+ float floatValue = -1;
+ std::string strValue = "";
+};
+
+class CConfigManager {
+public:
+ CConfigManager();
+
+ void tick();
+
+ int getInt(std::string);
+ float getFloat(std::string);
+ std::string getString(std::string);
+
+private:
+ std::unordered_map<std::string, SConfigValue> configValues;
+ time_t lastModifyTime = 0; // for reloading the config if changed
+
+ std::string currentCategory = ""; // For storing the category of the current item
+
+ std::string parseError = ""; // For storing a parse error to display later
+
+ bool isFirstLaunch = true; // For exec-once
+
+ // internal methods
+ void loadConfigLoadVars();
+ SConfigValue getConfigValueSafe(std::string);
+ void parseLine(std::string&);
+ void configSetValueSafe(const std::string&, const std::string&);
+ void handleRawExec(const std::string&, const std::string&);
+};
+
+inline std::unique_ptr<CConfigManager> g_pConfigManager; \ No newline at end of file
diff --git a/src/debug/Log.cpp b/src/debug/Log.cpp
index 65ba67c4..0acecb04 100644
--- a/src/debug/Log.cpp
+++ b/src/debug/Log.cpp
@@ -2,6 +2,7 @@
#include "../defines.hpp"
#include <fstream>
+#include <iostream>
void Debug::log(LogLevel level, const char* fmt, ...) {
va_list args;
@@ -37,5 +38,8 @@ void Debug::log(LogLevel level, const char* fmt, ...) {
ofs.close();
+ // log it to the stdout too.
+ std::cout << buf << "\n";
+
va_end(args);
}
diff --git a/src/defines.hpp b/src/defines.hpp
index ecf90ae8..33019666 100644
--- a/src/defines.hpp
+++ b/src/defines.hpp
@@ -8,4 +8,4 @@
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
-#define LISTENER(name) inline wl_listener listener_##name = {.notify = ##name}; \ No newline at end of file
+#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name }; \ No newline at end of file
diff --git a/src/events/Events.cpp b/src/events/Events.cpp
index 6df4c20b..a5b093f0 100644
--- a/src/events/Events.cpp
+++ b/src/events/Events.cpp
@@ -1,5 +1,70 @@
#include "Events.hpp"
+#include "../input/InputManager.hpp"
void Events::listener_activate(wl_listener* listener, void* data) {
+}
+
+void Events::listener_change(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_mouseAxis(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_mouseButton(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_mouseFrame(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_mouseMove(wl_listener* listener, void* data) {
+ g_pInputManager->onMouseMoved((wlr_event_pointer_motion*)data);
+}
+
+void Events::listener_mouseMoveAbsolute(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_newInput(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_newKeyboard(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_newOutput(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_outputMgrApply(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_outputMgrTest(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_requestMouse(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_requestSetPrimarySel(wl_listener* listener, void* data) {
+
+}
+
+void Events::listener_requestSetSel(wl_listener* listener, void* data) {
+
} \ No newline at end of file
diff --git a/src/helpers/Vector2D.cpp b/src/helpers/Vector2D.cpp
index 33b12e7c..acaace13 100644
--- a/src/helpers/Vector2D.cpp
+++ b/src/helpers/Vector2D.cpp
@@ -16,4 +16,8 @@ double Vector2D::normalize() {
y /= max;
return max;
+}
+
+Vector2D Vector2D::floor() {
+ return Vector2D((int)x, (int)y);
} \ No newline at end of file
diff --git a/src/helpers/Vector2D.hpp b/src/helpers/Vector2D.hpp
index 9bc427e8..20bc032e 100644
--- a/src/helpers/Vector2D.hpp
+++ b/src/helpers/Vector2D.hpp
@@ -26,4 +26,15 @@ class Vector2D {
Vector2D operator/(float a) {
return Vector2D(this->x / a, this->y / a);
}
+
+ bool operator==(Vector2D& a) {
+ return a.x == x && a.y == y;
+ }
+
+ bool operator!=(Vector2D& a) {
+ return a.x != x || a.y != y;
+ }
+
+
+ Vector2D floor();
}; \ No newline at end of file
diff --git a/src/includes.hpp b/src/includes.hpp
index 352286d4..a1b51b04 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -1,5 +1,11 @@
#pragma once
+// because C/C++ VS Code intellisense is stupid with includes, we will suppress them here.
+// This suppresses all "include file not found" errors.
+#ifdef __INTELLISENSE__
+#pragma diag_suppress 1696
+#endif
+
#include <X11/Xlib.h>
#include <getopt.h>
#include <libinput.h>
@@ -11,6 +17,8 @@
#include <time.h>
#include <unistd.h>
#include <wayland-server-core.h>
+#include <mutex>
+#include <thread>
#if true
diff --git a/src/input/InputManager.cpp b/src/input/InputManager.cpp
new file mode 100644
index 00000000..3140e22d
--- /dev/null
+++ b/src/input/InputManager.cpp
@@ -0,0 +1,17 @@
+#include "InputManager.hpp"
+#include "../Compositor.hpp"
+
+void CInputManager::onMouseMoved(wlr_event_pointer_motion* e) {
+ // TODO: sensitivity
+
+ float sensitivity = 0.25f;
+
+ m_vMouseCoords = m_vMouseCoords + Vector2D(e->delta_x * sensitivity, e->delta_y * sensitivity);
+
+ if (m_vMouseCoords.floor() != m_vWLRMouseCoords) {
+ Vector2D delta = m_vMouseCoords - m_vWLRMouseCoords;
+ m_vWLRMouseCoords = m_vMouseCoords.floor();
+
+ wlr_cursor_move(g_pCompositor->m_sWLRCursor, e->device, delta.floor().x, delta.floor().y);
+ }
+} \ No newline at end of file
diff --git a/src/input/InputManager.hpp b/src/input/InputManager.hpp
new file mode 100644
index 00000000..38ec419a
--- /dev/null
+++ b/src/input/InputManager.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "../defines.hpp"
+
+class CInputManager {
+public:
+
+ void onMouseMoved(wlr_event_pointer_motion*);
+ void onMouseButton(int);
+
+private:
+ Vector2D m_vMouseCoords = Vector2D(0,0);
+ Vector2D m_vWLRMouseCoords = Vector2D(0,0);
+
+};
+
+inline std::unique_ptr<CInputManager> g_pInputManager; \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index da0437e8..feaee667 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include "defines.hpp"
#include "debug/Log.hpp"
#include "Compositor.hpp"
+#include "config/ConfigManager.hpp"
int main(int argc, char** argv) {