FreeRDP
Loading...
Searching...
No Matches
xf_video.c
1
20#include <winpr/assert.h>
21#include <freerdp/client/geometry.h>
22#include <freerdp/client/video.h>
23#include <freerdp/gdi/video.h>
24
25#include "xf_video.h"
26
27#include <freerdp/log.h>
28#define TAG CLIENT_TAG("video")
29
30typedef struct
31{
32 VideoSurface base;
33 XImage* image;
34} xfVideoSurface;
35
36static VideoSurface* xfVideoCreateSurface(VideoClientContext* video, UINT32 x, UINT32 y,
37 UINT32 width, UINT32 height)
38{
39 xfContext* xfc = NULL;
40 xfVideoSurface* ret = NULL;
41
42 WINPR_ASSERT(video);
43 ret = (xfVideoSurface*)VideoClient_CreateCommonContext(sizeof(xfContext), x, y, width, height);
44 if (!ret)
45 return NULL;
46
47 xfc = (xfContext*)video->custom;
48 WINPR_ASSERT(xfc);
49
50 ret->image = XCreateImage(
51 xfc->display, xfc->visual, WINPR_ASSERTING_INT_CAST(uint32_t, xfc->depth), ZPixmap, 0,
52 (char*)ret->base.data, width, height, 8, WINPR_ASSERTING_INT_CAST(int, ret->base.scanline));
53
54 if (!ret->image)
55 {
56 WLog_ERR(TAG, "unable to create surface image");
57 VideoClient_DestroyCommonContext(&ret->base);
58 return NULL;
59 }
60
61 return &ret->base;
62}
63
64static BOOL xfVideoShowSurface(VideoClientContext* video, const VideoSurface* surface,
65 WINPR_ATTR_UNUSED UINT32 destinationWidth,
66 WINPR_ATTR_UNUSED UINT32 destinationHeight)
67{
68 const xfVideoSurface* xfSurface = (const xfVideoSurface*)surface;
69 xfContext* xfc = NULL;
70 const rdpSettings* settings = NULL;
71
72 WINPR_ASSERT(video);
73 WINPR_ASSERT(xfSurface);
74
75 xfc = video->custom;
76 WINPR_ASSERT(xfc);
77
78 settings = xfc->common.context.settings;
79 WINPR_ASSERT(settings);
80
81#ifdef WITH_XRENDER
82
83 if (freerdp_settings_get_bool(settings, FreeRDP_SmartSizing) ||
84 freerdp_settings_get_bool(settings, FreeRDP_MultiTouchGestures))
85 {
86 XPutImage(xfc->display, xfc->primary, xfc->gc, xfSurface->image, 0, 0,
87 WINPR_ASSERTING_INT_CAST(int, surface->x),
88 WINPR_ASSERTING_INT_CAST(int, surface->y), surface->w, surface->h);
89 xf_draw_screen(xfc, WINPR_ASSERTING_INT_CAST(int32_t, surface->x),
90 WINPR_ASSERTING_INT_CAST(int32_t, surface->y),
91 WINPR_ASSERTING_INT_CAST(int32_t, surface->w),
92 WINPR_ASSERTING_INT_CAST(int32_t, surface->h));
93 }
94 else
95#endif
96 {
97 XPutImage(xfc->display, xfc->drawable, xfc->gc, xfSurface->image, 0, 0,
98 WINPR_ASSERTING_INT_CAST(int, surface->x),
99 WINPR_ASSERTING_INT_CAST(int, surface->y), surface->w, surface->h);
100 }
101
102 return TRUE;
103}
104
105static BOOL xfVideoDeleteSurface(VideoClientContext* video, VideoSurface* surface)
106{
107 xfVideoSurface* xfSurface = (xfVideoSurface*)surface;
108
109 WINPR_UNUSED(video);
110
111 if (xfSurface)
112 XFree(xfSurface->image);
113
114 VideoClient_DestroyCommonContext(surface);
115 return TRUE;
116}
117
118void xf_video_control_init(xfContext* xfc, VideoClientContext* video)
119{
120 WINPR_ASSERT(xfc);
121 WINPR_ASSERT(video);
122
123 gdi_video_control_init(xfc->common.context.gdi, video);
124
125 /* X11 needs to be able to handle 32bpp colors directly. */
126 if (xfc->depth >= 24)
127 {
128 video->custom = xfc;
129 video->createSurface = xfVideoCreateSurface;
130 video->showSurface = xfVideoShowSurface;
131 video->deleteSurface = xfVideoDeleteSurface;
132 }
133}
134
135void xf_video_control_uninit(xfContext* xfc, VideoClientContext* video)
136{
137 WINPR_ASSERT(xfc);
138 gdi_video_control_uninit(xfc->common.context.gdi, video);
139}
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
an implementation of surface used by the video channel