FreeRDP
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 
30 typedef struct
31 {
32  VideoSurface base;
33  XImage* image;
34 } xfVideoSurface;
35 
36 static 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 
64 static BOOL xfVideoShowSurface(VideoClientContext* video, const VideoSurface* surface,
65  UINT32 destinationWidth, UINT32 destinationHeight)
66 {
67  const xfVideoSurface* xfSurface = (const xfVideoSurface*)surface;
68  xfContext* xfc = NULL;
69  const rdpSettings* settings = NULL;
70 
71  WINPR_ASSERT(video);
72  WINPR_ASSERT(xfSurface);
73 
74  xfc = video->custom;
75  WINPR_ASSERT(xfc);
76 
77  settings = xfc->common.context.settings;
78  WINPR_ASSERT(settings);
79 
80 #ifdef WITH_XRENDER
81 
82  if (freerdp_settings_get_bool(settings, FreeRDP_SmartSizing) ||
83  freerdp_settings_get_bool(settings, FreeRDP_MultiTouchGestures))
84  {
85  XPutImage(xfc->display, xfc->primary, xfc->gc, xfSurface->image, 0, 0,
86  WINPR_ASSERTING_INT_CAST(int, surface->x),
87  WINPR_ASSERTING_INT_CAST(int, surface->y), surface->w, surface->h);
88  xf_draw_screen(xfc, WINPR_ASSERTING_INT_CAST(int32_t, surface->x),
89  WINPR_ASSERTING_INT_CAST(int32_t, surface->y),
90  WINPR_ASSERTING_INT_CAST(int32_t, surface->w),
91  WINPR_ASSERTING_INT_CAST(int32_t, surface->h));
92  }
93  else
94 #endif
95  {
96  XPutImage(xfc->display, xfc->drawable, xfc->gc, xfSurface->image, 0, 0,
97  WINPR_ASSERTING_INT_CAST(int, surface->x),
98  WINPR_ASSERTING_INT_CAST(int, surface->y), surface->w, surface->h);
99  }
100 
101  return TRUE;
102 }
103 
104 static BOOL xfVideoDeleteSurface(VideoClientContext* video, VideoSurface* surface)
105 {
106  xfVideoSurface* xfSurface = (xfVideoSurface*)surface;
107 
108  WINPR_UNUSED(video);
109 
110  if (xfSurface)
111  XFree(xfSurface->image);
112 
113  VideoClient_DestroyCommonContext(surface);
114  return TRUE;
115 }
116 
117 void xf_video_control_init(xfContext* xfc, VideoClientContext* video)
118 {
119  WINPR_ASSERT(xfc);
120  WINPR_ASSERT(video);
121 
122  gdi_video_control_init(xfc->common.context.gdi, video);
123 
124  /* X11 needs to be able to handle 32bpp colors directly. */
125  if (xfc->depth >= 24)
126  {
127  video->custom = xfc;
128  video->createSurface = xfVideoCreateSurface;
129  video->showSurface = xfVideoShowSurface;
130  video->deleteSurface = xfVideoDeleteSurface;
131  }
132 }
133 
134 void xf_video_control_uninit(xfContext* xfc, VideoClientContext* video)
135 {
136  WINPR_ASSERT(xfc);
137  gdi_video_control_uninit(xfc->common.context.gdi, video);
138 }
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
Definition: client/video.h:36