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>
30 void gdi_video_geometry_init(rdpGdi* gdi, GeometryClientContext* geom)
39 VideoClientContext* video = gdi->video;
42 WINPR_ASSERT(video->setGeometry);
43 video->setGeometry(video, gdi->geometry);
47 void gdi_video_geometry_uninit(rdpGdi* gdi, GeometryClientContext* geom)
55 static VideoSurface* gdiVideoCreateSurface(VideoClientContext* video, UINT32 x, UINT32 y,
56 UINT32 width, UINT32 height)
58 return VideoClient_CreateCommonContext(
sizeof(
VideoSurface), x, y, width, height);
61 static BOOL gdiVideoShowSurface(VideoClientContext* video,
const VideoSurface* surface,
62 UINT32 destinationWidth, UINT32 destinationHeight)
66 rdpUpdate* update = NULL;
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 gdi_InvalidateRegion(gdi->primary->hdc, (INT32)nXDst, (INT32)nYDst, (INT32)width,
116 if (!update_end_paint(update))
122 static BOOL gdiVideoDeleteSurface(VideoClientContext* video,
VideoSurface* surface)
125 VideoClient_DestroyCommonContext(surface);
129 void gdi_video_control_init(rdpGdi* gdi, VideoClientContext* video)
136 video->createSurface = gdiVideoCreateSurface;
137 video->showSurface = gdiVideoShowSurface;
138 video->deleteSurface = gdiVideoDeleteSurface;
139 video->setGeometry(video, gdi->geometry);
142 void gdi_video_control_uninit(rdpGdi* gdi, VideoClientContext* video)
148 static void gdi_video_timer(
void* context,
const TimerEventArgs* timer)
150 rdpContext* ctx = (rdpContext*)context;
158 if (gdi && gdi->video)
159 gdi->video->timer(gdi->video, timer->now);
162 void gdi_video_data_init(rdpGdi* gdi, VideoClientContext* video)
165 WINPR_ASSERT(gdi->context);
166 PubSub_SubscribeTimer(gdi->context->pubSub, gdi_video_timer);
169 void gdi_video_data_uninit(rdpGdi* gdi, VideoClientContext* context)
172 WINPR_ASSERT(gdi->context);
173 PubSub_UnsubscribeTimer(gdi->context->pubSub, gdi_video_timer);
176 VideoSurface* VideoClient_CreateCommonContext(
size_t size, UINT32 x, UINT32 y, UINT32 w, UINT32 h)
182 ret = calloc(1, size);
186 ret->format = PIXEL_FORMAT_BGRX32;
191 ret->alignedWidth = ret->w + 32 - ret->w % 16;
192 ret->alignedHeight = ret->h + 32 - ret->h % 16;
194 ret->scanline = ret->alignedWidth * FreeRDPGetBytesPerPixel(ret->format);
195 ret->data = winpr_aligned_malloc(1ull * ret->scanline * ret->alignedHeight, 64);
200 VideoClient_DestroyCommonContext(ret);
204 void VideoClient_DestroyCommonContext(
VideoSurface* surface)
208 winpr_aligned_free(surface->data);
an implementation of surface used by the video channel