xwayland/present: Add xwl_present_maybe_(un)redirect_window
A later commit will use these to (un)redirect the surface window on demand. Not used yet, so no functional change intended. v2: * Use "surface_window_damage" instead of "surf_win_damage". (Olivier Fourdan) * Slightly simplify logic in xwl_unrealize_window. v3: * Add comment in xwl_present_maybe_unredirect_window explaining why we use a timer. (Olivier Fourdan) v4: * Rename unredir_timer field to unredirect_timer. Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1300>
This commit is contained in:
parent
fa7b1c20c4
commit
fca63f8fb8
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <compint.h>
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
#include <glamor.h>
|
||||
#endif
|
||||
|
@ -484,6 +485,7 @@ xwl_present_cleanup(WindowPtr window)
|
|||
|
||||
/* Clear timer */
|
||||
xwl_present_free_timer(xwl_present_window);
|
||||
TimerFree(xwl_present_window->unredirect_timer);
|
||||
|
||||
/* Remove from privates so we don't try to access it later */
|
||||
dixSetPrivate(&window->devPrivates,
|
||||
|
@ -1263,6 +1265,67 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
|
|||
xwl_present_reset_timer(xwl_present_window);
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_present_maybe_redirect_window(WindowPtr window, PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
|
||||
struct xwl_window *xwl_window = xwl_window_from_window(window);
|
||||
|
||||
if (xwl_present_window->redirect_failed)
|
||||
return FALSE;
|
||||
|
||||
if (compRedirectWindow(serverClient, window, CompositeRedirectManual) != Success) {
|
||||
xwl_present_window->redirect_failed = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xwl_window_update_surface_window(xwl_window);
|
||||
if (xwl_window->surface_window != window) {
|
||||
compUnredirectWindow(serverClient, window, CompositeRedirectManual);
|
||||
xwl_present_window->redirect_failed = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!xwl_window->surface_window_damage)
|
||||
xwl_window->surface_window_damage = RegionCreate(NullBox, 1);
|
||||
|
||||
xwl_present_window->redirected = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static CARD32
|
||||
unredirect_window(OsTimerPtr timer, CARD32 time, void *arg)
|
||||
{
|
||||
WindowPtr window = arg;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
|
||||
|
||||
compUnredirectWindow(serverClient, window, CompositeRedirectManual);
|
||||
xwl_present_window->redirected = FALSE;
|
||||
|
||||
xwl_present_window->unredirect_timer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_present_maybe_unredirect_window(WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
|
||||
|
||||
if (!xwl_present_window || !xwl_present_window->redirected)
|
||||
return FALSE;
|
||||
|
||||
/* This function may get called from composite layer code, in which case
|
||||
* calling compUnredirectWindow would blow up. To avoid this, set up a timer
|
||||
* which will call it "as soon as possible".
|
||||
*/
|
||||
if (!xwl_present_window->unredirect_timer) {
|
||||
xwl_present_window->unredirect_timer =
|
||||
TimerSet(NULL, 0, 1, unredirect_window, window);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_present_init(ScreenPtr screen)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,10 @@ struct xwl_present_window {
|
|||
|
||||
present_vblank_ptr flip_active;
|
||||
uint64_t blocking_event;
|
||||
|
||||
OsTimerPtr unredirect_timer;
|
||||
Bool redirected;
|
||||
Bool redirect_failed;
|
||||
};
|
||||
|
||||
struct xwl_present_event {
|
||||
|
@ -77,5 +81,7 @@ void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
|
|||
Bool xwl_present_init(ScreenPtr screen);
|
||||
void xwl_present_cleanup(WindowPtr window);
|
||||
void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window);
|
||||
Bool xwl_present_maybe_redirect_window(WindowPtr window, PixmapPtr pixmap);
|
||||
Bool xwl_present_maybe_unredirect_window(WindowPtr window);
|
||||
|
||||
#endif /* XWAYLAND_PRESENT_H */
|
||||
|
|
|
@ -1221,7 +1221,7 @@ err_surf:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
xwl_window_update_surface_window(struct xwl_window *xwl_window)
|
||||
{
|
||||
WindowPtr surface_window = xwl_window->toplevel;
|
||||
|
@ -1512,6 +1512,8 @@ xwl_unrealize_window(WindowPtr window)
|
|||
|
||||
xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
xwl_window = xwl_window_get(window);
|
||||
if (xwl_window)
|
||||
compUnredirectWindow(serverClient, window, CompositeRedirectManual);
|
||||
|
||||
screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
|
||||
|
@ -1519,7 +1521,6 @@ xwl_unrealize_window(WindowPtr window)
|
|||
xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
|
||||
screen->UnrealizeWindow = xwl_unrealize_window;
|
||||
|
||||
xwl_window = xwl_window_get(window);
|
||||
if (!xwl_window)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ struct xwl_window {
|
|||
* can also be used for the X dimensions of the Wayland surface though.
|
||||
*/
|
||||
WindowPtr surface_window;
|
||||
RegionPtr surface_window_damage;
|
||||
|
||||
struct xorg_list link_damage;
|
||||
struct xorg_list link_window;
|
||||
|
@ -121,6 +122,7 @@ void xwl_window_rootful_update_title(struct xwl_window *xwl_window);
|
|||
void xwl_window_rootful_update_fullscreen(struct xwl_window *xwl_window,
|
||||
struct xwl_output *xwl_output);
|
||||
void xwl_window_set_window_pixmap(WindowPtr window, PixmapPtr pixmap);
|
||||
void xwl_window_update_surface_window(struct xwl_window *xwl_window);
|
||||
|
||||
void xwl_window_leave_output(struct xwl_window *xwl_window,
|
||||
struct xwl_output *xwl_output);
|
||||
|
|
Loading…
Reference in New Issue