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); ...@@ -34,6 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
struct wayland process_wayland = struct wayland process_wayland =
{ {
.pointer.mutex = PTHREAD_MUTEX_INITIALIZER,
.output_list = {&process_wayland.output_list, &process_wayland.output_list}, .output_list = {&process_wayland.output_list, &process_wayland.output_list},
.output_mutex = PTHREAD_MUTEX_INITIALIZER .output_mutex = PTHREAD_MUTEX_INITIALIZER
}; };
...@@ -60,9 +61,9 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = ...@@ -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, static void wl_seat_handle_capabilities(void *data, struct wl_seat *seat,
enum wl_seat_capability caps) 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)); 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(); wayland_pointer_deinit();
} }
...@@ -155,7 +156,7 @@ static void registry_handle_global_remove(void *data, struct wl_registry *regist ...@@ -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) wl_proxy_get_id((struct wl_proxy *)process_wayland.wl_seat) == id)
{ {
TRACE("removing seat\n"); 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); wl_seat_release(process_wayland.wl_seat);
process_wayland.wl_seat = NULL; process_wayland.wl_seat = NULL;
} }
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#include "config.h" #include "config.h"
#include "waylanddrv.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, static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
uint32_t time, wl_fixed_t sx, wl_fixed_t sy) 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, ...@@ -35,11 +38,33 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *wl_surface, uint32_t serial, struct wl_surface *wl_surface,
wl_fixed_t sx, wl_fixed_t sy) 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, static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *wl_surface) 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, static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
...@@ -87,12 +112,22 @@ static const struct wl_pointer_listener pointer_listener = ...@@ -87,12 +112,22 @@ static const struct wl_pointer_listener pointer_listener =
void wayland_pointer_init(struct wl_pointer *wl_pointer) void wayland_pointer_init(struct wl_pointer *wl_pointer)
{ {
process_wayland.wl_pointer = wl_pointer; struct wayland_pointer *pointer = &process_wayland.pointer;
wl_pointer_add_listener(process_wayland.wl_pointer, &pointer_listener, NULL);
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) void wayland_pointer_deinit(void)
{ {
wl_pointer_release(process_wayland.wl_pointer); struct wayland_pointer *pointer = &process_wayland.pointer;
process_wayland.wl_pointer = NULL;
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) ...@@ -108,6 +108,7 @@ struct wayland_surface *wayland_surface_create(HWND hwnd)
ERR("Failed to create wl_surface Wayland surface\n"); ERR("Failed to create wl_surface Wayland surface\n");
goto err; goto err;
} }
wl_surface_set_user_data(surface->wl_surface, hwnd);
return surface; return surface;
...@@ -123,6 +124,11 @@ err: ...@@ -123,6 +124,11 @@ err:
*/ */
void wayland_surface_destroy(struct wayland_surface *surface) 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(&xdg_data_mutex);
pthread_mutex_lock(&surface->mutex); pthread_mutex_lock(&surface->mutex);
......
...@@ -56,6 +56,13 @@ enum wayland_window_message ...@@ -56,6 +56,13 @@ enum wayland_window_message
WM_WAYLAND_INIT_DISPLAY_DEVICES = 0x80001000 WM_WAYLAND_INIT_DISPLAY_DEVICES = 0x80001000
}; };
struct wayland_pointer
{
struct wl_pointer *wl_pointer;
HWND focused_hwnd;
pthread_mutex_t mutex;
};
struct wayland struct wayland
{ {
BOOL initialized; BOOL initialized;
...@@ -67,7 +74,7 @@ struct wayland ...@@ -67,7 +74,7 @@ struct wayland
struct xdg_wm_base *xdg_wm_base; struct xdg_wm_base *xdg_wm_base;
struct wl_shm *wl_shm; struct wl_shm *wl_shm;
struct wl_seat *wl_seat; struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer; struct wayland_pointer pointer;
struct wl_list output_list; struct wl_list output_list;
/* Protects the output_list and the wayland_output.current states. */ /* Protects the output_list and the wayland_output.current states. */
pthread_mutex_t output_mutex; 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