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.
This commit is contained in:
Drew DeVault 2018-03-28 23:04:20 -04:00
parent 382e8af418
commit cab1352801
23 changed files with 345 additions and 3787 deletions

View file

@ -1,197 +0,0 @@
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <poll.h>
#include <signal.h>
#include <time.h>
#include <dbus/dbus.h>
#include "swaybar/tray/dbus.h"
#include "swaybar/event_loop.h"
#include "log.h"
DBusConnection *conn = NULL;
static void dispatch_watch(int fd, short mask, void *data) {
sway_log(L_DEBUG, "Dispatching watch");
DBusWatch *watch = data;
if (!dbus_watch_get_enabled(watch)) {
return;
}
uint32_t flags = 0;
if (mask & POLLIN) {
flags |= DBUS_WATCH_READABLE;
} if (mask & POLLOUT) {
flags |= DBUS_WATCH_WRITABLE;
} if (mask & POLLHUP) {
flags |= DBUS_WATCH_HANGUP;
} if (mask & POLLERR) {
flags |= DBUS_WATCH_ERROR;
}
dbus_watch_handle(watch, flags);
}
static dbus_bool_t add_watch(DBusWatch *watch, void *_data) {
if (!dbus_watch_get_enabled(watch)) {
// Watch should not be polled
return TRUE;
}
short mask = 0;
uint32_t flags = dbus_watch_get_flags(watch);
if (flags & DBUS_WATCH_READABLE) {
mask |= POLLIN;
} if (flags & DBUS_WATCH_WRITABLE) {
mask |= POLLOUT;
}
int fd = dbus_watch_get_unix_fd(watch);
sway_log(L_DEBUG, "Adding DBus watch fd: %d", fd);
add_event(fd, mask, dispatch_watch, watch);
return TRUE;
}
static void remove_watch(DBusWatch *watch, void *_data) {
int fd = dbus_watch_get_unix_fd(watch);
remove_event(fd);
}
static void dispatch_timeout(timer_t timer, void *data) {
sway_log(L_DEBUG, "Dispatching DBus timeout");
DBusTimeout *timeout = data;
if (dbus_timeout_get_enabled(timeout)) {
dbus_timeout_handle(timeout);
}
}
static dbus_bool_t add_timeout(DBusTimeout *timeout, void *_data) {
if (!dbus_timeout_get_enabled(timeout)) {
return TRUE;
}
timer_t *timer = malloc(sizeof(timer_t));
if (!timer) {
sway_log(L_ERROR, "Cannot allocate memory");
return FALSE;
}
struct sigevent ev = {
.sigev_notify = SIGEV_NONE,
};
if (timer_create(CLOCK_MONOTONIC, &ev, timer)) {
sway_log(L_ERROR, "Could not create DBus timer");
return FALSE;
}
int interval = dbus_timeout_get_interval(timeout);
int interval_sec = interval / 1000;
int interval_msec = (interval_sec * 1000) - interval;
struct timespec period = {
(time_t) interval_sec,
((long) interval_msec) * 1000 * 1000,
};
struct itimerspec time = {
period,
period,
};
timer_settime(*timer, 0, &time, NULL);
dbus_timeout_set_data(timeout, timer, NULL);
sway_log(L_DEBUG, "Adding DBus timeout. Interval: %ds %dms", interval_sec, interval_msec);
add_timer(*timer, dispatch_timeout, timeout);
return TRUE;
}
static void remove_timeout(DBusTimeout *timeout, void *_data) {
timer_t *timer = (timer_t *) dbus_timeout_get_data(timeout);
sway_log(L_DEBUG, "Removing DBus timeout.");
if (timer) {
remove_timer(*timer);
timer_delete(*timer);
free(timer);
}
}
static bool should_dispatch = true;
static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_status,
void *_data) {
if (new_status == DBUS_DISPATCH_DATA_REMAINS) {
should_dispatch = true;
}
}
/* Public functions below */
void dispatch_dbus() {
if (!should_dispatch || !conn) {
return;
}
DBusDispatchStatus status;
do {
status = dbus_connection_dispatch(conn);
} while (status == DBUS_DISPATCH_DATA_REMAINS);
if (status != DBUS_DISPATCH_COMPLETE) {
sway_log(L_ERROR, "Cannot dispatch dbus events: %d", status);
}
should_dispatch = false;
}
int dbus_init() {
DBusError error;
dbus_error_init(&error);
conn = dbus_bus_get(DBUS_BUS_SESSION, &error);
if (conn == NULL) {
sway_log(L_INFO, "Compiled with dbus support, but unable to connect to dbus");
sway_log(L_INFO, "swaybar will be unable to display tray icons.");
return -1;
}
dbus_connection_set_exit_on_disconnect(conn, FALSE);
if (dbus_error_is_set(&error)) {
sway_log(L_ERROR, "Cannot get bus connection: %s\n", error.message);
conn = NULL;
return -1;
}
sway_log(L_INFO, "Unique name: %s\n", dbus_bus_get_unique_name(conn));
// Will be called if dispatch status changes
dbus_connection_set_dispatch_status_function(conn, dispatch_status, NULL, NULL);
if (!dbus_connection_set_watch_functions(conn, add_watch, remove_watch,
NULL, NULL, NULL)) {
dbus_connection_set_watch_functions(conn, NULL, NULL, NULL, NULL, NULL);
sway_log(L_ERROR, "Failed to activate DBUS watch functions");
return -1;
}
if (!dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout,
NULL, NULL, NULL)) {
dbus_connection_set_watch_functions(conn, NULL, NULL, NULL, NULL, NULL);
dbus_connection_set_timeout_functions(conn, NULL, NULL, NULL, NULL, NULL);
sway_log(L_ERROR, "Failed to activate DBUS timeout functions");
return -1;
}
return 0;
}