clients: consolidate timer code part 2
Continue moving bits to use toytimer instead of carelessly open-coded equivalent. Many of the copies were flawed against the race mentioned in toytimer_fire(). This patch handles window.c's key repeat, confine demo, and desktop-shell panel clock. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Derek Foreman <derekf@osg.samsung.com> Acked-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
3f5f3afa81
commit
64a26bc192
|
@ -33,8 +33,6 @@
|
|||
#include <cairo.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
|
@ -64,8 +62,7 @@ struct confine {
|
|||
int reset;
|
||||
|
||||
struct input *cursor_timeout_input;
|
||||
int cursor_timeout_fd;
|
||||
struct task cursor_timeout_task;
|
||||
struct toytimer cursor_timeout;
|
||||
|
||||
bool pointer_confined;
|
||||
|
||||
|
@ -347,14 +344,7 @@ button_handler(struct widget *widget,
|
|||
static void
|
||||
cursor_timeout_reset(struct confine *confine)
|
||||
{
|
||||
const long cursor_timeout = 500;
|
||||
struct itimerspec its;
|
||||
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = cursor_timeout / 1000;
|
||||
its.it_value.tv_nsec = (cursor_timeout % 1000) * 1000 * 1000;
|
||||
timerfd_settime(confine->cursor_timeout_fd, 0, &its, NULL);
|
||||
toytimer_arm_once_usec(&confine->cursor_timeout, 500 * 1000);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -406,15 +396,10 @@ leave_handler(struct widget *widget,
|
|||
}
|
||||
|
||||
static void
|
||||
cursor_timeout_func(struct task *task, uint32_t events)
|
||||
cursor_timeout_func(struct toytimer *tt)
|
||||
{
|
||||
struct confine *confine =
|
||||
container_of(task, struct confine, cursor_timeout_task);
|
||||
uint64_t exp;
|
||||
|
||||
if (read(confine->cursor_timeout_fd, &exp, sizeof (uint64_t)) !=
|
||||
sizeof(uint64_t))
|
||||
abort();
|
||||
container_of(tt, struct confine, cursor_timeout);
|
||||
|
||||
input_set_pointer_image(confine->cursor_timeout_input,
|
||||
CURSOR_LEFT_PTR);
|
||||
|
@ -461,12 +446,8 @@ confine_create(struct display *display)
|
|||
confine->line.old_y = -1;
|
||||
confine->reset = 0;
|
||||
|
||||
confine->cursor_timeout_fd =
|
||||
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||
confine->cursor_timeout_task.run = cursor_timeout_func;
|
||||
display_watch_fd(window_get_display(confine->window),
|
||||
confine->cursor_timeout_fd,
|
||||
EPOLLIN, &confine->cursor_timeout_task);
|
||||
toytimer_init(&confine->cursor_timeout, CLOCK_MONOTONIC,
|
||||
display, cursor_timeout_func);
|
||||
|
||||
return confine;
|
||||
}
|
||||
|
@ -474,9 +455,7 @@ confine_create(struct display *display)
|
|||
static void
|
||||
confine_destroy(struct confine *confine)
|
||||
{
|
||||
display_unwatch_fd(window_get_display(confine->window),
|
||||
confine->cursor_timeout_fd);
|
||||
close(confine->cursor_timeout_fd);
|
||||
toytimer_fini(&confine->cursor_timeout);
|
||||
if (confine->buffer)
|
||||
cairo_surface_destroy(confine->buffer);
|
||||
widget_destroy(confine->widget);
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include <math.h>
|
||||
#include <cairo.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <linux/input.h>
|
||||
#include <libgen.h>
|
||||
#include <ctype.h>
|
||||
|
@ -148,8 +146,7 @@ struct panel_launcher {
|
|||
struct panel_clock {
|
||||
struct widget *widget;
|
||||
struct panel *panel;
|
||||
struct task clock_task;
|
||||
int clock_fd;
|
||||
struct toytimer timer;
|
||||
char *format_string;
|
||||
time_t refresh_timer;
|
||||
};
|
||||
|
@ -365,14 +362,10 @@ panel_launcher_touch_up_handler(struct widget *widget, struct input *input,
|
|||
}
|
||||
|
||||
static void
|
||||
clock_func(struct task *task, uint32_t events)
|
||||
clock_func(struct toytimer *tt)
|
||||
{
|
||||
struct panel_clock *clock =
|
||||
container_of(task, struct panel_clock, clock_task);
|
||||
uint64_t exp;
|
||||
struct panel_clock *clock = container_of(tt, struct panel_clock, timer);
|
||||
|
||||
if (read(clock->clock_fd, &exp, sizeof exp) != sizeof exp)
|
||||
abort();
|
||||
widget_schedule_redraw(clock->widget);
|
||||
}
|
||||
|
||||
|
@ -423,10 +416,7 @@ clock_timer_reset(struct panel_clock *clock)
|
|||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = clock->refresh_timer;
|
||||
its.it_value.tv_nsec = 0;
|
||||
if (timerfd_settime(clock->clock_fd, 0, &its, NULL) < 0) {
|
||||
fprintf(stderr, "could not set timerfd\n: %m");
|
||||
return -1;
|
||||
}
|
||||
toytimer_arm(&clock->timer, &its);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -435,9 +425,7 @@ static void
|
|||
panel_destroy_clock(struct panel_clock *clock)
|
||||
{
|
||||
widget_destroy(clock->widget);
|
||||
|
||||
close(clock->clock_fd);
|
||||
|
||||
toytimer_fini(&clock->timer);
|
||||
free(clock);
|
||||
}
|
||||
|
||||
|
@ -445,18 +433,10 @@ static void
|
|||
panel_add_clock(struct panel *panel)
|
||||
{
|
||||
struct panel_clock *clock;
|
||||
int timerfd;
|
||||
|
||||
timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||
if (timerfd < 0) {
|
||||
fprintf(stderr, "could not create timerfd\n: %m");
|
||||
return;
|
||||
}
|
||||
|
||||
clock = xzalloc(sizeof *clock);
|
||||
clock->panel = panel;
|
||||
panel->clock = clock;
|
||||
clock->clock_fd = timerfd;
|
||||
|
||||
switch (panel->clock_format) {
|
||||
case CLOCK_FORMAT_MINUTES:
|
||||
|
@ -471,9 +451,8 @@ panel_add_clock(struct panel *panel)
|
|||
assert(!"not reached");
|
||||
}
|
||||
|
||||
clock->clock_task.run = clock_func;
|
||||
display_watch_fd(window_get_display(panel->window), clock->clock_fd,
|
||||
EPOLLIN, &clock->clock_task);
|
||||
toytimer_init(&clock->timer, CLOCK_MONOTONIC,
|
||||
window_get_display(panel->window), clock_func);
|
||||
clock_timer_reset(clock);
|
||||
|
||||
clock->widget = widget_add_widget(panel->widget, clock);
|
||||
|
|
|
@ -388,8 +388,7 @@ struct input {
|
|||
int32_t repeat_delay_sec;
|
||||
int32_t repeat_delay_nsec;
|
||||
|
||||
struct task repeat_task;
|
||||
int repeat_timer_fd;
|
||||
struct toytimer repeat_timer;
|
||||
uint32_t repeat_sym;
|
||||
uint32_t repeat_key;
|
||||
uint32_t repeat_time;
|
||||
|
@ -2910,13 +2909,8 @@ static void
|
|||
input_remove_keyboard_focus(struct input *input)
|
||||
{
|
||||
struct window *window = input->keyboard_focus;
|
||||
struct itimerspec its;
|
||||
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = 0;
|
||||
its.it_value.tv_nsec = 0;
|
||||
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
|
||||
toytimer_disarm(&input->repeat_timer);
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
@ -2929,18 +2923,10 @@ input_remove_keyboard_focus(struct input *input)
|
|||
}
|
||||
|
||||
static void
|
||||
keyboard_repeat_func(struct task *task, uint32_t events)
|
||||
keyboard_repeat_func(struct toytimer *tt)
|
||||
{
|
||||
struct input *input =
|
||||
container_of(task, struct input, repeat_task);
|
||||
struct input *input = container_of(tt, struct input, repeat_timer);
|
||||
struct window *window = input->keyboard_focus;
|
||||
uint64_t exp;
|
||||
|
||||
if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp)
|
||||
/* If we change the timer between the fd becoming
|
||||
* readable and getting here, there'll be nothing to
|
||||
* read and we get EAGAIN. */
|
||||
return;
|
||||
|
||||
if (window && window->key_handler) {
|
||||
(*window->key_handler)(window, input, input->repeat_time,
|
||||
|
@ -3163,11 +3149,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
|||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_RELEASED &&
|
||||
key == input->repeat_key) {
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = 0;
|
||||
its.it_value.tv_nsec = 0;
|
||||
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
|
||||
toytimer_disarm(&input->repeat_timer);
|
||||
} else if (state == WL_KEYBOARD_KEY_STATE_PRESSED &&
|
||||
xkb_keymap_key_repeats(input->xkb.keymap, code)) {
|
||||
input->repeat_sym = sym;
|
||||
|
@ -3177,7 +3159,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
|||
its.it_interval.tv_nsec = input->repeat_rate_nsec;
|
||||
its.it_value.tv_sec = input->repeat_delay_sec;
|
||||
its.it_value.tv_nsec = input->repeat_delay_nsec;
|
||||
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
|
||||
toytimer_arm(&input->repeat_timer, &its);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5846,13 +5828,10 @@ display_add_input(struct display *d, uint32_t id, int display_seat_version)
|
|||
|
||||
toytimer_init(&input->cursor_timer, CLOCK_MONOTONIC, d,
|
||||
cursor_timer_func);
|
||||
set_repeat_info(input, 40, 400);
|
||||
|
||||
input->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC,
|
||||
TFD_CLOEXEC | TFD_NONBLOCK);
|
||||
input->repeat_task.run = keyboard_repeat_func;
|
||||
display_watch_fd(d, input->repeat_timer_fd,
|
||||
EPOLLIN, &input->repeat_task);
|
||||
set_repeat_info(input, 40, 400);
|
||||
toytimer_init(&input->repeat_timer, CLOCK_MONOTONIC, d,
|
||||
keyboard_repeat_func);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5895,7 +5874,7 @@ input_destroy(struct input *input)
|
|||
|
||||
wl_list_remove(&input->link);
|
||||
wl_seat_destroy(input->seat);
|
||||
close(input->repeat_timer_fd);
|
||||
toytimer_fini(&input->repeat_timer);
|
||||
toytimer_fini(&input->cursor_timer);
|
||||
free(input);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue