summaryrefslogtreecommitdiff
path: root/libdecor/src/cursor-settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdecor/src/cursor-settings.c')
-rw-r--r--libdecor/src/cursor-settings.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/libdecor/src/cursor-settings.c b/libdecor/src/cursor-settings.c
new file mode 100644
index 000000000..b94623fd6
--- /dev/null
+++ b/libdecor/src/cursor-settings.c
@@ -0,0 +1,136 @@
+#include "cursor-settings.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "config.h"
+
+#ifdef HAS_DBUS
+#include <dbus/dbus.h>
+
+static DBusMessage *
+get_setting_sync(DBusConnection *const connection,
+ const char *key,
+ const char *value)
+{
+ DBusError error;
+ dbus_bool_t success;
+ DBusMessage *message;
+ DBusMessage *reply;
+
+ dbus_error_init(&error);
+
+ message = dbus_message_new_method_call(
+ "org.freedesktop.portal.Desktop",
+ "/org/freedesktop/portal/desktop",
+ "org.freedesktop.portal.Settings",
+ "Read");
+
+ success = dbus_message_append_args(message,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_STRING, &value,
+ DBUS_TYPE_INVALID);
+
+ if (!success)
+ return NULL;
+
+ reply = dbus_connection_send_with_reply_and_block(
+ connection,
+ message,
+ DBUS_TIMEOUT_USE_DEFAULT,
+ &error);
+
+ dbus_message_unref(message);
+
+ if (dbus_error_is_set(&error))
+ return NULL;
+
+ return reply;
+}
+
+static bool
+parse_type(DBusMessage *const reply,
+ const int type,
+ void *value)
+{
+ DBusMessageIter iter[3];
+
+ dbus_message_iter_init(reply, &iter[0]);
+ if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT)
+ return false;
+
+ dbus_message_iter_recurse(&iter[0], &iter[1]);
+ if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT)
+ return false;
+
+ dbus_message_iter_recurse(&iter[1], &iter[2]);
+ if (dbus_message_iter_get_arg_type(&iter[2]) != type)
+ return false;
+
+ dbus_message_iter_get_basic(&iter[2], value);
+
+ return true;
+}
+
+bool
+libdecor_get_cursor_settings(char **theme, int *size)
+{
+ static const char name[] = "org.gnome.desktop.interface";
+ static const char key_theme[] = "cursor-theme";
+ static const char key_size[] = "cursor-size";
+
+ DBusError error;
+ DBusConnection *connection;
+ DBusMessage *reply;
+ const char *value_theme = NULL;
+
+ dbus_error_init(&error);
+
+ connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
+
+ if (dbus_error_is_set(&error))
+ return false;
+
+ reply = get_setting_sync(connection, name, key_theme);
+ if (!reply)
+ return false;
+
+ if (!parse_type(reply, DBUS_TYPE_STRING, &value_theme)) {
+ dbus_message_unref(reply);
+ return false;
+ }
+
+ *theme = strdup(value_theme);
+
+ dbus_message_unref(reply);
+
+ reply = get_setting_sync(connection, name, key_size);
+ if (!reply)
+ return false;
+
+ if (!parse_type(reply, DBUS_TYPE_INT32, size)) {
+ dbus_message_unref(reply);
+ return false;
+ }
+
+ dbus_message_unref(reply);
+
+ return true;
+}
+#else
+bool
+libdecor_get_cursor_settings(char **theme, int *size)
+{
+ char *env_xtheme;
+ char *env_xsize;
+
+ env_xtheme = getenv("XCURSOR_THEME");
+ if (env_xtheme != NULL)
+ *theme = strdup(env_xtheme);
+
+ env_xsize = getenv("XCURSOR_SIZE");
+ if (env_xsize != NULL)
+ *size = atoi(env_xsize);
+
+ return env_xtheme != NULL && env_xsize != NULL;
+}
+#endif