[rail] Added window update from surface

This commit is contained in:
Armin Novak 2022-11-08 09:33:02 +01:00 committed by akallabeth
parent 325c03501e
commit 697e020abd
5 changed files with 141 additions and 14 deletions

View File

@ -807,6 +807,8 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, const XConfigureEvent* even
appWindow->width = event->width;
appWindow->height = event->height;
xf_AppWindowResize(xfc, appWindow);
/*
* Additional checks for not in a local move and not ignoring configure to send
* position update to server, also should the window not be focused then do not

View File

@ -431,8 +431,8 @@ static UINT xf_UpdateWindowFromSurface(RdpgfxClientContext* context, gdiGfxSurfa
xfContext* xfc = (xfContext*)gdi->context;
WINPR_ASSERT(gdi->context);
// if (freerdp_settings_get_bool(gdi->context->settings, FreeRDP_RemoteApplicationMode))
// return xf_AppUpdateWindowFromSurface(xfc, surface);
if (freerdp_settings_get_bool(gdi->context->settings, FreeRDP_RemoteApplicationMode))
return xf_AppUpdateWindowFromSurface(xfc, surface);
WLog_WARN(TAG, "[%s] function not implemented", __func__);
return CHANNEL_RC_OK;

View File

@ -1131,13 +1131,15 @@ xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, U
appWindow->y = y;
appWindow->width = width;
appWindow->height = height;
xf_AppWindowCreate(xfc, appWindow);
if (!xf_AppWindowCreate(xfc, appWindow))
goto fail;
if (!HashTable_Insert(xfc->railWindows, &appWindow->windowId, (void*)appWindow))
{
rail_window_free(appWindow);
return NULL;
}
goto fail;
return appWindow;
fail:
rail_window_free(appWindow);
return NULL;
}
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id)

View File

@ -51,6 +51,7 @@
#include "xf_input.h"
#endif
#include "xf_gfx.h"
#include "xf_rail.h"
#include "xf_input.h"
#include "xf_keyboard.h"
@ -783,7 +784,7 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
return 1;
}
int xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow)
BOOL xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow)
{
XGCValues gcv = { 0 };
int input_mask;
@ -815,9 +816,13 @@ int xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow)
xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs);
if (!appWindow->handle)
return -1;
return FALSE;
appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures, &gcv);
if (!xf_AppWindowResize(xfc, appWindow))
return FALSE;
class_hints = XAllocClassHint();
if (class_hints)
@ -859,7 +864,7 @@ int xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow)
if (xfc->_XWAYLAND_MAY_GRAB_KEYBOARD)
xf_SendClientEvent(xfc, appWindow->handle, xfc->_XWAYLAND_MAY_GRAB_KEYBOARD, 1, 1);
return 1;
return TRUE;
}
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, int maxWidth, int maxHeight,
@ -1111,16 +1116,27 @@ void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, i
if (settings->SoftwareGdi)
{
XPutImage(xfc->display, xfc->primary, appWindow->gc, xfc->image, ax, ay, ax, ay, width,
XPutImage(xfc->display, appWindow->pixmap, appWindow->gc, xfc->image, ax, ay, x, y, width,
height);
}
XCopyArea(xfc->display, xfc->primary, appWindow->handle, appWindow->gc, ax, ay, width, height,
x, y);
XCopyArea(xfc->display, appWindow->pixmap, appWindow->handle, appWindow->gc, x, y, width,
height, x, y);
XFlush(xfc->display);
xf_unlock_x11(xfc);
}
static void xf_AppWindowDestroyImage(xfAppWindow* appWindow)
{
WINPR_ASSERT(appWindow);
if (appWindow->image)
{
appWindow->image->data = NULL;
XDestroyImage(appWindow->image);
appWindow->image = NULL;
}
}
void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
{
if (!appWindow)
@ -1132,6 +1148,11 @@ void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
if (appWindow->gc)
XFreeGC(xfc->display, appWindow->gc);
if (appWindow->pixmap)
XFreePixmap(xfc->display, appWindow->pixmap);
xf_AppWindowDestroyImage(appWindow);
if (appWindow->handle)
{
XUnmapWindow(xfc->display, appWindow->handle);
@ -1185,3 +1206,96 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
free(pKeys);
return NULL;
}
UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface)
{
XImage* image = NULL;
UINT rc = ERROR_INTERNAL_ERROR;
WINPR_ASSERT(xfc);
WINPR_ASSERT(surface);
xfAppWindow* appWindow = xf_rail_get_window(xfc, surface->windowId);
if (!appWindow)
{
WLog_VRB(TAG, "[%s] Failed to find a window for id=0x%08" PRIx64, __func__,
surface->windowId);
return CHANNEL_RC_OK;
}
const BOOL swGdi = freerdp_settings_get_bool(xfc->common.context.settings, FreeRDP_SoftwareGdi);
UINT32 nrects = 0;
const RECTANGLE_16* rects = region16_rects(&surface->invalidRegion, &nrects);
xf_lock_x11(xfc);
if (swGdi)
{
if (appWindow->surfaceId != surface->surfaceId)
{
xf_AppWindowDestroyImage(appWindow);
appWindow->surfaceId = surface->surfaceId;
}
if (appWindow->width != (INT64)surface->width)
xf_AppWindowDestroyImage(appWindow);
if (appWindow->height != (INT64)surface->height)
xf_AppWindowDestroyImage(appWindow);
if (!appWindow->image)
{
appWindow->image =
XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, surface->data,
surface->width, surface->height, xfc->scanline_pad, surface->scanline);
if (!appWindow->image)
{
WLog_WARN(TAG,
"[%s] Failed create a XImage[%" PRIu32 "x%" PRIu32 ", scanline=%" PRIu32
", bpp=%" PRIu32 "] for window id=0x%08" PRIx64,
__func__, surface->width, surface->height, surface->scanline, xfc->depth,
surface->windowId);
goto fail;
}
appWindow->image->byte_order = LSBFirst;
appWindow->image->bitmap_bit_order = LSBFirst;
}
image = appWindow->image;
}
else
{
xfGfxSurface* xfSurface = (xfGfxSurface*)surface;
image = xfSurface->image;
}
for (UINT32 x = 0; x < nrects; x++)
{
const RECTANGLE_16* rect = &rects[x];
const UINT32 width = rect->right - rect->left;
const UINT32 height = rect->bottom - rect->top;
XPutImage(xfc->display, appWindow->pixmap, appWindow->gc, image, rect->left, rect->top,
rect->left, rect->top, width, height);
XCopyArea(xfc->display, appWindow->pixmap, appWindow->handle, appWindow->gc, rect->left,
rect->top, width, height, rect->left, rect->top);
}
rc = CHANNEL_RC_OK;
fail:
XFlush(xfc->display);
xf_unlock_x11(xfc);
return rc;
}
BOOL xf_AppWindowResize(xfContext* xfc, xfAppWindow* appWindow)
{
WINPR_ASSERT(xfc);
WINPR_ASSERT(appWindow);
if (appWindow->pixmap != 0)
XFreePixmap(xfc->display, appWindow->pixmap);
appWindow->pixmap =
XCreatePixmap(xfc->display, xfc->drawable, appWindow->width, appWindow->height, xfc->depth);
xf_AppWindowDestroyImage(appWindow);
return appWindow->pixmap != 0;
}

View File

@ -23,6 +23,7 @@
#include <X11/Xlib.h>
#include <freerdp/freerdp.h>
#include <freerdp/gdi/gfx.h>
typedef struct xf_app_window xfAppWindow;
@ -155,6 +156,9 @@ struct xf_app_window
BOOL maxHorz;
BOOL minimized;
BOOL rail_ignore_configure;
Pixmap pixmap;
XImage* image;
};
void xf_ewmhints_init(xfContext* xfc);
@ -178,8 +182,11 @@ BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int leng
unsigned long* nitems, unsigned long* bytes, BYTE** prop);
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...);
int xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow);
BOOL xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow);
int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow);
BOOL xf_AppWindowResize(xfContext* xfc, xfAppWindow* appWindow);
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, const char* name);
void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height);
void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state);
@ -190,6 +197,8 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32
void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style);
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width,
int height);
UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface);
void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow);
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, int maxWidth, int maxHeight,
int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight,