mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
@@ -2086,7 +2086,8 @@ static BOOL freerdp_client_touch_update(rdpClientContext* cctx, UINT32 flags, IN
|
||||
BOOL freerdp_client_handle_touch(rdpClientContext* cctx, UINT32 flags, INT32 finger,
|
||||
UINT32 pressure, INT32 x, INT32 y)
|
||||
{
|
||||
const UINT32 mask = FREERDP_TOUCH_DOWN | FREERDP_TOUCH_UP | FREERDP_TOUCH_MOTION;
|
||||
const UINT32 mask =
|
||||
FREERDP_TOUCH_DOWN | FREERDP_TOUCH_UP | FREERDP_TOUCH_MOTION | FREERDP_TOUCH_CANCEL;
|
||||
WINPR_ASSERT(cctx);
|
||||
|
||||
FreeRDP_TouchContact contact = { 0 };
|
||||
|
||||
@@ -813,9 +813,6 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
|
||||
if (!context || !format || !sdata || !out || !context->common.encoder)
|
||||
return FALSE;
|
||||
|
||||
if (!context || !sdata || !out)
|
||||
return FALSE;
|
||||
|
||||
/* https://github.com/FreeRDP/FreeRDP/issues/7607
|
||||
*
|
||||
* we get noisy data with channel transformation, so do it ourselves.
|
||||
|
||||
@@ -376,12 +376,10 @@ static BOOL gdi_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, INT32 x,
|
||||
static BOOL gdi_Glyph_BeginDraw(rdpContext* context, INT32 x, INT32 y, INT32 width, INT32 height,
|
||||
UINT32 bgcolor, UINT32 fgcolor, BOOL fOpRedundant)
|
||||
{
|
||||
rdpGdi* gdi = NULL;
|
||||
|
||||
if (!context || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
gdi = context->gdi;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
if (!gdi->drawing || !gdi->drawing->hdc)
|
||||
return FALSE;
|
||||
@@ -394,11 +392,12 @@ static BOOL gdi_Glyph_BeginDraw(rdpContext* context, INT32 x, INT32 y, INT32 wid
|
||||
if (!gdi_decode_color(gdi, fgcolor, &fgcolor, NULL))
|
||||
return FALSE;
|
||||
|
||||
gdi_SetClipRgn(gdi->drawing->hdc, x, y, width, height);
|
||||
if (!gdi_SetClipRgn(gdi->drawing->hdc, x, y, width, height))
|
||||
return FALSE;
|
||||
|
||||
gdi_SetTextColor(gdi->drawing->hdc, bgcolor);
|
||||
gdi_SetBkColor(gdi->drawing->hdc, fgcolor);
|
||||
|
||||
if (1)
|
||||
{
|
||||
GDI_RECT rect = { 0 };
|
||||
HGDI_BRUSH brush = gdi_CreateSolidBrush(fgcolor);
|
||||
@@ -415,13 +414,13 @@ static BOOL gdi_Glyph_BeginDraw(rdpContext* context, INT32 x, INT32 y, INT32 wid
|
||||
rect.right = x + width - 1;
|
||||
rect.bottom = y + height - 1;
|
||||
|
||||
BOOL res = TRUE;
|
||||
if ((x + width > rect.left) && (y + height > rect.top))
|
||||
{
|
||||
if (!gdi_FillRect(gdi->drawing->hdc, &rect, brush))
|
||||
return FALSE;
|
||||
}
|
||||
res = gdi_FillRect(gdi->drawing->hdc, &rect, brush);
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)brush);
|
||||
if (!res)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gdi_SetNullClipRgn(gdi->drawing->hdc);
|
||||
|
||||
@@ -134,15 +134,11 @@ BOOL gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int n
|
||||
|
||||
BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
{
|
||||
UINT32 color = 0;
|
||||
UINT32 dstColor = 0;
|
||||
BOOL monochrome = FALSE;
|
||||
INT32 nXDest = 0;
|
||||
INT32 nYDest = 0;
|
||||
INT32 nWidth = 0;
|
||||
INT32 nHeight = 0;
|
||||
const BYTE* srcp = NULL;
|
||||
DWORD formatSize = 0;
|
||||
|
||||
if (!gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight))
|
||||
return FALSE;
|
||||
|
||||
@@ -155,7 +151,8 @@ BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
switch (hbr->style)
|
||||
{
|
||||
case GDI_BS_SOLID:
|
||||
color = hbr->color;
|
||||
{
|
||||
const UINT32 color = hbr->color;
|
||||
|
||||
for (INT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
@@ -165,21 +162,28 @@ BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
FreeRDPWriteColor(dstp, hdc->format, color);
|
||||
}
|
||||
|
||||
srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
|
||||
formatSize = FreeRDPGetBytesPerPixel(hdc->format);
|
||||
const BYTE* srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
|
||||
const UINT32 formatSize = FreeRDPGetBytesPerPixel(hdc->format);
|
||||
if (formatSize == 0)
|
||||
return FALSE;
|
||||
|
||||
for (INT32 y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
||||
if (!dstp)
|
||||
return FALSE;
|
||||
memcpy(dstp, srcp, 1ull * WINPR_ASSERTING_INT_CAST(size_t, nWidth) * formatSize);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GDI_BS_HATCHED:
|
||||
case GDI_BS_PATTERN:
|
||||
monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
|
||||
formatSize = FreeRDPGetBytesPerPixel(hbr->pattern->format);
|
||||
{
|
||||
const BOOL monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
|
||||
const UINT32 formatSize = FreeRDPGetBytesPerPixel(hbr->pattern->format);
|
||||
if (formatSize == 0)
|
||||
return FALSE;
|
||||
|
||||
for (INT32 y = 0; y < nHeight; y++)
|
||||
{
|
||||
@@ -197,6 +201,7 @@ BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
formatSize;
|
||||
const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
|
||||
|
||||
UINT32 dstColor = 0;
|
||||
if (monochrome)
|
||||
{
|
||||
if (*patp == 0)
|
||||
@@ -206,9 +211,9 @@ BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
}
|
||||
else
|
||||
{
|
||||
dstColor = FreeRDPReadColor(patp, hbr->pattern->format);
|
||||
const UINT32 tmp = FreeRDPReadColor(patp, hbr->pattern->format);
|
||||
dstColor =
|
||||
FreeRDPConvertColor(dstColor, hbr->pattern->format, hdc->format, NULL);
|
||||
FreeRDPConvertColor(tmp, hbr->pattern->format, hdc->format, NULL);
|
||||
}
|
||||
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest + y);
|
||||
@@ -216,8 +221,8 @@ BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
FreeRDPWriteColor(dstp, hdc->format, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -792,37 +792,28 @@ static int x11_shadow_error_handler_for_capture(Display* display, XErrorEvent* e
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
static int x11_shadow_screen_grab_locked(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
int rc = 0;
|
||||
size_t count = 0;
|
||||
int status = -1;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
XImage* image = NULL;
|
||||
rdpShadowServer* server = NULL;
|
||||
rdpShadowSurface* surface = NULL;
|
||||
RECTANGLE_16 invalidRect;
|
||||
RECTANGLE_16 surfaceRect;
|
||||
RECTANGLE_16 invalidRect = { 0 };
|
||||
RECTANGLE_16 surfaceRect = { 0 };
|
||||
const RECTANGLE_16* extents = NULL;
|
||||
server = subsystem->common.server;
|
||||
surface = server->surface;
|
||||
count = ArrayList_Count(server->clients);
|
||||
rdpShadowServer* server = subsystem->common.server;
|
||||
rdpShadowSurface* surface = server->surface;
|
||||
size_t count = ArrayList_Count(server->clients);
|
||||
|
||||
if (count < 1)
|
||||
return 1;
|
||||
|
||||
EnterCriticalSection(&surface->lock);
|
||||
surfaceRect.left = 0;
|
||||
surfaceRect.top = 0;
|
||||
|
||||
surfaceRect.right = WINPR_ASSERTING_INT_CAST(UINT16, surface->width);
|
||||
surfaceRect.bottom = WINPR_ASSERTING_INT_CAST(UINT16, surface->height);
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
|
||||
XLockDisplay(subsystem->display);
|
||||
/*
|
||||
* Ignore BadMatch error during image capture. The screen size may be
|
||||
* changed outside. We will resize to correct resolution at next frame
|
||||
@@ -835,17 +826,14 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
|
||||
subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);
|
||||
|
||||
EnterCriticalSection(&surface->lock);
|
||||
status = shadow_capture_compare_with_format(
|
||||
surface->data, surface->format, surface->scanline, surface->width, surface->height,
|
||||
(BYTE*)&(image->data[surface->width * 4ull]), subsystem->format,
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, image->bytes_per_line), &invalidRect);
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
EnterCriticalSection(&surface->lock);
|
||||
image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y,
|
||||
surface->width, surface->height, AllPlanes, ZPixmap);
|
||||
|
||||
@@ -856,7 +844,7 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
(BYTE*)image->data, subsystem->format,
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, image->bytes_per_line), &invalidRect);
|
||||
}
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
|
||||
if (!image)
|
||||
{
|
||||
/*
|
||||
@@ -870,12 +858,10 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
/* Restore the default error handler */
|
||||
XSetErrorHandler(NULL);
|
||||
XSync(subsystem->display, False);
|
||||
XUnlockDisplay(subsystem->display);
|
||||
|
||||
if (status)
|
||||
{
|
||||
BOOL empty = 0;
|
||||
EnterCriticalSection(&surface->lock);
|
||||
if (!region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&invalidRect))
|
||||
goto fail_capture;
|
||||
@@ -883,12 +869,10 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
&surfaceRect))
|
||||
goto fail_capture;
|
||||
empty = region16_is_empty(&(surface->invalidRegion));
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
|
||||
if (!empty)
|
||||
{
|
||||
BOOL success = 0;
|
||||
EnterCriticalSection(&surface->lock);
|
||||
extents = region16_extents(&(surface->invalidRegion));
|
||||
x = extents->left;
|
||||
y = extents->top;
|
||||
@@ -906,7 +890,6 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
WINPR_ASSERTING_INT_CAST(uint32_t, image->bytes_per_line),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, x), WINPR_ASSERTING_INT_CAST(UINT32, y), NULL,
|
||||
FREERDP_FLIP_NONE);
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
if (!success)
|
||||
goto fail_capture;
|
||||
|
||||
@@ -927,9 +910,7 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
shadow_encoder_preferred_fps(client->encoder);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&surface->lock);
|
||||
region16_clear(&(surface->invalidRegion));
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -942,12 +923,28 @@ fail_capture:
|
||||
{
|
||||
XSetErrorHandler(NULL);
|
||||
XSync(subsystem->display, False);
|
||||
XUnlockDisplay(subsystem->display);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
WINPR_ASSERT(subsystem);
|
||||
rdpShadowServer* server = subsystem->common.server;
|
||||
WINPR_ASSERT(server);
|
||||
|
||||
rdpShadowSurface* surface = server->surface;
|
||||
WINPR_ASSERT(surface);
|
||||
|
||||
EnterCriticalSection(&surface->lock);
|
||||
XLockDisplay(subsystem->display);
|
||||
const int rc = x11_shadow_screen_grab_locked(subsystem);
|
||||
XUnlockDisplay(subsystem->display);
|
||||
LeaveCriticalSection(&surface->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int x11_shadow_subsystem_process_message(x11ShadowSubsystem* subsystem, wMessage* message)
|
||||
{
|
||||
switch (message->id)
|
||||
|
||||
@@ -1908,12 +1908,16 @@ static BOOL shadow_client_send_surface_update(rdpShadowClient* client, SHADOW_GF
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
|
||||
EnterCriticalSection(&(client->lock));
|
||||
region16_init(&invalidRegion);
|
||||
if (!region16_copy(&invalidRegion, &(client->invalidRegion)))
|
||||
goto out;
|
||||
region16_clear(&(client->invalidRegion));
|
||||
LeaveCriticalSection(&(client->lock));
|
||||
{
|
||||
EnterCriticalSection(&(client->lock));
|
||||
region16_init(&invalidRegion);
|
||||
|
||||
const BOOL res = region16_copy(&invalidRegion, &(client->invalidRegion));
|
||||
region16_clear(&(client->invalidRegion));
|
||||
LeaveCriticalSection(&(client->lock));
|
||||
if (!res)
|
||||
goto out;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&surface->lock);
|
||||
rects = region16_rects(&(surface->invalidRegion), &numRects);
|
||||
|
||||
Reference in New Issue
Block a user