84 lines
2.9 KiB
C++
84 lines
2.9 KiB
C++
// gKeyMapper - talk to gkeymapper-daemon over the session bus.
|
|
#ifndef GKEYMAPPER_DAEMONCLIENT_H
|
|
#define GKEYMAPPER_DAEMONCLIENT_H
|
|
|
|
#include <gio/gio.h>
|
|
|
|
#include <functional>
|
|
#include <string>
|
|
|
|
namespace gkeymapper {
|
|
|
|
// What the footer needs to know about the daemon.
|
|
struct DaemonStatus {
|
|
bool reachable = false;
|
|
bool configOk = true; // false after a ConfigReloaded(false); see fetch_status
|
|
std::string version;
|
|
std::string device;
|
|
std::string configPath;
|
|
};
|
|
|
|
// The daemon as the GUI shows it: the last status reply plus what the signals
|
|
// added since (the last G key that fired). The footer shows a one-line summary of
|
|
// it, the options window the full picture.
|
|
struct DaemonView {
|
|
bool reachable = false;
|
|
bool configOk = true;
|
|
std::string version;
|
|
std::string device;
|
|
std::string configPath;
|
|
std::string lastKey;
|
|
};
|
|
|
|
// Control-plane client for the daemon. Every call is asynchronous and its
|
|
// result arrives on the GTK main loop, so the UI never blocks on the daemon
|
|
// (a call is answered at most one daemon loop iteration late). Keypresses never
|
|
// travel through here.
|
|
class DaemonClient {
|
|
public:
|
|
using StatusFn = std::function<void(const DaemonStatus&)>;
|
|
using KeyFn = std::function<void(int index, const std::string& action)>;
|
|
|
|
DaemonClient() = default;
|
|
~DaemonClient();
|
|
|
|
DaemonClient(const DaemonClient&) = delete;
|
|
DaemonClient& operator=(const DaemonClient&) = delete;
|
|
|
|
void init(StatusFn onStatus, KeyFn onKey);
|
|
|
|
// Best effort: asks the daemon to re-read the mappings file. Its file watch
|
|
// would pick the save up by itself, this only makes it immediate.
|
|
void reload();
|
|
|
|
private:
|
|
static void on_bus_ready(GObject* source, GAsyncResult* result, gpointer userData);
|
|
static void on_daemon_signal(GDBusConnection* connection, const gchar* sender,
|
|
const gchar* objectPath, const gchar* interfaceName,
|
|
const gchar* signalName, GVariant* parameters,
|
|
gpointer userData);
|
|
static void on_name_owner_changed(GDBusConnection* connection, const gchar* sender,
|
|
const gchar* objectPath, const gchar* interfaceName,
|
|
const gchar* signalName, GVariant* parameters,
|
|
gpointer userData);
|
|
static void on_status_reply(GObject* source, GAsyncResult* result, gpointer userData);
|
|
static void on_reload_reply(GObject* source, GAsyncResult* result, gpointer userData);
|
|
|
|
void watch_signals();
|
|
void fetch_status();
|
|
void report_unreachable();
|
|
void publish(const DaemonStatus& status);
|
|
|
|
GDBusConnection* connection_ = nullptr;
|
|
guint signal_subscription_ = 0;
|
|
guint name_subscription_ = 0;
|
|
bool started_ = false;
|
|
bool configOk_ = true;
|
|
StatusFn onStatus_;
|
|
KeyFn onKey_;
|
|
};
|
|
|
|
} // namespace gkeymapper
|
|
|
|
#endif // GKEYMAPPER_DAEMONCLIENT_H
|