From: Alexandros Frantzis alexandros.frantzis@collabora.com
Create and manage an internal driver data structure for each non-desktop, non-message window. --- dlls/winewayland.drv/waylanddrv.h | 4 + dlls/winewayland.drv/waylanddrv_main.c | 4 +- dlls/winewayland.drv/window.c | 120 +++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 57125e011cb..ed1d3ea0be2 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -111,8 +111,12 @@ void wayland_output_use_xdg_extension(struct wayland_output *output) DECLSPEC_HI */
LRESULT WAYLAND_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) DECLSPEC_HIDDEN; +void WAYLAND_DestroyWindow(HWND hwnd) DECLSPEC_HIDDEN; BOOL WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, BOOL force, void *param) DECLSPEC_HIDDEN; LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) DECLSPEC_HIDDEN; +BOOL WAYLAND_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, + RECT *visible_rect, struct window_surface **surface) DECLSPEC_HIDDEN;
#endif /* __WINE_WAYLANDDRV_H */ diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 2a7bed9d1d8..3ef03e16d0b 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -32,8 +32,10 @@ static const struct user_driver_funcs waylanddrv_funcs = { .pDesktopWindowProc = WAYLAND_DesktopWindowProc, + .pDestroyWindow = WAYLAND_DestroyWindow, .pUpdateDisplayDevices = WAYLAND_UpdateDisplayDevices, - .pWindowMessage = WAYLAND_WindowMessage + .pWindowMessage = WAYLAND_WindowMessage, + .pWindowPosChanging = WAYLAND_WindowPosChanging };
static NTSTATUS waylanddrv_unix_init(void *arg) diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index ea5ac22a8a2..23add167abd 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -28,8 +28,128 @@
#include "wine/debug.h"
+#include <stdlib.h> + WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
+/* private window data */ +struct wayland_win_data +{ + /* hwnd that this private data belongs to */ + HWND hwnd; +}; + +static pthread_mutex_t win_data_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct wayland_win_data *win_data_context[32768]; + +static inline int context_idx(HWND hwnd) +{ + return LOWORD(hwnd) >> 1; +} + +/*********************************************************************** + * wayland_win_data_create + * + * Create a data window structure for an existing window. + */ +static struct wayland_win_data *wayland_win_data_create(HWND hwnd) +{ + struct wayland_win_data *data; + HWND parent; + + /* Don't create win data for desktop or HWND_MESSAGE windows. */ + if (!(parent = NtUserGetAncestor(hwnd, GA_PARENT))) return NULL; + if (parent != NtUserGetDesktopWindow() && !NtUserGetAncestor(parent, GA_PARENT)) + return NULL; + + if (!(data = calloc(1, sizeof(*data)))) return NULL; + + data->hwnd = hwnd; + + pthread_mutex_lock(&win_data_mutex); + win_data_context[context_idx(hwnd)] = data; + + TRACE("hwnd=%p\n", data->hwnd); + + return data; +} + +/*********************************************************************** + * wayland_win_data_destroy + */ +static void wayland_win_data_destroy(struct wayland_win_data *data) +{ + TRACE("hwnd=%p\n", data->hwnd); + + win_data_context[context_idx(data->hwnd)] = NULL; + + free(data); + + pthread_mutex_unlock(&win_data_mutex); +} + +/*********************************************************************** + * wayland_win_data_get + * + * Lock and return the data structure associated with a window. + */ +static struct wayland_win_data *wayland_win_data_get(HWND hwnd) +{ + struct wayland_win_data *data; + + if (!hwnd) return NULL; + + pthread_mutex_lock(&win_data_mutex); + if ((data = win_data_context[context_idx(hwnd)]) && data->hwnd == hwnd) + return data; + pthread_mutex_unlock(&win_data_mutex); + + return NULL; +} + +/*********************************************************************** + * wayland_win_data_release + * + * Release the data returned by wayland_win_data_get. + */ +static void wayland_win_data_release(struct wayland_win_data *data) +{ + if (data) pthread_mutex_unlock(&win_data_mutex); +} + +/*********************************************************************** + * WAYLAND_DestroyWindow + */ +void WAYLAND_DestroyWindow(HWND hwnd) +{ + struct wayland_win_data *data; + + TRACE("%p\n", hwnd); + + if (!(data = wayland_win_data_get(hwnd))) return; + wayland_win_data_destroy(data); +} + +/*********************************************************************** + * WAYLAND_WindowPosChanging + */ +BOOL WAYLAND_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, + RECT *visible_rect, struct window_surface **surface) +{ + struct wayland_win_data *data = wayland_win_data_get(hwnd); + + TRACE("hwnd %p window %s client %s visible %s after %p flags %08x\n", + hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), + wine_dbgstr_rect(visible_rect), insert_after, swp_flags); + + if (!data && !(data = wayland_win_data_create(hwnd))) return TRUE; + + wayland_win_data_release(data); + + return TRUE; +} + static void wayland_resize_desktop(void) { RECT virtual_rect = NtUserGetVirtualScreenRect();