mirror of
https://github.com/hyprwm/hyprsunset.git
synced 2025-05-13 05:40:36 +01:00

Some checks failed
Build / nix (push) Has been cancelled
Co-authored-by: Janczar Knurek <jacek@beit.tech>
184 lines
6 KiB
C++
184 lines
6 KiB
C++
#include "IPCSocket.hpp"
|
|
#include "Hyprsunset.hpp"
|
|
|
|
#include <cerrno>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/un.h>
|
|
#include <unistd.h>
|
|
#include <pwd.h>
|
|
#include <thread>
|
|
|
|
void CIPCSocket::initialize() {
|
|
std::thread([&]() {
|
|
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (SOCKET < 0) {
|
|
Debug::log(ERR, "Couldn't start the hyprsunset Socket. (1) IPC will not work.");
|
|
return;
|
|
}
|
|
|
|
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
|
|
|
const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
|
const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR");
|
|
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
|
|
|
const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/";
|
|
|
|
std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprsunset.sock" : USERDIR + ".hyprsunset.sock";
|
|
|
|
if (!HISenv)
|
|
mkdir(USERDIR.c_str(), S_IRWXU);
|
|
|
|
unlink(socketPath.c_str());
|
|
|
|
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
|
|
|
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
|
|
|
// 10 max queued.
|
|
listen(SOCKET, 10);
|
|
|
|
sockaddr_in clientAddress = {};
|
|
socklen_t clientSize = sizeof(clientAddress);
|
|
|
|
char readBuffer[1024] = {0};
|
|
|
|
Debug::log(LOG, "hyprsunset socket started at {} (fd: {})", socketPath, SOCKET);
|
|
while (1) {
|
|
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
|
if (ACCEPTEDCONNECTION < 0) {
|
|
Debug::log(ERR, "Couldn't listen on the hyprsunset Socket. (3) IPC will not work.");
|
|
break;
|
|
} else {
|
|
do {
|
|
Debug::log(LOG, "Accepted incoming socket connection request on fd {}", ACCEPTEDCONNECTION);
|
|
std::lock_guard<std::mutex> lg(g_pHyprsunset->m_mtTickMutex);
|
|
|
|
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
|
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
|
if (messageSize == 0)
|
|
break;
|
|
std::string request(readBuffer);
|
|
|
|
m_szRequest = request;
|
|
m_bRequestReady = true;
|
|
|
|
g_pHyprsunset->tick();
|
|
while (!m_bReplyReady) { // wait for Hyprsunset to finish processing the request
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
write(ACCEPTEDCONNECTION, m_szReply.c_str(), m_szReply.length());
|
|
m_bReplyReady = false;
|
|
m_szReply = "";
|
|
|
|
} while (1);
|
|
Debug::log(LOG, "Closing Accepted Connection");
|
|
close(ACCEPTEDCONNECTION);
|
|
}
|
|
}
|
|
|
|
close(SOCKET);
|
|
}).detach();
|
|
}
|
|
|
|
bool CIPCSocket::mainThreadParseRequest() {
|
|
|
|
if (!m_bRequestReady)
|
|
return false;
|
|
|
|
std::string copy = m_szRequest;
|
|
|
|
if (copy == "")
|
|
return false;
|
|
|
|
// now we can work on the copy
|
|
|
|
Debug::log(LOG, "Received a request: {}", copy);
|
|
|
|
// set default reply
|
|
m_szReply = "ok";
|
|
m_bReplyReady = true;
|
|
m_bRequestReady = false;
|
|
|
|
// config commands
|
|
if (copy.find("gamma") == 0) {
|
|
int spaceSeparator = copy.find_first_of(' ');
|
|
if (spaceSeparator == -1) {
|
|
m_szReply = std::to_string(g_pHyprsunset->GAMMA * 100);
|
|
return false;
|
|
}
|
|
|
|
std::string args = copy.substr(spaceSeparator + 1);
|
|
float gamma = g_pHyprsunset->GAMMA * 100;
|
|
float maxGamma = g_pHyprsunset->MAX_GAMMA * 100;
|
|
if (args[0] == '+' || args[0] == '-') {
|
|
try {
|
|
if (args[0] == '-')
|
|
gamma -= std::stof(args.substr(1));
|
|
else
|
|
gamma += std::stof(args.substr(1));
|
|
} catch (std::exception& e) {
|
|
m_szReply = "Invalid gamma value (should be in range 0-" + std::to_string(maxGamma) + "%)";
|
|
return false;
|
|
}
|
|
|
|
gamma = std::clamp(gamma, 0.0f, maxGamma);
|
|
} else
|
|
gamma = std::stof(args);
|
|
|
|
if (gamma < 0 || gamma > maxGamma) {
|
|
m_szReply = "Invalid gamma value (should be in range 0-" + std::to_string(maxGamma) + "%)";
|
|
return false;
|
|
}
|
|
|
|
g_pHyprsunset->GAMMA = gamma / 100;
|
|
return true;
|
|
}
|
|
|
|
if (copy.find("temperature") == 0) {
|
|
int spaceSeparator = copy.find_first_of(' ');
|
|
if (spaceSeparator == -1) {
|
|
m_szReply = std::to_string(g_pHyprsunset->KELVIN);
|
|
return false;
|
|
}
|
|
|
|
std::string args = copy.substr(spaceSeparator + 1);
|
|
unsigned long long kelvin = g_pHyprsunset->KELVIN;
|
|
try {
|
|
if (args[0] == '+' || args[0] == '-') {
|
|
if (args[0] == '-')
|
|
kelvin -= std::stoull(args.substr(1));
|
|
else
|
|
kelvin += std::stoull(args.substr(1));
|
|
kelvin = std::clamp(kelvin, 1000ull, 20000ull);
|
|
} else
|
|
kelvin = std::stoull(args);
|
|
} catch (std::exception& e) {
|
|
m_szReply = "Invalid temperature (should be an integer in range 1000-20000)";
|
|
return false;
|
|
}
|
|
if (kelvin < 1000 || kelvin > 20000) {
|
|
m_szReply = "Invalid temperature (should be an integer in range 1000-20000)";
|
|
return false;
|
|
}
|
|
|
|
g_pHyprsunset->KELVIN = kelvin;
|
|
g_pHyprsunset->identity = false;
|
|
return true;
|
|
}
|
|
|
|
if (copy.find("identity") == 0) {
|
|
g_pHyprsunset->identity = true;
|
|
return true;
|
|
}
|
|
|
|
m_szReply = "invalid command";
|
|
return false;
|
|
}
|