wlroots/backend/drm/event.c

94 lines
1.9 KiB
C
Raw Normal View History

2017-05-01 03:20:48 +00:00
#include <stdbool.h>
#include <stdlib.h>
#include <poll.h>
2017-05-01 05:49:18 +00:00
#include "backend/drm/backend.h"
#include "backend/drm/event.h"
#include "backend/drm/drm.h"
#include "backend/drm/udev.h"
static inline void event_swap(struct wlr_drm_event *a, struct wlr_drm_event *b)
2017-05-01 03:20:48 +00:00
{
2017-05-01 05:49:18 +00:00
struct wlr_drm_event tmp = *a;
2017-05-01 03:20:48 +00:00
*a = *b;
*b = tmp;
}
2017-05-01 05:49:18 +00:00
bool wlr_drm_get_event(struct wlr_drm_backend *backend,
struct wlr_drm_event *restrict ret)
2017-05-01 03:20:48 +00:00
{
struct pollfd fds[] = {
2017-05-01 05:49:18 +00:00
{ .fd = backend->fd, .events = POLLIN },
{ .fd = backend->udev.mon_fd, .events = POLLIN },
2017-05-01 03:20:48 +00:00
};
while (poll(fds, 2, 0) > 0) {
if (fds[0].revents)
2017-05-01 05:49:18 +00:00
wlr_drm_event(backend->fd);
2017-05-01 03:20:48 +00:00
if (fds[1].revents)
2017-05-01 05:49:18 +00:00
wlr_udev_event(backend);
2017-05-01 03:20:48 +00:00
}
2017-05-01 05:49:18 +00:00
if (backend->event_len == 0) {
ret->type = DRM_EV_NONE;
2017-05-01 03:20:48 +00:00
ret->display = NULL;
return false;
}
2017-05-01 05:49:18 +00:00
struct wlr_drm_event *ev = backend->events;
2017-05-01 03:20:48 +00:00
// Downheap
*ret = ev[0];
2017-05-01 05:49:18 +00:00
ev[0] = ev[--backend->event_len];
2017-05-01 03:20:48 +00:00
size_t i = 0;
2017-05-01 05:49:18 +00:00
while (i < backend->event_len / 2) {
2017-05-01 03:20:48 +00:00
size_t left = i * 2 + 1;
size_t right = i * 2 + 2;
size_t max = (ev[left].type > ev[right].type) ? left : right;
if (ev[i].type <= ev[max].type) {
event_swap(&ev[i], &ev[max]);
i = max;
} else {
break;
}
}
return true;
}
2017-05-01 05:49:18 +00:00
bool wlr_drm_add_event(struct wlr_drm_backend *backend,
struct wlr_drm_display *disp, enum wlr_drm_event_type type)
2017-05-01 03:20:48 +00:00
{
2017-05-01 05:49:18 +00:00
if (type == DRM_EV_NONE)
2017-05-01 03:20:48 +00:00
return true;
2017-05-01 05:49:18 +00:00
if (backend->event_len == backend->event_cap) {
size_t new_size = (backend->event_cap == 0) ? 8 : backend->event_cap * 2;
2017-05-01 03:20:48 +00:00
2017-05-01 05:49:18 +00:00
struct wlr_drm_event *new = realloc(backend->events, sizeof *new * new_size);
2017-05-01 03:20:48 +00:00
if (!new) {
return false;
}
2017-05-01 05:49:18 +00:00
backend->event_cap = new_size;
backend->events = new;
2017-05-01 03:20:48 +00:00
}
2017-05-01 05:49:18 +00:00
struct wlr_drm_event *ev = backend->events;
2017-05-01 03:20:48 +00:00
// Upheap
2017-05-01 05:49:18 +00:00
size_t i = backend->event_len++;
2017-05-01 03:20:48 +00:00
ev[i].type = type;
ev[i].display = disp;
size_t j;
while (i > 0 && ev[i].type > ev[(j = (i - 1) / 2)].type) {
event_swap(&ev[i], &ev[j]);
i = j;
}
return true;
}