Commit 579d67e1 authored by Alexandros Frantzis's avatar Alexandros Frantzis Committed by Alexandre Julliard

winewayland.drv: Handle pointer focus events.

Handle wl_pointer enter/leave events and maintain information about the focused HWND. Since pointer information will be accessed by any UI capable thread, ensure proper proper locking is in place.
parent a3709b93
......@@ -34,6 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
struct wayland process_wayland =
{
.pointer.mutex = PTHREAD_MUTEX_INITIALIZER,
.output_list = {&process_wayland.output_list, &process_wayland.output_list},
.output_mutex = PTHREAD_MUTEX_INITIALIZER
};
......@@ -60,9 +61,9 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener =
static void wl_seat_handle_capabilities(void *data, struct wl_seat *seat,
enum wl_seat_capability caps)
{
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !process_wayland.wl_pointer)
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !process_wayland.pointer.wl_pointer)
wayland_pointer_init(wl_seat_get_pointer(seat));
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && process_wayland.wl_pointer)
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && process_wayland.pointer.wl_pointer)
wayland_pointer_deinit();
}
......@@ -155,7 +156,7 @@ static void registry_handle_global_remove(void *data, struct wl_registry *regist
wl_proxy_get_id((struct wl_proxy *)process_wayland.wl_seat) == id)
{
TRACE("removing seat\n");
if (process_wayland.wl_pointer) wayland_pointer_deinit();
if (process_wayland.pointer.wl_pointer) wayland_pointer_deinit();
wl_seat_release(process_wayland.wl_seat);
process_wayland.wl_seat = NULL;
}
......
......@@ -25,6 +25,9 @@
#include "config.h"
#include "waylanddrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
......@@ -35,11 +38,33 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *wl_surface,
wl_fixed_t sx, wl_fixed_t sy)
{
struct wayland_pointer *pointer = &process_wayland.pointer;
HWND hwnd;
if (!wl_surface) return;
/* The wl_surface user data remains valid and immutable for the whole
* lifetime of the object, so it's safe to access without locking. */
hwnd = wl_surface_get_user_data(wl_surface);
TRACE("hwnd=%p\n", hwnd);
pthread_mutex_lock(&pointer->mutex);
pointer->focused_hwnd = hwnd;
pthread_mutex_unlock(&pointer->mutex);
}
static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *wl_surface)
{
struct wayland_pointer *pointer = &process_wayland.pointer;
if (!wl_surface) return;
TRACE("hwnd=%p\n", wl_surface_get_user_data(wl_surface));
pthread_mutex_lock(&pointer->mutex);
pointer->focused_hwnd = NULL;
pthread_mutex_unlock(&pointer->mutex);
}
static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
......@@ -87,12 +112,22 @@ static const struct wl_pointer_listener pointer_listener =
void wayland_pointer_init(struct wl_pointer *wl_pointer)
{
process_wayland.wl_pointer = wl_pointer;
wl_pointer_add_listener(process_wayland.wl_pointer, &pointer_listener, NULL);
struct wayland_pointer *pointer = &process_wayland.pointer;
pthread_mutex_lock(&pointer->mutex);
pointer->wl_pointer = wl_pointer;
pointer->focused_hwnd = NULL;
pthread_mutex_unlock(&pointer->mutex);
wl_pointer_add_listener(pointer->wl_pointer, &pointer_listener, NULL);
}
void wayland_pointer_deinit(void)
{
wl_pointer_release(process_wayland.wl_pointer);
process_wayland.wl_pointer = NULL;
struct wayland_pointer *pointer = &process_wayland.pointer;
pthread_mutex_lock(&pointer->mutex);
wl_pointer_release(pointer->wl_pointer);
pointer->wl_pointer = NULL;
pointer->focused_hwnd = NULL;
pthread_mutex_unlock(&pointer->mutex);
}
......@@ -108,6 +108,7 @@ struct wayland_surface *wayland_surface_create(HWND hwnd)
ERR("Failed to create wl_surface Wayland surface\n");
goto err;
}
wl_surface_set_user_data(surface->wl_surface, hwnd);
return surface;
......@@ -123,6 +124,11 @@ err:
*/
void wayland_surface_destroy(struct wayland_surface *surface)
{
pthread_mutex_lock(&process_wayland.pointer.mutex);
if (process_wayland.pointer.focused_hwnd == surface->hwnd)
process_wayland.pointer.focused_hwnd = NULL;
pthread_mutex_unlock(&process_wayland.pointer.mutex);
pthread_mutex_lock(&xdg_data_mutex);
pthread_mutex_lock(&surface->mutex);
......
......@@ -56,6 +56,13 @@ enum wayland_window_message
WM_WAYLAND_INIT_DISPLAY_DEVICES = 0x80001000
};
struct wayland_pointer
{
struct wl_pointer *wl_pointer;
HWND focused_hwnd;
pthread_mutex_t mutex;
};
struct wayland
{
BOOL initialized;
......@@ -67,7 +74,7 @@ struct wayland
struct xdg_wm_base *xdg_wm_base;
struct wl_shm *wl_shm;
struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer;
struct wayland_pointer pointer;
struct wl_list output_list;
/* Protects the output_list and the wayland_output.current states. */
pthread_mutex_t output_mutex;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment