20#include "../core/update.h"
22#include <winpr/assert.h>
24#include <freerdp/client/geometry.h>
25#include <freerdp/client/video.h>
26#include <freerdp/gdi/gdi.h>
27#include <freerdp/gdi/video.h>
28#include <freerdp/gdi/region.h>
30void gdi_video_geometry_init(rdpGdi* gdi, GeometryClientContext* geom)
39 VideoClientContext* video = gdi->video;
42 WINPR_ASSERT(video->setGeometry);
43 video->setGeometry(video, gdi->geometry);
47void gdi_video_geometry_uninit(rdpGdi* gdi, GeometryClientContext* geom)
55static VideoSurface* gdiVideoCreateSurface(WINPR_ATTR_UNUSED VideoClientContext* video, UINT32 x,
56 UINT32 y, UINT32 width, UINT32 height)
58 return VideoClient_CreateCommonContext(
sizeof(
VideoSurface), x, y, width, height);
61static BOOL gdiVideoShowSurface(VideoClientContext* video,
const VideoSurface* surface,
62 UINT32 destinationWidth, UINT32 destinationHeight)
65 rdpGdi* gdi =
nullptr;
66 rdpUpdate* update =
nullptr;
69 WINPR_ASSERT(surface);
71 gdi = (rdpGdi*)video->custom;
73 WINPR_ASSERT(gdi->context);
75 update = gdi->context->update;
78 if (!update_begin_paint(update))
81 if ((gdi->width < 0) || (gdi->height < 0))
85 const UINT32 nXSrc = surface->x;
86 const UINT32 nYSrc = surface->y;
87 const UINT32 nXDst = nXSrc;
88 const UINT32 nYDst = nYSrc;
89 const UINT32 width = (destinationWidth + surface->x < (UINT32)gdi->width)
91 : (UINT32)gdi->width - surface->x;
92 const UINT32 height = (destinationHeight + surface->y < (UINT32)gdi->height)
94 : (UINT32)gdi->height - surface->y;
96 WINPR_ASSERT(gdi->primary_buffer);
97 WINPR_ASSERT(gdi->primary);
98 WINPR_ASSERT(gdi->primary->hdc);
100 if (!freerdp_image_scale(gdi->primary_buffer, gdi->primary->hdc->format, gdi->stride, nXDst,
101 nYDst, width, height, surface->data, surface->format,
102 surface->scanline, 0, 0, surface->w, surface->h))
105 if ((nXDst > INT32_MAX) || (nYDst > INT32_MAX) || (width > INT32_MAX) ||
106 (height > INT32_MAX))
109 rc = gdi_InvalidateRegion(gdi->primary->hdc, (INT32)nXDst, (INT32)nYDst, (INT32)width,
114 if (!update_end_paint(update))
120static BOOL gdiVideoDeleteSurface(VideoClientContext* video,
VideoSurface* surface)
123 VideoClient_DestroyCommonContext(surface);
127void gdi_video_control_init(rdpGdi* gdi, VideoClientContext* video)
134 video->createSurface = gdiVideoCreateSurface;
135 video->showSurface = gdiVideoShowSurface;
136 video->deleteSurface = gdiVideoDeleteSurface;
137 video->setGeometry(video, gdi->geometry);
140void gdi_video_control_uninit(rdpGdi* gdi, WINPR_ATTR_UNUSED VideoClientContext* video)
143 gdi->video =
nullptr;
146void gdi_video_data_init(WINPR_ATTR_UNUSED rdpGdi* gdi, WINPR_ATTR_UNUSED VideoClientContext* video)
149 WINPR_ASSERT(gdi->context);
152void gdi_video_data_uninit(WINPR_ATTR_UNUSED rdpGdi* gdi,
153 WINPR_ATTR_UNUSED VideoClientContext* context)
156 WINPR_ASSERT(gdi->context);
159VideoSurface* VideoClient_CreateCommonContext(
size_t size, UINT32 x, UINT32 y, UINT32 w, UINT32 h)
165 ret = calloc(1, size);
169 ret->format = PIXEL_FORMAT_BGRX32;
174 ret->alignedWidth = ret->w + 32 - ret->w % 16;
175 ret->alignedHeight = ret->h + 32 - ret->h % 16;
177 ret->scanline = ret->alignedWidth * FreeRDPGetBytesPerPixel(ret->format);
178 ret->data = winpr_aligned_malloc(1ull * ret->scanline * ret->alignedHeight, 64);
183 VideoClient_DestroyCommonContext(ret);
187void VideoClient_DestroyCommonContext(
VideoSurface* surface)
191 winpr_aligned_free(surface->data);
an implementation of surface used by the video channel