From cab1352801b62d1b8a12ca1c995cb24445ce4bc9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 23:04:20 -0400 Subject: Start port of swaybar to layer shell This starts up the event loop and wayland display and shims out the basic top level rendering concepts. Also includes some changes to incorporate pango into the 1.x codebase properly. --- swaybar/tray/sni_watcher.c | 497 --------------------------------------------- 1 file changed, 497 deletions(-) delete mode 100644 swaybar/tray/sni_watcher.c (limited to 'swaybar/tray/sni_watcher.c') diff --git a/swaybar/tray/sni_watcher.c b/swaybar/tray/sni_watcher.c deleted file mode 100644 index 86453e70..00000000 --- a/swaybar/tray/sni_watcher.c +++ /dev/null @@ -1,497 +0,0 @@ -#define _XOPEN_SOURCE 500 -#include -#include -#include -#include -#include -#include -#include "swaybar/tray/dbus.h" -#include "list.h" -#include "log.h" - -static list_t *items = NULL; -static list_t *hosts = NULL; - -/** - * Describes the function of the StatusNotifierWatcher - * See https://freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierWatcher/ - * - * We also implement KDE's special snowflake protocol, it's like this but with - * all occurrences 'freedesktop' replaced with 'kde'. There is no KDE introspect. - */ -static const char *interface_xml = - "" - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; - -static void host_registered_signal(DBusConnection *connection) { - // Send one signal for each protocol - DBusMessage *signal = dbus_message_new_signal( - "/StatusNotifierWatcher", - "org.freedesktop.StatusNotifierWatcher", - "StatusNotifierHostRegistered"); - - dbus_connection_send(connection, signal, NULL); - dbus_message_unref(signal); - - - signal = dbus_message_new_signal( - "/StatusNotifierWatcher", - "org.kde.StatusNotifierWatcher", - "StatusNotifierHostRegistered"); - - dbus_connection_send(connection, signal, NULL); - dbus_message_unref(signal); -} -static void item_registered_signal(DBusConnection *connection, const char *name) { - DBusMessage *signal = dbus_message_new_signal( - "/StatusNotifierWatcher", - "org.freedesktop.StatusNotifierWatcher", - "StatusNotifierItemRegistered"); - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - dbus_connection_send(connection, signal, NULL); - dbus_message_unref(signal); - - signal = dbus_message_new_signal( - "/StatusNotifierWatcher", - "org.kde.StatusNotifierWatcher", - "StatusNotifierItemRegistered"); - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - dbus_connection_send(connection, signal, NULL); - dbus_message_unref(signal); -} -static void item_unregistered_signal(DBusConnection *connection, const char *name) { - DBusMessage *signal = dbus_message_new_signal( - "/StatusNotifierWatcher", - "org.freedesktop.StatusNotifierWatcher", - "StatusNotifierItemUnregistered"); - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - dbus_connection_send(connection, signal, NULL); - dbus_message_unref(signal); - - signal = dbus_message_new_signal( - "/StatusNotifierWatcher", - "org.kde.StatusNotifierWatcher", - "StatusNotifierItemUnregistered"); - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - dbus_connection_send(connection, signal, NULL); - dbus_message_unref(signal); -} - -static void respond_to_introspect(DBusConnection *connection, DBusMessage *request) { - DBusMessage *reply; - - reply = dbus_message_new_method_return(request); - dbus_message_append_args(reply, - DBUS_TYPE_STRING, &interface_xml, - DBUS_TYPE_INVALID); - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); -} - -static void register_item(DBusConnection *connection, DBusMessage *message) { - DBusError error; - char *name; - - dbus_error_init(&error); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) { - sway_log(L_ERROR, "Error parsing method args: %s\n", error.message); - } - - sway_log(L_INFO, "RegisterStatusNotifierItem called with \"%s\"\n", name); - - // Don't add duplicate or not real item - if (!dbus_validate_bus_name(name, NULL)) { - sway_log(L_INFO, "This item is not valid, we cannot keep track of it."); - return; - } - - if (list_seq_find(items, (int (*)(const void *, const void *))strcmp, name) != -1) { - return; - } - if (!dbus_bus_name_has_owner(connection, name, &error)) { - return; - } - - list_add(items, strdup(name)); - item_registered_signal(connection, name); - - // It's silly, but xembedsniproxy wants a reply for this function - DBusMessage *reply = dbus_message_new_method_return(message); - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); -} - -static void register_host(DBusConnection *connection, DBusMessage *message) { - DBusError error; - char *name; - - dbus_error_init(&error); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) { - sway_log(L_ERROR, "Error parsing method args: %s\n", error.message); - } - - sway_log(L_INFO, "RegisterStatusNotifierHost called with \"%s\"\n", name); - - // Don't add duplicate or not real host - if (!dbus_validate_bus_name(name, NULL)) { - sway_log(L_INFO, "This item is not valid, we cannot keep track of it."); - return; - } - - - if (list_seq_find(hosts, (int (*)(const void *, const void *))strcmp, name) != -1) { - return; - } - if (!dbus_bus_name_has_owner(connection, name, &error)) { - return; - } - - list_add(hosts, strdup(name)); - host_registered_signal(connection); -} - -static void get_property(DBusConnection *connection, DBusMessage *message) { - DBusError error; - char *interface; - char *property; - - dbus_error_init(&error); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &interface, - DBUS_TYPE_STRING, &property, - DBUS_TYPE_INVALID)) { - sway_log(L_ERROR, "Error parsing prop args: %s\n", error.message); - return; - } - - if (strcmp(property, "RegisteredStatusNotifierItems") == 0) { - sway_log(L_INFO, "Replying with items\n"); - DBusMessage *reply; - reply = dbus_message_new_method_return(message); - DBusMessageIter iter; - DBusMessageIter sub; - DBusMessageIter subsub; - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - "as", &sub); - dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, - "s", &subsub); - - for (int i = 0; i < items->length; ++i) { - dbus_message_iter_append_basic(&subsub, - DBUS_TYPE_STRING, &items->items[i]); - } - - dbus_message_iter_close_container(&sub, &subsub); - dbus_message_iter_close_container(&iter, &sub); - - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); - } else if (strcmp(property, "IsStatusNotifierHostRegistered") == 0) { - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter sub; - int registered = (hosts == NULL || hosts->length == 0) ? 0 : 1; - - reply = dbus_message_new_method_return(message); - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - "b", &sub); - dbus_message_iter_append_basic(&sub, - DBUS_TYPE_BOOLEAN, ®istered); - - dbus_message_iter_close_container(&iter, &sub); - - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); - } else if (strcmp(property, "ProtocolVersion") == 0) { - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter sub; - const int version = 0; - - reply = dbus_message_new_method_return(message); - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - "i", &sub); - dbus_message_iter_append_basic(&sub, - DBUS_TYPE_INT32, &version); - - dbus_message_iter_close_container(&iter, &sub); - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); - } -} - -static void set_property(DBusConnection *connection, DBusMessage *message) { - // All properties are read only and we don't allow new properties - return; -} - -static void get_all(DBusConnection *connection, DBusMessage *message) { - DBusMessage *reply; - reply = dbus_message_new_method_return(message); - DBusMessageIter iter; /* a{v} */ - DBusMessageIter arr; - DBusMessageIter dict; - DBusMessageIter sub; - DBusMessageIter subsub; - int registered = (hosts == NULL || hosts->length == 0) ? 0 : 1; - const int version = 0; - const char *prop; - - // Could clean this up with a function for each prop - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - "{sv}", &arr); - - prop = "RegisteredStatusNotifierItems"; - dbus_message_iter_open_container(&arr, DBUS_TYPE_DICT_ENTRY, - NULL, &dict); - dbus_message_iter_append_basic(&dict, - DBUS_TYPE_STRING, &prop); - dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, - "as", &sub); - dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, - "s", &subsub); - for (int i = 0; i < items->length; ++i) { - dbus_message_iter_append_basic(&subsub, - DBUS_TYPE_STRING, &items->items[i]); - } - dbus_message_iter_close_container(&sub, &subsub); - dbus_message_iter_close_container(&dict, &sub); - dbus_message_iter_close_container(&arr, &dict); - - prop = "IsStatusNotifierHostRegistered"; - dbus_message_iter_open_container(&arr, DBUS_TYPE_DICT_ENTRY, - NULL, &dict); - dbus_message_iter_append_basic(&dict, - DBUS_TYPE_STRING, &prop); - dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, - "b", &sub); - dbus_message_iter_append_basic(&sub, - DBUS_TYPE_BOOLEAN, ®istered); - dbus_message_iter_close_container(&dict, &sub); - dbus_message_iter_close_container(&arr, &dict); - - prop = "ProtocolVersion"; - dbus_message_iter_open_container(&arr, DBUS_TYPE_DICT_ENTRY, - NULL, &dict); - dbus_message_iter_append_basic(&dict, - DBUS_TYPE_STRING, &prop); - dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, - "i", &sub); - dbus_message_iter_append_basic(&sub, - DBUS_TYPE_INT32, &version); - dbus_message_iter_close_container(&dict, &sub); - dbus_message_iter_close_container(&arr, &dict); - - dbus_message_iter_close_container(&iter, &arr); - - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); -} - -static DBusHandlerResult message_handler(DBusConnection *connection, - DBusMessage *message, void *data) { - const char *interface_name = dbus_message_get_interface(message); - const char *member_name = dbus_message_get_member(message); - - // In order of the xml above - if (strcmp(interface_name, "org.freedesktop.DBus.Introspectable") == 0 && - strcmp(member_name, "Introspect") == 0) { - // We don't have an introspect for KDE - respond_to_introspect(connection, message); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (strcmp(interface_name, "org.freedesktop.DBus.Properties") == 0) { - if (strcmp(member_name, "Get") == 0) { - get_property(connection, message); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (strcmp(member_name, "Set") == 0) { - set_property(connection, message); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (strcmp(member_name, "GetAll") == 0) { - get_all(connection, message); - return DBUS_HANDLER_RESULT_HANDLED; - } else { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - } else if (strcmp(interface_name, "org.freedesktop.StatusNotifierWatcher") == 0 || - strcmp(interface_name, "org.kde.StatusNotifierWatcher") == 0) { - if (strcmp(member_name, "RegisterStatusNotifierItem") == 0) { - register_item(connection, message); - return DBUS_HANDLER_RESULT_HANDLED; - } else if (strcmp(member_name, "RegisterStatusNotifierHost") == 0) { - register_host(connection, message); - return DBUS_HANDLER_RESULT_HANDLED; - } else { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult signal_handler(DBusConnection *connection, - DBusMessage *message, void *_data) { - if (dbus_message_is_signal(message, "org.freedesktop.DBus", "NameOwnerChanged")) { - // Only eat the message if it is name that we are watching - const char *name; - const char *old_owner; - const char *new_owner; - int index; - if (!dbus_message_get_args(message, NULL, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &old_owner, - DBUS_TYPE_STRING, &new_owner, - DBUS_TYPE_INVALID)) { - sway_log(L_ERROR, "Error getting LostName args"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - if (strcmp(new_owner, "") != 0) { - // Name is not lost - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - if ((index = list_seq_find(items, (int (*)(const void *, const void *))strcmp, name)) != -1) { - sway_log(L_INFO, "Status Notifier Item lost %s", name); - free(items->items[index]); - list_del(items, index); - item_unregistered_signal(connection, name); - - return DBUS_HANDLER_RESULT_HANDLED; - } - if ((index = list_seq_find(hosts, (int (*)(const void *, const void *))strcmp, name)) != -1) { - sway_log(L_INFO, "Status Notifier Host lost %s", name); - free(hosts->items[index]); - list_del(hosts, index); - - return DBUS_HANDLER_RESULT_HANDLED; - } - } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static const DBusObjectPathVTable vtable = { - .message_function = message_handler, - .unregister_function = NULL, -}; - -int init_sni_watcher() { - DBusError error; - dbus_error_init(&error); - if (!conn) { - sway_log(L_ERROR, "Connection is null, cannot initiate StatusNotifierWatcher"); - return -1; - } - - items = create_list(); - hosts = create_list(); - - int status = dbus_bus_request_name(conn, "org.freedesktop.StatusNotifierWatcher", - DBUS_NAME_FLAG_REPLACE_EXISTING, - &error); - if (status == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - sway_log(L_DEBUG, "Got watcher name"); - } else if (status == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { - sway_log(L_INFO, "Could not get watcher name, it may start later"); - } - if (dbus_error_is_set(&error)) { - sway_log(L_ERROR, "dbus err getting watcher name: %s\n", error.message); - return -1; - } - - status = dbus_bus_request_name(conn, "org.kde.StatusNotifierWatcher", - DBUS_NAME_FLAG_REPLACE_EXISTING, - &error); - if (status == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - sway_log(L_DEBUG, "Got kde watcher name"); - } else if (status == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { - sway_log(L_INFO, "Could not get kde watcher name, it may start later"); - } - if (dbus_error_is_set(&error)) { - sway_log(L_ERROR, "dbus err getting kde watcher name: %s\n", error.message); - return -1; - } - - dbus_connection_try_register_object_path(conn, - "/StatusNotifierWatcher", - &vtable, NULL, &error); - if (dbus_error_is_set(&error)) { - sway_log(L_ERROR, "dbus_err: %s\n", error.message); - return -1; - } - - dbus_bus_add_match(conn, - "type='signal',\ - sender='org.freedesktop.DBus',\ - interface='org.freedesktop.DBus',\ - member='NameOwnerChanged'", - &error); - - if (dbus_error_is_set(&error)) { - sway_log(L_ERROR, "DBus error getting match args: %s", error.message); - } - - dbus_connection_add_filter(conn, signal_handler, NULL, NULL); - return 0; -} -- cgit v1.2.3-54-g00ecf