mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-26 10:12:17 +02:00
Implement DBUS timeout functions
This commit is contained in:
27
glfw/backend_utils.c
vendored
27
glfw/backend_utils.c
vendored
@@ -12,11 +12,25 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
#define ppoll pollts
|
#define ppoll pollts
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
monotonic() {
|
||||||
|
struct timespec ts = {0};
|
||||||
|
#ifdef CLOCK_HIGHRES
|
||||||
|
clock_gettime(CLOCK_HIGHRES, &ts);
|
||||||
|
#elif CLOCK_MONOTONIC_RAW
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
#else
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
#endif
|
||||||
|
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
update_fds(EventLoopData *eld) {
|
update_fds(EventLoopData *eld) {
|
||||||
eld->fds_count = 0;
|
eld->fds_count = 0;
|
||||||
@@ -73,7 +87,6 @@ toggleWatch(EventLoopData *eld, id_type watch_id, int enabled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static id_type timer_counter = 0;
|
static id_type timer_counter = 0;
|
||||||
extern double glfwGetTime(void);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_timers(const void *a_, const void *b_) {
|
compare_timers(const void *a_, const void *b_) {
|
||||||
@@ -91,7 +104,7 @@ addTimer(EventLoopData *eld, double interval, int enabled, timer_callback_func c
|
|||||||
if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) return 0;
|
if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) return 0;
|
||||||
Timer *t = eld->timers + eld->timers_count++;
|
Timer *t = eld->timers + eld->timers_count++;
|
||||||
t->interval = interval;
|
t->interval = interval;
|
||||||
t->trigger_at = enabled ? glfwGetTime() + interval : DBL_MAX;
|
t->trigger_at = enabled ? monotonic() + interval : DBL_MAX;
|
||||||
t->callback = cb;
|
t->callback = cb;
|
||||||
t->callback_data = cb_data;
|
t->callback_data = cb_data;
|
||||||
t->id = ++timer_counter;
|
t->id = ++timer_counter;
|
||||||
@@ -108,7 +121,7 @@ void
|
|||||||
toggleTimer(EventLoopData *eld, id_type timer_id, int enabled) {
|
toggleTimer(EventLoopData *eld, id_type timer_id, int enabled) {
|
||||||
for (nfds_t i = 0; i < eld->timers_count; i++) {
|
for (nfds_t i = 0; i < eld->timers_count; i++) {
|
||||||
if (eld->timers[i].id == timer_id) {
|
if (eld->timers[i].id == timer_id) {
|
||||||
double trigger_at = enabled ? (glfwGetTime() + eld->timers[i].interval) : DBL_MAX;
|
double trigger_at = enabled ? (monotonic() + eld->timers[i].interval) : DBL_MAX;
|
||||||
if (trigger_at != eld->timers[i].trigger_at) {
|
if (trigger_at != eld->timers[i].trigger_at) {
|
||||||
eld->timers[i].trigger_at = trigger_at;
|
eld->timers[i].trigger_at = trigger_at;
|
||||||
update_timers(eld);
|
update_timers(eld);
|
||||||
@@ -133,7 +146,7 @@ double
|
|||||||
prepareForPoll(EventLoopData *eld, double timeout) {
|
prepareForPoll(EventLoopData *eld, double timeout) {
|
||||||
for (nfds_t i = 0; i < eld->fds_count; i++) eld->fds[i].revents = 0;
|
for (nfds_t i = 0; i < eld->fds_count; i++) eld->fds[i].revents = 0;
|
||||||
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return timeout;
|
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return timeout;
|
||||||
double now = glfwGetTime(), next_repeat_at = eld->timers[0].trigger_at;
|
double now = monotonic(), next_repeat_at = eld->timers[0].trigger_at;
|
||||||
if (timeout < 0 || now + timeout > next_repeat_at) {
|
if (timeout < 0 || now + timeout > next_repeat_at) {
|
||||||
timeout = next_repeat_at <= now ? 0 : next_repeat_at - now;
|
timeout = next_repeat_at <= now ? 0 : next_repeat_at - now;
|
||||||
}
|
}
|
||||||
@@ -165,7 +178,7 @@ dispatchTimers(EventLoopData *eld) {
|
|||||||
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return 0;
|
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return 0;
|
||||||
static struct { timer_callback_func func; id_type id; void* data; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
|
static struct { timer_callback_func func; id_type id; void* data; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
|
||||||
unsigned num_dispatches = 0;
|
unsigned num_dispatches = 0;
|
||||||
double now = glfwGetTime();
|
double now = monotonic();
|
||||||
for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at < DBL_MAX; i++) {
|
for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at < DBL_MAX; i++) {
|
||||||
if (eld->timers[i].trigger_at <= now) {
|
if (eld->timers[i].trigger_at <= now) {
|
||||||
eld->timers[i].trigger_at = now + eld->timers[i].interval;
|
eld->timers[i].trigger_at = now + eld->timers[i].interval;
|
||||||
@@ -201,7 +214,7 @@ pollForEvents(EventLoopData *eld, double timeout) {
|
|||||||
int read_ok = 0;
|
int read_ok = 0;
|
||||||
timeout = prepareForPoll(eld, timeout);
|
timeout = prepareForPoll(eld, timeout);
|
||||||
int result;
|
int result;
|
||||||
double end_time = glfwGetTime() + timeout;
|
double end_time = monotonic() + timeout;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if (timeout >= 0) {
|
if (timeout >= 0) {
|
||||||
@@ -212,7 +225,7 @@ pollForEvents(EventLoopData *eld, double timeout) {
|
|||||||
read_ok = eld->watches[0].ready;
|
read_ok = eld->watches[0].ready;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
timeout = end_time - glfwGetTime();
|
timeout = end_time - monotonic();
|
||||||
if (timeout <= 0) break;
|
if (timeout <= 0) break;
|
||||||
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
|
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
|
||||||
break;
|
break;
|
||||||
|
|||||||
42
glfw/dbus_glfw.c
vendored
42
glfw/dbus_glfw.c
vendored
@@ -76,6 +76,7 @@ add_dbus_watch(DBusWatch *watch, void *data) {
|
|||||||
if (!watch_id) return FALSE;
|
if (!watch_id) return FALSE;
|
||||||
id_type *idp = malloc(sizeof(id_type));
|
id_type *idp = malloc(sizeof(id_type));
|
||||||
if (!idp) return FALSE;
|
if (!idp) return FALSE;
|
||||||
|
*idp = watch_id;
|
||||||
dbus_watch_set_data(watch, idp, free);
|
dbus_watch_set_data(watch, idp, free);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -92,6 +93,41 @@ toggle_dbus_watch(DBusWatch *watch, void *data) {
|
|||||||
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
|
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_dbus_timer_ready(id_type timer_id, void *data) {
|
||||||
|
DBusTimeout *t = (DBusTimeout*)data;
|
||||||
|
dbus_timeout_handle(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static dbus_bool_t
|
||||||
|
add_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||||
|
int enabled = dbus_timeout_get_enabled(timeout) ? 1 : 0;
|
||||||
|
double interval = ((double)dbus_timeout_get_interval(timeout)) / 1000.0;
|
||||||
|
if (interval < 0) return FALSE;
|
||||||
|
id_type timer_id = addTimer(dbus_data->eld, interval, enabled, on_dbus_timer_ready, timeout);
|
||||||
|
if (!timer_id) return FALSE;
|
||||||
|
id_type *idp = malloc(sizeof(id_type));
|
||||||
|
if (!idp) return FALSE;
|
||||||
|
*idp = timer_id;
|
||||||
|
dbus_timeout_set_data(timeout, idp, free);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||||
|
id_type *idp = dbus_timeout_get_data(timeout);
|
||||||
|
if (idp) removeTimer(dbus_data->eld, *idp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||||
|
id_type *idp = dbus_timeout_get_data(timeout);
|
||||||
|
if (idp) toggleTimer(dbus_data->eld, *idp, dbus_timeout_get_enabled(timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DBusConnection*
|
DBusConnection*
|
||||||
glfw_dbus_connect_to(const char *path, const char* err_msg) {
|
glfw_dbus_connect_to(const char *path, const char* err_msg) {
|
||||||
DBusError err;
|
DBusError err;
|
||||||
@@ -114,6 +150,12 @@ glfw_dbus_connect_to(const char *path, const char* err_msg) {
|
|||||||
dbus_connection_unref(ans);
|
dbus_connection_unref(ans);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (!dbus_connection_set_timeout_functions(ans, add_dbus_timeout, remove_dbus_timeout, toggle_dbus_timeout, NULL, NULL)) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set DBUS timeout functions on connection to: %s", path);
|
||||||
|
dbus_connection_close(ans);
|
||||||
|
dbus_connection_unref(ans);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user