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