window: Fix crash in input_set_pointer_image when cursor is special

Certain circumstances may lead to the "force" clause in
input_set_pointer_image() being reached when the current cursor
is blank or unset.  These are special cursors that don't have
images, and they need to be handled differently than image cursors.

This patch puts the special cursor handling in its own function and calls
it from both places that need it.  Previously only the frame callback
handler did this correctly.

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Derek Foreman 2015-03-04 16:26:25 -06:00 committed by Pekka Paalanen
parent fa79b1d9dc
commit 493d979e57

View File

@ -38,6 +38,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <sys/timerfd.h> #include <sys/timerfd.h>
#include <stdbool.h>
#ifdef HAVE_CAIRO_EGL #ifdef HAVE_CAIRO_EGL
#include <wayland-egl.h> #include <wayland-egl.h>
@ -3524,6 +3525,22 @@ input_set_pointer_image_index(struct input *input, int index)
static const struct wl_callback_listener pointer_surface_listener; static const struct wl_callback_listener pointer_surface_listener;
static bool
input_set_pointer_special(struct input *input)
{
if (input->current_cursor == CURSOR_BLANK) {
wl_pointer_set_cursor(input->pointer,
input->pointer_enter_serial,
NULL, 0, 0);
return true;
}
if (input->current_cursor == CURSOR_UNSET)
return true;
return false;
}
static void static void
pointer_surface_frame_callback(void *data, struct wl_callback *callback, pointer_surface_frame_callback(void *data, struct wl_callback *callback,
uint32_t time) uint32_t time)
@ -3541,15 +3558,9 @@ pointer_surface_frame_callback(void *data, struct wl_callback *callback,
if (!input->pointer) if (!input->pointer)
return; return;
if (input->current_cursor == CURSOR_BLANK) { if (input_set_pointer_special(input))
wl_pointer_set_cursor(input->pointer,
input->pointer_enter_serial,
NULL, 0, 0);
return; return;
}
if (input->current_cursor == CURSOR_UNSET)
return;
cursor = input->display->cursors[input->current_cursor]; cursor = input->display->cursors[input->current_cursor];
if (!cursor) if (!cursor)
return; return;
@ -3598,7 +3609,7 @@ input_set_pointer_image(struct input *input, int pointer)
input->cursor_serial = input->pointer_enter_serial; input->cursor_serial = input->pointer_enter_serial;
if (!input->cursor_frame_cb) if (!input->cursor_frame_cb)
pointer_surface_frame_callback(input, NULL, 0); pointer_surface_frame_callback(input, NULL, 0);
else if (force) { else if (force && !input_set_pointer_special(input)) {
/* The current frame callback may be stuck if, for instance, /* The current frame callback may be stuck if, for instance,
* the set cursor request was processed by the server after * the set cursor request was processed by the server after
* this client lost the focus. In this case the cursor surface * this client lost the focus. In this case the cursor surface