[Wayland] Fixes segfault when mouse enters window

This commit is contained in:
Gabriel Jacobo 2014-01-28 11:39:37 -03:00
parent 682bc47bc5
commit f52d7f5eea
2 changed files with 64 additions and 45 deletions

View File

@ -87,9 +87,18 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
return; return;
} }
input->pointer_focus = wl_surface_get_user_data(surface); /* This handler will be called twice in Wayland 1.4
window = input->pointer_focus; * Once for the window surface which has valid user data
SDL_SetMouseFocus(window->sdlwindow); * and again for the mouse cursor surface which does not have valid user data
* We ignore the later
*/
window = (SDL_WindowData *)wl_surface_get_user_data(surface);
if (window) {
input->pointer_focus = window;
SDL_SetMouseFocus(window->sdlwindow);
}
} }
static void static void
@ -98,8 +107,10 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
{ {
struct SDL_WaylandInput *input = data; struct SDL_WaylandInput *input = data;
SDL_SetMouseFocus(NULL); if (input->pointer_focus) {
input->pointer_focus = NULL; SDL_SetMouseFocus(NULL);
input->pointer_focus = NULL;
}
} }
static void static void
@ -110,8 +121,9 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
SDL_WindowData *window = input->pointer_focus; SDL_WindowData *window = input->pointer_focus;
int sx = wl_fixed_to_int(sx_w); int sx = wl_fixed_to_int(sx_w);
int sy = wl_fixed_to_int(sy_w); int sy = wl_fixed_to_int(sy_w);
if (input->pointer_focus) {
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy); SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
}
} }
static void static void
@ -123,28 +135,30 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
enum wl_pointer_button_state state = state_w; enum wl_pointer_button_state state = state_w;
uint32_t sdl_button; uint32_t sdl_button;
switch (button) { if (input->pointer_focus) {
case BTN_LEFT: switch (button) {
sdl_button = SDL_BUTTON_LEFT; case BTN_LEFT:
break; sdl_button = SDL_BUTTON_LEFT;
case BTN_MIDDLE: break;
sdl_button = SDL_BUTTON_MIDDLE; case BTN_MIDDLE:
break; sdl_button = SDL_BUTTON_MIDDLE;
case BTN_RIGHT: break;
sdl_button = SDL_BUTTON_RIGHT; case BTN_RIGHT:
break; sdl_button = SDL_BUTTON_RIGHT;
case BTN_SIDE: break;
sdl_button = SDL_BUTTON_X1; case BTN_SIDE:
break; sdl_button = SDL_BUTTON_X1;
case BTN_EXTRA: break;
sdl_button = SDL_BUTTON_X2; case BTN_EXTRA:
break; sdl_button = SDL_BUTTON_X2;
default: break;
return; default:
} return;
}
SDL_SendMouseButton(window->sdlwindow, 0, SDL_SendMouseButton(window->sdlwindow, 0,
state ? SDL_PRESSED : SDL_RELEASED, sdl_button); state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
}
} }
static void static void
@ -156,20 +170,22 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
enum wl_pointer_axis a = axis; enum wl_pointer_axis a = axis;
int x, y; int x, y;
switch (a) { if (input->pointer_focus) {
case WL_POINTER_AXIS_VERTICAL_SCROLL: switch (a) {
x = 0; case WL_POINTER_AXIS_VERTICAL_SCROLL:
y = wl_fixed_to_int(value); x = 0;
break; y = wl_fixed_to_int(value);
case WL_POINTER_AXIS_HORIZONTAL_SCROLL: break;
x = wl_fixed_to_int(value); case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
y = 0; x = wl_fixed_to_int(value);
break; y = 0;
default: break;
return; default:
} return;
}
SDL_SendMouseWheel(window->sdlwindow, 0, x, y); SDL_SendMouseWheel(window->sdlwindow, 0, x, y);
}
} }
static const struct wl_pointer_listener pointer_listener = { static const struct wl_pointer_listener pointer_listener = {
@ -234,7 +250,9 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
input->keyboard_focus = window; input->keyboard_focus = window;
window->keyboard_device = input; window->keyboard_device = input;
SDL_SetKeyboardFocus(window->sdlwindow); if (window) {
SDL_SetKeyboardFocus(window->sdlwindow);
}
} }
static void static void
@ -340,11 +358,10 @@ Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
{ {
struct SDL_WaylandInput *input; struct SDL_WaylandInput *input;
input = malloc(sizeof *input); input = SDL_calloc(1, sizeof *input);
if (input == NULL) if (input == NULL)
return; return;
memset(input, 0, sizeof *input);
input->display = d; input->display = d;
input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1); input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
@ -378,7 +395,7 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
if (input->xkb.keymap) if (input->xkb.keymap)
WAYLAND_xkb_keymap_unref(input->xkb.keymap); WAYLAND_xkb_keymap_unref(input->xkb.keymap);
free(input); SDL_free(input);
d->input = NULL; d->input = NULL;
} }

View File

@ -181,6 +181,7 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
surface->h * surface->pitch); surface->h * surface->pitch);
data->surface = wl_compositor_create_surface(wd->compositor); data->surface = wl_compositor_create_surface(wd->compositor);
wl_surface_set_user_data(data->surface, NULL);
wl_surface_attach(data->surface, wl_surface_attach(data->surface,
data->buffer, data->buffer,
0, 0,
@ -214,6 +215,7 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
* reference to it here */ * reference to it here */
data->buffer = NULL; data->buffer = NULL;
data->surface = wl_compositor_create_surface(d->compositor); data->surface = wl_compositor_create_surface(d->compositor);
wl_surface_set_user_data(data->surface, NULL);
wl_surface_attach(data->surface, wl_surface_attach(data->surface,
WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]), WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]),
0, 0,