summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorAlexander Preisinger <alexander.preisinger@gmail.com>2013-05-01 15:41:33 +0200
committerAlexander Preisinger <alexander.preisinger@gmail.com>2013-05-01 15:41:33 +0200
commitdb0c3d79f8dc53e07d0215fd1c67a0922e735d8f (patch)
tree4a1c3e2262375bd79aadf64353764d71d4e90a2d /video
parent048c68e5c22c6e2db54f228c6af7acfacad2d880 (diff)
downloadmpv-db0c3d79f8dc53e07d0215fd1c67a0922e735d8f.tar.bz2
mpv-db0c3d79f8dc53e07d0215fd1c67a0922e735d8f.tar.xz
wayland: use GetTimerMS for hiding mouse cursor
This commit remove a lot of linux specific code, like epoll. It also reduces the complexity of the code. Instead of epoll we use poll which makes the wayland backend more portable to other platforms.
Diffstat (limited to 'video')
-rw-r--r--video/out/wayland_common.c184
-rw-r--r--video/out/wayland_common.h16
2 files changed, 39 insertions, 161 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 3c81f829b9..12bffce386 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -26,12 +26,10 @@
#include <inttypes.h>
#include <limits.h>
#include <assert.h>
-#include <fcntl.h>
+#include <poll.h>
#include <unistd.h>
#include <sys/mman.h>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
#include <linux/input.h>
#include "config.h"
@@ -387,20 +385,8 @@ static void pointer_handle_motion(void *data,
display->cursor.pointer = pointer;
- if (wl->window->type == TYPE_FULLSCREEN) {
+ if (wl->window->type == TYPE_FULLSCREEN)
show_cursor(wl);
-
- struct itimerspec its;
- int ms = wl->vo->opts->cursor_autohide_delay;
- int sec = ms / 1000;
- ms %= 1000;
-
- its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = 100 * 1000 * 1000;
- its.it_value.tv_sec = sec;
- its.it_value.tv_nsec = ms * 1000 * 1000;
- timerfd_settime(display->cursor.timer_fd, 0, &its, NULL);
- }
}
static void pointer_handle_button(void *data,
@@ -417,7 +403,6 @@ static void pointer_handle_button(void *data,
if ((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED))
wl_shell_surface_move(wl->window->shell_surface, wl->input->seat, serial);
-
}
static void pointer_handle_axis(void *data,
@@ -555,40 +540,6 @@ static const struct wl_registry_listener registry_listener = {
/*** internal functions ***/
-static int set_cloexec_or_close(int fd)
-{
- long flags;
-
- if (fd == -1)
- return -1;
-
- if ((flags = fcntl(fd, F_GETFD)) == -1)
- goto err;
-
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
- goto err;
-
- return fd;
-
-err:
- close(fd);
- return -1;
-}
-
-static int os_epoll_create_cloexec(void)
-{
- int fd;
-
-#ifdef EPOLL_CLOEXEC
- if ((fd = epoll_create1(EPOLL_CLOEXEC)) >= 0)
- return fd;
- if (errno != EINVAL)
- return -1;
-#endif
-
- return set_cloexec_or_close(epoll_create(1));
-}
-
static int lookupkey(int key)
{
static const char *passthrough_keys
@@ -615,6 +566,7 @@ static void hide_cursor (struct vo_wayland_state *wl)
wl_pointer_set_cursor(display->cursor.pointer, display->cursor.serial,
NULL, 0, 0);
+
}
static void show_cursor (struct vo_wayland_state *wl)
@@ -634,59 +586,9 @@ static void show_cursor (struct vo_wayland_state *wl)
wl_surface_damage(display->cursor.surface, 0, 0,
image->width, image->height);
wl_surface_commit(display->cursor.surface);
-}
-
-static void
-display_watch_fd(struct vo_wayland_display *display,
- int fd, uint32_t events, struct vo_wayland_task *task)
-{
- struct epoll_event ep;
- if (display->epoll_fd < 0) {
- mp_msg(MSGT_VO, MSGL_WARN, "[wayland] Could not watch fd\n");
- return;
- }
-
- ep.events = events;
- ep.data.ptr = task;
- epoll_ctl(display->epoll_fd, EPOLL_CTL_ADD, fd, &ep);
-}
-
-static void display_handle_data(struct vo_wayland_task *task,
- uint32_t events,
- struct vo_wayland_state *wl)
-{
- struct vo_wayland_display *display = wl->display;
- struct epoll_event ep;
- int ret;
-
- if (events & EPOLLERR || events & EPOLLHUP)
- exit(-1);
-
- if (events & EPOLLIN) {
- ret = wl_display_dispatch(display->display);
- if (ret == -1)
- exit(-1);
- }
-
- if (events & EPOLLOUT) {
- ret = wl_display_flush(display->display);
- if (ret == 0) {
- ep.events = EPOLLIN | EPOLLERR | EPOLLHUP;
- ep.data.ptr = &display->display_task;
- epoll_ctl(display->epoll_fd, EPOLL_CTL_MOD,
- display->display_fd, &ep);
- } else if (ret == -1 && errno != EAGAIN)
- exit(-1);
- }
-}
-
-static void cursor_timer_func(struct vo_wayland_task *task,
- uint32_t events,
- struct vo_wayland_state *wl)
-{
- if (wl->window->type == TYPE_FULLSCREEN)
- hide_cursor(wl);
+ display->cursor.mouse_timer = GetTimerMS() + wl->vo->opts->cursor_autohide_delay;
+ display->cursor.mouse_waiting_hide = true;
}
static bool create_display (struct vo_wayland_state *wl)
@@ -713,11 +615,7 @@ static bool create_display (struct vo_wayland_state *wl)
d->cursor.surface =
wl_compositor_create_surface(d->compositor);
- d->epoll_fd = os_epoll_create_cloexec();
d->display_fd = wl_display_get_fd(d->display);
- d->display_task.run = display_handle_data;
- display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP,
- &d->display_task);
return true;
}
@@ -798,22 +696,6 @@ static void destroy_input (struct vo_wayland_state *wl)
xkb_context_unref(wl->input->xkb.context);
}
-static void create_timers (struct vo_wayland_state *wl)
-{
- struct vo_wayland_display *d = wl->display;
-
- d->cursor.task.run = cursor_timer_func;
- d->cursor.timer_fd = timerfd_create(CLOCK_MONOTONIC,
- TFD_CLOEXEC | TFD_NONBLOCK);
- display_watch_fd(d, d->cursor.timer_fd, EPOLLIN, &d->cursor.task);
-}
-
-static void destroy_timers (struct vo_wayland_state *wl)
-{
- close(wl->display->cursor.timer_fd);
-}
-
-
/*** mplayer2 interface ***/
int vo_wayland_init (struct vo *vo)
@@ -829,8 +711,7 @@ int vo_wayland_init (struct vo *vo)
return false;
}
- create_timers(wl);
- vo->event_fd = wl->display->epoll_fd;
+ vo->event_fd = wl->display->display_fd;
create_window(wl);
vo_wayland_update_window_title(vo);
@@ -840,7 +721,6 @@ int vo_wayland_init (struct vo *vo)
void vo_wayland_uninit (struct vo *vo)
{
struct vo_wayland_state *wl = vo->wayland;
- destroy_timers(wl);
destroy_input(wl);
destroy_window(wl);
destroy_display(wl);
@@ -907,35 +787,43 @@ void vo_wayland_fullscreen (struct vo *vo)
int vo_wayland_check_events (struct vo *vo)
{
- struct vo_wayland_task *task;
struct vo_wayland_state *wl = vo->wayland;
- int i, ret, count;
- struct epoll_event ep[16];
-
- wl_display_dispatch_pending(wl->display->display);
-
- ret = wl_display_flush(wl->display->display);
-
- if (ret < 0 && errno == EAGAIN) {
- ep[0].events = EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP;
- ep[0].data.ptr = NULL;
+ struct wl_display *dp = wl->display->display;
+ int ret;
- epoll_ctl(wl->display->epoll_fd, EPOLL_CTL_MOD,
- wl->display->display_fd, &ep[0]);
- }
- else if (ret < 0) {
- return 0;
+ if (wl->window->type == TYPE_FULLSCREEN &&
+ wl->display->cursor.mouse_waiting_hide &&
+ GetTimerMS() >= wl->display->cursor.mouse_timer)
+ {
+ hide_cursor(wl);
+ wl->display->cursor.mouse_waiting_hide = false;
}
- count = epoll_wait(wl->display->epoll_fd, ep, ARRAY_LENGTH(ep), 1);
+ wl_display_dispatch_pending(dp);
+ wl_display_flush(dp);
- for (i = 0; i < count; i++) {
- task = ep[i].data.ptr;
- task->run(task, ep[i].events, wl);
- }
+ struct pollfd fd = {
+ wl->display->display_fd,
+ POLLIN | POLLERR | POLLHUP,
+ 0
+ };
+ /* wl_display_dispatch is blocking
+ * wl_dipslay_dispatch is non-blocking but does not read from the fd
+ *
+ * when pausing no input events get queued so we have to check if there
+ * are events to read from the file descriptor through poll */
+ if (poll(&fd, 1, 0) > 0) {
+ if (fd.revents & POLLIN)
+ wl_display_dispatch(dp);
+ if (fd.revents & POLLOUT)
+ wl_display_flush(dp);
+ }
+
+ if (wl->display->cursor.mouse_waiting_hide)
+ vo->next_wakeup_time = FFMIN(vo->next_wakeup_time,
+ wl->display->cursor.mouse_timer);
ret = wl->window->events;
-
wl->window->events = 0;
return ret;
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index 20d3853fcf..30706686fe 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -35,15 +35,6 @@ enum vo_wayland_window_type {
};
struct vo;
-struct vo_wayland_state;
-
-struct vo_wayland_task {
- void (*run)(struct vo_wayland_task *task,
- uint32_t events,
- struct vo_wayland_state *wl);
-
- struct wl_list link;
-};
struct vo_wayland_output {
uint32_t id; /* unique name */
@@ -68,14 +59,13 @@ struct vo_wayland_display {
struct wl_surface *surface;
/* save timer and pointer for fading out */
+ int mouse_timer;
+ bool mouse_waiting_hide;
struct wl_pointer *pointer;
uint32_t serial;
- int timer_fd;
- struct vo_wayland_task task;
} cursor;
- int display_fd, epoll_fd;
- struct vo_wayland_task display_task;
+ int display_fd;
struct wl_list output_list;
struct wl_output *fs_output; /* fullscreen output */