mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 08:25:32 +00:00
162 lines
4.4 KiB
C++
162 lines
4.4 KiB
C++
#include "config.h"
|
|
#include <cassert>
|
|
#if DBUS_IMPLEMENTATION == SYSTEMD
|
|
#include <systemd/sd-bus.h>
|
|
#else
|
|
#include <basu/sd-bus.h>
|
|
#endif
|
|
#include <km_linux_common.h>
|
|
#include "KeymanSystemServiceClient.h"
|
|
|
|
|
|
extern gboolean testing;
|
|
|
|
class KeymanSystemServiceClient {
|
|
private:
|
|
sd_bus_message *msg = NULL;
|
|
sd_bus *bus = NULL;
|
|
bool initialized = false;
|
|
|
|
public:
|
|
KeymanSystemServiceClient();
|
|
~KeymanSystemServiceClient();
|
|
|
|
void Init();
|
|
bool IsInitialized() { return initialized; }
|
|
|
|
void SetCapsLockIndicator(guint32 capsLock);
|
|
gint32 GetCapsLockIndicator();
|
|
void CallOrderedOutputSentinel();
|
|
void Ping();
|
|
};
|
|
|
|
static KeymanSystemServiceClient _KeymanSystemServiceClient;
|
|
|
|
KeymanSystemServiceClient::KeymanSystemServiceClient() {
|
|
}
|
|
|
|
KeymanSystemServiceClient::~KeymanSystemServiceClient() {
|
|
if (msg) { sd_bus_message_unref(msg); }
|
|
if (bus) { sd_bus_unref(bus); }
|
|
}
|
|
|
|
void KeymanSystemServiceClient::Init() {
|
|
int result;
|
|
if (testing) {
|
|
result = sd_bus_default_user(&bus);
|
|
} else {
|
|
result = sd_bus_default_system(&bus);
|
|
}
|
|
if (result < 0) {
|
|
g_error("%s: Can't get connection: %s", __FUNCTION__, strerror(-result));
|
|
}
|
|
initialized = true;
|
|
}
|
|
|
|
void KeymanSystemServiceClient::SetCapsLockIndicator(guint32 capsLock) {
|
|
if (!bus) {
|
|
// we already reported the error in the c'tor, so just return
|
|
return;
|
|
}
|
|
|
|
sd_bus_error *error = NULL;
|
|
int result = sd_bus_call_method(bus, KEYMAN_BUS_NAME, KEYMAN_OBJECT_PATH,
|
|
KEYMAN_INTERFACE_NAME, "SetCapsLockIndicator", error, &msg, "b", capsLock != 0);
|
|
if (result < 0) {
|
|
g_error("%s: Failed to call method SetCapsLockIndicator: %s. %s. %s.",
|
|
__FUNCTION__, strerror(-result), error ? error->name : "-", error ? error->message : "-");
|
|
sd_bus_error_free(error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
gint32 KeymanSystemServiceClient::GetCapsLockIndicator() {
|
|
if (!bus) {
|
|
// we already reported the error in the c'tor, so just return
|
|
return -1;
|
|
}
|
|
|
|
sd_bus_error *error = NULL;
|
|
int result = sd_bus_call_method(bus, KEYMAN_BUS_NAME, KEYMAN_OBJECT_PATH,
|
|
KEYMAN_INTERFACE_NAME, "GetCapsLockIndicator", error, &msg, "");
|
|
if (result < 0) {
|
|
g_error("%s: Failed to call method GetCapsLockIndicator: %s. %s. %s.",
|
|
__FUNCTION__, strerror(-result), error ? error->name : "-", error ? error->message : "-");
|
|
sd_bus_error_free(error);
|
|
return -1;
|
|
}
|
|
|
|
guint32 capsLock = 0;
|
|
result = sd_bus_message_read(msg, "b", &capsLock);
|
|
if (result < 0) {
|
|
g_error("%s: Failed to parse response message: %s",
|
|
__FUNCTION__, strerror(-result));
|
|
return -1;
|
|
}
|
|
|
|
return capsLock;
|
|
}
|
|
|
|
void
|
|
KeymanSystemServiceClient::CallOrderedOutputSentinel() {
|
|
if (!bus) {
|
|
// we already reported the error in the c'tor, so just return
|
|
return;
|
|
}
|
|
|
|
sd_bus_error *error = NULL;
|
|
int result = sd_bus_call_method(bus, KEYMAN_BUS_NAME, KEYMAN_OBJECT_PATH,
|
|
KEYMAN_INTERFACE_NAME, "CallOrderedOutputSentinel", error, &msg, "");
|
|
if (result < 0) {
|
|
g_error("%s: Failed to call method CallOrderedOutputSentinel: %s. %s. %s.",
|
|
__FUNCTION__, strerror(-result), error ? error->name : "-", error ? error->message : "-");
|
|
sd_bus_error_free(error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void KeymanSystemServiceClient::Ping() {
|
|
if (!bus) {
|
|
// we already reported the error in the c'tor, so just return
|
|
return;
|
|
}
|
|
|
|
sd_bus_error *error = NULL;
|
|
int result = sd_bus_call_method(bus, KEYMAN_BUS_NAME, KEYMAN_OBJECT_PATH,
|
|
KEYMAN_INTERFACE_NAME, "Ping", error, &msg, "");
|
|
if (result < 0) {
|
|
g_error("%s: Failed to call method Ping: %s. %s. %s.",
|
|
__FUNCTION__, strerror(-result), error ? error->name : "-", error ? error->message : "-");
|
|
sd_bus_error_free(error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void initialize_keyman_system_service_client() {
|
|
if (!_KeymanSystemServiceClient.IsInitialized()) {
|
|
_KeymanSystemServiceClient.Init();
|
|
}
|
|
}
|
|
|
|
void
|
|
set_capslock_indicator(guint32 capsLock) {
|
|
assert(_KeymanSystemServiceClient.IsInitialized());
|
|
_KeymanSystemServiceClient.SetCapsLockIndicator(capsLock);
|
|
}
|
|
|
|
gint32 get_capslock_indicator() {
|
|
assert(_KeymanSystemServiceClient.IsInitialized());
|
|
return _KeymanSystemServiceClient.GetCapsLockIndicator();
|
|
}
|
|
|
|
void
|
|
call_ordered_output_sentinel() {
|
|
assert(_KeymanSystemServiceClient.IsInitialized());
|
|
_KeymanSystemServiceClient.CallOrderedOutputSentinel();
|
|
}
|
|
|
|
void
|
|
ping_keyman_system_service() {
|
|
assert(_KeymanSystemServiceClient.IsInitialized());
|
|
_KeymanSystemServiceClient.Ping();
|
|
}
|