mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 16:45:48 +00:00
winewayland.drv: Introduce window_surface for Wayland.
This commit is contained in:
parent
a7ec328fa8
commit
d53cb7206d
|
@ -12,5 +12,6 @@ SOURCES = \
|
|||
wayland_surface.c \
|
||||
waylanddrv_main.c \
|
||||
window.c \
|
||||
window_surface.c \
|
||||
xdg-output-unstable-v1.xml \
|
||||
xdg-shell.xml
|
||||
|
|
|
@ -126,6 +126,12 @@ void wayland_surface_destroy(struct wayland_surface *surface) DECLSPEC_HIDDEN;
|
|||
void wayland_surface_make_toplevel(struct wayland_surface *surface) DECLSPEC_HIDDEN;
|
||||
void wayland_surface_clear_role(struct wayland_surface *surface) DECLSPEC_HIDDEN;
|
||||
|
||||
/**********************************************************************
|
||||
* Wayland window surface
|
||||
*/
|
||||
|
||||
struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect) DECLSPEC_HIDDEN;
|
||||
|
||||
/**********************************************************************
|
||||
* USER driver functions
|
||||
*/
|
||||
|
|
|
@ -41,6 +41,8 @@ struct wayland_win_data
|
|||
HWND hwnd;
|
||||
/* wayland surface (if any) for this window */
|
||||
struct wayland_surface *wayland_surface;
|
||||
/* wine window_surface backing this window */
|
||||
struct window_surface *window_surface;
|
||||
};
|
||||
|
||||
static int wayland_win_data_cmp_rb(const void *key,
|
||||
|
@ -105,6 +107,7 @@ static void wayland_win_data_destroy(struct wayland_win_data *data)
|
|||
|
||||
pthread_mutex_unlock(&win_data_mutex);
|
||||
|
||||
if (data->window_surface) window_surface_release(data->window_surface);
|
||||
if (data->wayland_surface) wayland_surface_destroy(data->wayland_surface);
|
||||
free(data);
|
||||
}
|
||||
|
@ -201,6 +204,9 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags,
|
|||
RECT *visible_rect, struct window_surface **surface)
|
||||
{
|
||||
struct wayland_win_data *data = wayland_win_data_get(hwnd);
|
||||
HWND parent;
|
||||
BOOL visible;
|
||||
RECT surface_rect;
|
||||
|
||||
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),
|
||||
|
@ -208,8 +214,35 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags,
|
|||
|
||||
if (!data && !(data = wayland_win_data_create(hwnd))) return TRUE;
|
||||
|
||||
wayland_win_data_release(data);
|
||||
/* Release the dummy surface wine provides for toplevels. */
|
||||
if (*surface) window_surface_release(*surface);
|
||||
*surface = NULL;
|
||||
|
||||
parent = NtUserGetAncestor(hwnd, GA_PARENT);
|
||||
visible = ((NtUserGetWindowLongW(hwnd, GWL_STYLE) & WS_VISIBLE) ||
|
||||
(swp_flags & SWP_SHOWWINDOW)) &&
|
||||
!(swp_flags & SWP_HIDEWINDOW);
|
||||
|
||||
/* Check if we don't want a dedicated window surface. */
|
||||
if ((parent && parent != NtUserGetDesktopWindow()) || !visible) goto done;
|
||||
|
||||
surface_rect = *window_rect;
|
||||
OffsetRect(&surface_rect, -surface_rect.left, -surface_rect.top);
|
||||
|
||||
/* Check if we can reuse our current window surface. */
|
||||
if (data->window_surface &&
|
||||
EqualRect(&data->window_surface->rect, &surface_rect))
|
||||
{
|
||||
window_surface_add_ref(data->window_surface);
|
||||
*surface = data->window_surface;
|
||||
TRACE("reusing surface %p\n", *surface);
|
||||
goto done;
|
||||
}
|
||||
|
||||
*surface = wayland_window_surface_create(data->hwnd, &surface_rect);
|
||||
|
||||
done:
|
||||
wayland_win_data_release(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -229,6 +262,10 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
|
|||
|
||||
if (!data) return;
|
||||
|
||||
if (surface) window_surface_add_ref(surface);
|
||||
if (data->window_surface) window_surface_release(data->window_surface);
|
||||
data->window_surface = surface;
|
||||
|
||||
wayland_win_data_update_wayland_surface(data);
|
||||
|
||||
wayland_win_data_release(data);
|
||||
|
|
184
dlls/winewayland.drv/window_surface.c
Normal file
184
dlls/winewayland.drv/window_surface.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Wayland window surface implementation
|
||||
*
|
||||
* Copyright 2020 Alexandros Frantzis for Collabora Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "waylanddrv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
|
||||
|
||||
struct wayland_window_surface
|
||||
{
|
||||
struct window_surface header;
|
||||
HWND hwnd;
|
||||
RECT bounds;
|
||||
void *bits;
|
||||
pthread_mutex_t mutex;
|
||||
BITMAPINFO info;
|
||||
};
|
||||
|
||||
static struct wayland_window_surface *wayland_window_surface_cast(
|
||||
struct window_surface *window_surface)
|
||||
{
|
||||
return (struct wayland_window_surface *)window_surface;
|
||||
}
|
||||
|
||||
static inline void reset_bounds(RECT *bounds)
|
||||
{
|
||||
bounds->left = bounds->top = INT_MAX;
|
||||
bounds->right = bounds->bottom = INT_MIN;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_lock
|
||||
*/
|
||||
static void wayland_window_surface_lock(struct window_surface *window_surface)
|
||||
{
|
||||
struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface);
|
||||
pthread_mutex_lock(&wws->mutex);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_unlock
|
||||
*/
|
||||
static void wayland_window_surface_unlock(struct window_surface *window_surface)
|
||||
{
|
||||
struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface);
|
||||
pthread_mutex_unlock(&wws->mutex);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_get_bitmap_info
|
||||
*/
|
||||
static void *wayland_window_surface_get_bitmap_info(struct window_surface *window_surface,
|
||||
BITMAPINFO *info)
|
||||
{
|
||||
struct wayland_window_surface *surface = wayland_window_surface_cast(window_surface);
|
||||
/* We don't store any additional information at the end of our BITMAPINFO, so
|
||||
* just copy the structure itself. */
|
||||
memcpy(info, &surface->info, sizeof(*info));
|
||||
return surface->bits;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_get_bounds
|
||||
*/
|
||||
static RECT *wayland_window_surface_get_bounds(struct window_surface *window_surface)
|
||||
{
|
||||
struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface);
|
||||
return &wws->bounds;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_set_region
|
||||
*/
|
||||
static void wayland_window_surface_set_region(struct window_surface *window_surface,
|
||||
HRGN region)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_flush
|
||||
*/
|
||||
static void wayland_window_surface_flush(struct window_surface *window_surface)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_destroy
|
||||
*/
|
||||
static void wayland_window_surface_destroy(struct window_surface *window_surface)
|
||||
{
|
||||
struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface);
|
||||
|
||||
TRACE("surface=%p\n", wws);
|
||||
|
||||
pthread_mutex_destroy(&wws->mutex);
|
||||
free(wws->bits);
|
||||
free(wws);
|
||||
}
|
||||
|
||||
static const struct window_surface_funcs wayland_window_surface_funcs =
|
||||
{
|
||||
wayland_window_surface_lock,
|
||||
wayland_window_surface_unlock,
|
||||
wayland_window_surface_get_bitmap_info,
|
||||
wayland_window_surface_get_bounds,
|
||||
wayland_window_surface_set_region,
|
||||
wayland_window_surface_flush,
|
||||
wayland_window_surface_destroy
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_create
|
||||
*/
|
||||
struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect)
|
||||
{
|
||||
struct wayland_window_surface *wws;
|
||||
int width = rect->right - rect->left;
|
||||
int height = rect->bottom - rect->top;
|
||||
pthread_mutexattr_t mutexattr;
|
||||
|
||||
TRACE("hwnd %p rect %s\n", hwnd, wine_dbgstr_rect(rect));
|
||||
|
||||
wws = calloc(1, sizeof(*wws));
|
||||
if (!wws) return NULL;
|
||||
wws->info.bmiHeader.biSize = sizeof(wws->info.bmiHeader);
|
||||
wws->info.bmiHeader.biClrUsed = 0;
|
||||
wws->info.bmiHeader.biBitCount = 32;
|
||||
wws->info.bmiHeader.biCompression = BI_RGB;
|
||||
wws->info.bmiHeader.biWidth = width;
|
||||
wws->info.bmiHeader.biHeight = -height; /* top-down */
|
||||
wws->info.bmiHeader.biPlanes = 1;
|
||||
wws->info.bmiHeader.biSizeImage = width * height * 4;
|
||||
|
||||
pthread_mutexattr_init(&mutexattr);
|
||||
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&wws->mutex, &mutexattr);
|
||||
pthread_mutexattr_destroy(&mutexattr);
|
||||
|
||||
wws->header.funcs = &wayland_window_surface_funcs;
|
||||
wws->header.rect = *rect;
|
||||
wws->header.ref = 1;
|
||||
wws->hwnd = hwnd;
|
||||
reset_bounds(&wws->bounds);
|
||||
|
||||
if (!(wws->bits = malloc(wws->info.bmiHeader.biSizeImage)))
|
||||
goto failed;
|
||||
|
||||
TRACE("created %p hwnd %p %s bits [%p,%p)\n", wws, hwnd, wine_dbgstr_rect(rect),
|
||||
wws->bits, (char *)wws->bits + wws->info.bmiHeader.biSizeImage);
|
||||
|
||||
return &wws->header;
|
||||
|
||||
failed:
|
||||
wayland_window_surface_destroy(&wws->header);
|
||||
return NULL;
|
||||
}
|
Loading…
Reference in a new issue