feat: Implement messaging support for Linux

This commit is contained in:
WerWolv
2025-01-27 19:07:22 +01:00
parent b2c8ed17d5
commit ef2373e8c0
6 changed files with 92 additions and 53 deletions

View File

@@ -27,7 +27,27 @@ namespace hex::messaging {
}
});
EventNativeMessageReceived::subscribe([](const std::string &eventName, const std::vector<u8> &eventData) {
EventNativeMessageReceived::subscribe([](const std::vector<u8> &rawData) {
ssize_t nullIndex = -1;
auto messageData = reinterpret_cast<const char*>(rawData.data());
size_t messageSize = rawData.size();
for (size_t i = 0; i < messageSize; i++) {
if (messageData[i] == '\0') {
nullIndex = i;
break;
}
}
if (nullIndex == -1) {
log::warn("Received invalid forwarded event");
return;
}
std::string eventName(messageData, nullIndex);
std::vector<u8> eventData(messageData + nullIndex + 1, messageData + messageSize);
messageReceived(eventName, eventData);
});
}

View File

@@ -1,22 +1,79 @@
#if defined(OS_LINUX)
#include <stdexcept>
#include <fcntl.h>
#include <sys/file.h>
#include <hex/helpers/logger.hpp>
#include <hex/api/events/events_lifecycle.hpp>
#include "messaging.hpp"
namespace hex::messaging {
constexpr static auto CommunicationPipePath = "/tmp/imhex.fifo";
constexpr static auto LockPath = "/tmp/imhex.lock";
void sendToOtherInstance(const std::string &eventName, const std::vector<u8> &args) {
std::ignore = eventName;
std::ignore = args;
log::error("Unimplemented function 'sendToOtherInstance()' called");
log::debug("Sending event {} to another instance (not us)", eventName);
// Create the message
std::vector<u8> fullEventData(eventName.begin(), eventName.end());
fullEventData.push_back('\0');
fullEventData.insert(fullEventData.end(), args.begin(), args.end());
u8 *data = &fullEventData[0];
auto dataSize = fullEventData.size();
int fifo = open(CommunicationPipePath, O_WRONLY);
if (fifo < 0) return;
::write(fifo, data, dataSize);
close(fifo);
}
void setupEventListener() {
unlink(CommunicationPipePath);
if (mkfifo(CommunicationPipePath, 0600) < 0) return;
static int fifo = 0;
fifo = open(CommunicationPipePath, O_RDWR);
static auto listenerThread = std::jthread([](const std::stop_token &stopToken){
std::vector<u8> buffer(0xFFFF);
while (!stopToken.stop_requested()) {
int result = ::read(fifo, buffer.data(), buffer.size());
if (result > 0) {
EventNativeMessageReceived::post(std::vector<u8>{ buffer.begin(), buffer.begin() + result });
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
std::atexit([]{
listenerThread.request_stop();
close(fifo);
listenerThread.join();
});
}
// Not implemented, so lets say we are the main instance every time so events are forwarded to ourselves
bool setupNative() {
return true;
int fd = open(LockPath, O_RDONLY);
if (fd < 0) {
fd = open(LockPath, O_CREAT, 0600);
if (fd < 0)
return false;
}
bool mainInstance = flock(fd, LOCK_EX | LOCK_NB) == 0;
if (mainInstance)
setupEventListener();
return mainInstance;
}
}

View File

@@ -71,30 +71,10 @@ namespace hex {
// Handle opening files in existing instance
auto message = reinterpret_cast<COPYDATASTRUCT *>(lParam);
if (message == nullptr) break;
ssize_t nullIndex = -1;
auto messageData = static_cast<const char*>(message->lpData);
size_t messageSize = message->cbData;
for (size_t i = 0; i < messageSize; i++) {
if (messageData[i] == '\0') {
nullIndex = i;
break;
}
}
if (nullIndex == -1) {
log::warn("Received invalid forwarded event");
if (message == nullptr)
break;
}
std::string eventName(messageData, nullIndex);
std::vector<u8> eventData(messageData + nullIndex + 1, messageData + messageSize);
EventNativeMessageReceived::post(eventName, eventData);
EventNativeMessageReceived::post(std::vector<u8>(message->lpData, message->lpData + message->cbData));
break;
}
case WM_SETTINGCHANGE: {