aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/event_loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/event_loop.c')
-rw-r--r--swaybar/event_loop.c156
1 files changed, 0 insertions, 156 deletions
diff --git a/swaybar/event_loop.c b/swaybar/event_loop.c
deleted file mode 100644
index 686b9962..00000000
--- a/swaybar/event_loop.c
+++ /dev/null
@@ -1,156 +0,0 @@
1#define _XOPEN_SOURCE 700
2#include <stdlib.h>
3#include <stdbool.h>
4#include <string.h>
5#include <strings.h>
6#include <poll.h>
7#include <time.h>
8#include "swaybar/event_loop.h"
9#include "list.h"
10
11struct event_item {
12 void (*cb)(int fd, short mask, void *data);
13 void *data;
14};
15
16struct timer_item {
17 timer_t timer;
18 void (*cb)(timer_t timer, void *data);
19 void *data;
20};
21
22static struct {
23 // The order of each must be kept consistent
24 struct { /* pollfd array */
25 struct pollfd *items;
26 int capacity;
27 int length;
28 } fds;
29 list_t *items; /* event_item list */
30
31 // Timer list
32 list_t *timers;
33} event_loop;
34
35void add_timer(timer_t timer,
36 void(*cb)(timer_t timer, void *data),
37 void *data) {
38
39 struct timer_item *item = malloc(sizeof(struct timer_item));
40 item->timer = timer;
41 item->cb = cb;
42 item->data = data;
43
44 list_add(event_loop.timers, item);
45}
46
47void add_event(int fd, short mask,
48 void(*cb)(int fd, short mask, void *data), void *data) {
49
50 struct pollfd pollfd = {
51 fd,
52 mask,
53 0,
54 };
55
56 // Resize
57 if (event_loop.fds.length == event_loop.fds.capacity) {
58 event_loop.fds.capacity += 10;
59 event_loop.fds.items = realloc(event_loop.fds.items,
60 sizeof(struct pollfd) * event_loop.fds.capacity);
61 }
62
63 event_loop.fds.items[event_loop.fds.length++] = pollfd;
64
65 struct event_item *item = malloc(sizeof(struct event_item));
66 item->cb = cb;
67 item->data = data;
68
69 list_add(event_loop.items, item);
70
71 return;
72}
73
74bool remove_event(int fd) {
75 /*
76 * Instead of removing events immediately, we mark them for deletion
77 * and clean them up later. This is so we can call remove_event inside
78 * an event callback safely.
79 */
80 for (int i = 0; i < event_loop.fds.length; ++i) {
81 if (event_loop.fds.items[i].fd == fd) {
82 event_loop.fds.items[i].fd = -1;
83 return true;
84 }
85 }
86 return false;
87}
88
89static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) {
90 const struct timer_item *timer_item = _timer_item;
91 const timer_t *timer = _timer;
92 if (timer_item->timer == *timer) {
93 return 0;
94 } else {
95 return -1;
96 }
97}
98bool remove_timer(timer_t timer) {
99 int index = list_seq_find(event_loop.timers, timer_item_timer_cmp, &timer);
100 if (index != -1) {
101 free(event_loop.timers->items[index]);
102 list_del(event_loop.timers, index);
103 return true;
104 }
105 return false;
106}
107
108void event_loop_poll(void) {
109 poll(event_loop.fds.items, event_loop.fds.length, -1);
110
111 for (int i = 0; i < event_loop.fds.length; ++i) {
112 struct pollfd pfd = event_loop.fds.items[i];
113 struct event_item *item = (struct event_item *)event_loop.items->items[i];
114
115 // Always send these events
116 unsigned events = pfd.events | POLLHUP | POLLERR;
117
118 if (pfd.revents & events) {
119 item->cb(pfd.fd, pfd.revents, item->data);
120 }
121 }
122
123 // Cleanup removed events
124 int end = 0;
125 int length = event_loop.fds.length;
126 for (int i = 0; i < length; ++i) {
127 if (event_loop.fds.items[i].fd == -1) {
128 free(event_loop.items->items[i]);
129 list_del(event_loop.items, i);
130 --event_loop.fds.length;
131 } else if (end != i) {
132 event_loop.fds.items[end++] = event_loop.fds.items[i];
133 } else {
134 end = i + 1;
135 }
136 }
137
138 // check timers
139 // not tested, but seems to work
140 for (int i = 0; i < event_loop.timers->length; ++i) {
141 struct timer_item *item = event_loop.timers->items[i];
142 int overrun = timer_getoverrun(item->timer);
143 if (overrun && overrun != -1) {
144 item->cb(item->timer, item->data);
145 }
146 }
147}
148
149void init_event_loop(void) {
150 event_loop.fds.length = 0;
151 event_loop.fds.capacity = 10;
152 event_loop.fds.items = malloc(
153 event_loop.fds.capacity * sizeof(struct pollfd));
154 event_loop.items = create_list();
155 event_loop.timers = create_list();
156}