1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * Session Shadowing
4  *
5  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef FREERDP_SERVER_SHADOW_H
21 #define FREERDP_SERVER_SHADOW_H
22 
23 #include <freerdp/api.h>
24 #include <freerdp/types.h>
25 
26 #include <freerdp/settings.h>
27 #include <freerdp/listener.h>
28 
29 #include <freerdp/channels/wtsvc.h>
30 #include <freerdp/channels/channels.h>
31 
32 #include <freerdp/server/encomsp.h>
33 #include <freerdp/server/remdesk.h>
34 #include <freerdp/server/rdpsnd.h>
35 #include <freerdp/server/audin.h>
36 #include <freerdp/server/rdpgfx.h>
37 
38 #include <freerdp/codec/color.h>
39 #include <freerdp/codec/region.h>
40 
41 #include <winpr/crt.h>
42 #include <winpr/synch.h>
43 #include <winpr/collections.h>
44 
45 typedef struct rdp_shadow_client rdpShadowClient;
46 typedef struct rdp_shadow_server rdpShadowServer;
47 typedef struct rdp_shadow_screen rdpShadowScreen;
48 typedef struct rdp_shadow_surface rdpShadowSurface;
49 typedef struct rdp_shadow_encoder rdpShadowEncoder;
50 typedef struct rdp_shadow_capture rdpShadowCapture;
51 typedef struct rdp_shadow_subsystem rdpShadowSubsystem;
52 typedef struct rdp_shadow_multiclient_event rdpShadowMultiClientEvent;
53 
54 typedef struct _RDP_SHADOW_ENTRY_POINTS RDP_SHADOW_ENTRY_POINTS;
55 typedef int (*pfnShadowSubsystemEntry)(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
56 
57 typedef rdpShadowSubsystem* (*pfnShadowSubsystemNew)(void);
58 typedef void (*pfnShadowSubsystemFree)(rdpShadowSubsystem* subsystem);
59 
60 typedef int (*pfnShadowSubsystemInit)(rdpShadowSubsystem* subsystem);
61 typedef int (*pfnShadowSubsystemUninit)(rdpShadowSubsystem* subsystem);
62 
63 typedef int (*pfnShadowSubsystemStart)(rdpShadowSubsystem* subsystem);
64 typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem);
65 
66 typedef UINT32 (*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, UINT32 maxMonitors);
67 
68 typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
69                                      const char* user, const char* domain, const char* password);
70 typedef BOOL (*pfnShadowClientConnect)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
71 typedef void (*pfnShadowClientDisconnect)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
72 typedef BOOL (*pfnShadowClientCapabilities)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
73 
74 typedef BOOL (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
75                                           UINT32 flags);
76 typedef BOOL (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
77                                        UINT16 flags, UINT16 code);
78 typedef BOOL (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem,
79                                               rdpShadowClient* client, UINT16 flags, UINT16 code);
80 typedef BOOL (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
81                                     UINT16 flags, UINT16 x, UINT16 y);
82 typedef BOOL (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
83                                             UINT16 flags, UINT16 x, UINT16 y);
84 
85 typedef BOOL (*pfnShadowChannelAudinServerReceiveSamples)(rdpShadowSubsystem* subsystem,
86                                                           rdpShadowClient* client,
87                                                           const AUDIO_FORMAT* format, wStream* buf,
88                                                           size_t nframes);
89 
90 struct rdp_shadow_client
91 {
92 	rdpContext context;
93 
94 	HANDLE thread;
95 	BOOL activated;
96 	BOOL inLobby;
97 	BOOL mayView;
98 	BOOL mayInteract;
99 	BOOL suppressOutput;
100 	wMessageQueue* MsgQueue;
101 	CRITICAL_SECTION lock;
102 	REGION16 invalidRegion;
103 	rdpShadowServer* server;
104 	rdpShadowEncoder* encoder;
105 	rdpShadowSubsystem* subsystem;
106 
107 	UINT32 pointerX;
108 	UINT32 pointerY;
109 
110 	HANDLE vcm;
111 	EncomspServerContext* encomsp;
112 	RemdeskServerContext* remdesk;
113 	RdpsndServerContext* rdpsnd;
114 	audin_server_context* audin;
115 	RdpgfxServerContext* rdpgfx;
116 };
117 
118 struct rdp_shadow_server
119 {
120 	void* ext;
121 	HANDLE thread;
122 	HANDLE StopEvent;
123 	wArrayList* clients;
124 	rdpSettings* settings;
125 	rdpShadowScreen* screen;
126 	rdpShadowSurface* surface;
127 	rdpShadowSurface* lobby;
128 	rdpShadowCapture* capture;
129 	rdpShadowSubsystem* subsystem;
130 
131 	DWORD port;
132 	BOOL mayView;
133 	BOOL mayInteract;
134 	BOOL shareSubRect;
135 	BOOL authentication;
136 	int selectedMonitor;
137 	RECTANGLE_16 subRect;
138 
139 	/* Codec settings */
140 	RLGR_MODE rfxMode;
141 	H264_RATECONTROL_MODE h264RateControlMode;
142 	UINT32 h264BitRate;
143 	FLOAT h264FrameRate;
144 	UINT32 h264QP;
145 
146 	char* ipcSocket;
147 	char* ConfigPath;
148 	char* CertificateFile;
149 	char* PrivateKeyFile;
150 	CRITICAL_SECTION lock;
151 	freerdp_listener* listener;
152 };
153 
154 struct rdp_shadow_surface
155 {
156 	rdpShadowServer* server;
157 
158 	int x;
159 	int y;
160 	int width;
161 	int height;
162 	int scanline;
163 	DWORD format;
164 	BYTE* data;
165 
166 	CRITICAL_SECTION lock;
167 	REGION16 invalidRegion;
168 };
169 
170 struct _RDP_SHADOW_ENTRY_POINTS
171 {
172 	pfnShadowSubsystemNew New;
173 	pfnShadowSubsystemFree Free;
174 
175 	pfnShadowSubsystemInit Init;
176 	pfnShadowSubsystemUninit Uninit;
177 
178 	pfnShadowSubsystemStart Start;
179 	pfnShadowSubsystemStop Stop;
180 
181 	pfnShadowEnumMonitors EnumMonitors;
182 };
183 
184 struct rdp_shadow_subsystem
185 {
186 	RDP_SHADOW_ENTRY_POINTS ep;
187 	HANDLE event;
188 	int numMonitors;
189 	int captureFrameRate;
190 	int selectedMonitor;
191 	MONITOR_DEF monitors[16];
192 	MONITOR_DEF virtualScreen;
193 
194 	/* This event indicates that we have graphic change */
195 	/* such as screen update and resize. It should not be */
196 	/* used by subsystem implementation directly */
197 	rdpShadowMultiClientEvent* updateEvent;
198 
199 	wMessagePipe* MsgPipe;
200 	UINT32 pointerX;
201 	UINT32 pointerY;
202 
203 	AUDIO_FORMAT* rdpsndFormats;
204 	size_t nRdpsndFormats;
205 	AUDIO_FORMAT* audinFormats;
206 	size_t nAudinFormats;
207 
208 	pfnShadowSynchronizeEvent SynchronizeEvent;
209 	pfnShadowKeyboardEvent KeyboardEvent;
210 	pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent;
211 	pfnShadowMouseEvent MouseEvent;
212 	pfnShadowExtendedMouseEvent ExtendedMouseEvent;
213 	pfnShadowChannelAudinServerReceiveSamples AudinServerReceiveSamples;
214 
215 	pfnShadowAuthenticate Authenticate;
216 	pfnShadowClientConnect ClientConnect;
217 	pfnShadowClientDisconnect ClientDisconnect;
218 	pfnShadowClientCapabilities ClientCapabilities;
219 
220 	rdpShadowServer* server;
221 };
222 
223 /* Definition of message between subsystem and clients */
224 #define SHADOW_MSG_IN_REFRESH_REQUEST_ID 1001
225 
226 typedef struct _SHADOW_MSG_OUT SHADOW_MSG_OUT;
227 typedef void (*MSG_OUT_FREE_FN)(UINT32 id,
228                                 SHADOW_MSG_OUT* msg); /* function to free SHADOW_MSG_OUT */
229 
230 struct _SHADOW_MSG_OUT
231 {
232 	int refCount;
233 	MSG_OUT_FREE_FN Free;
234 };
235 
236 #define SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID 2001
237 #define SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE_ID 2002
238 #define SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES_ID 2003
239 #define SHADOW_MSG_OUT_AUDIO_OUT_VOLUME_ID 2004
240 
241 struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
242 {
243 	SHADOW_MSG_OUT common;
244 	UINT32 xPos;
245 	UINT32 yPos;
246 };
247 typedef struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
248 
249 struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
250 {
251 	SHADOW_MSG_OUT common;
252 	UINT32 xHot;
253 	UINT32 yHot;
254 	UINT32 width;
255 	UINT32 height;
256 	UINT32 lengthAndMask;
257 	UINT32 lengthXorMask;
258 	BYTE* xorMaskData;
259 	BYTE* andMaskData;
260 };
261 typedef struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
262 
263 struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
264 {
265 	SHADOW_MSG_OUT common;
266 	AUDIO_FORMAT* audio_format;
267 	void* buf;
268 	int nFrames;
269 	UINT16 wTimestamp;
270 };
271 typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
272 
273 struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME
274 {
275 	SHADOW_MSG_OUT common;
276 	int left;
277 	int right;
278 };
279 typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME SHADOW_MSG_OUT_AUDIO_OUT_VOLUME;
280 
281 #ifdef __cplusplus
282 extern "C"
283 {
284 #endif
285 
286 	FREERDP_API void shadow_subsystem_set_entry_builtin(const char* name);
287 	FREERDP_API void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry);
288 
289 	FREERDP_API int shadow_subsystem_pointer_convert_alpha_pointer_data(
290 	    BYTE* pixels, BOOL premultiplied, UINT32 width, UINT32 height,
291 	    SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor);
292 
293 	FREERDP_API int shadow_server_parse_command_line(rdpShadowServer* server, int argc,
294 	                                                 char** argv);
295 	FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server, int argc,
296 	                                                        char** argv, int status);
297 
298 	FREERDP_API int shadow_server_start(rdpShadowServer* server);
299 	FREERDP_API int shadow_server_stop(rdpShadowServer* server);
300 
301 	FREERDP_API int shadow_server_init(rdpShadowServer* server);
302 	FREERDP_API int shadow_server_uninit(rdpShadowServer* server);
303 
304 	FREERDP_API UINT32 shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors);
305 
306 	FREERDP_API rdpShadowServer* shadow_server_new(void);
307 	FREERDP_API void shadow_server_free(rdpShadowServer* server);
308 
309 	FREERDP_API int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip);
310 	FREERDP_API int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth,
311 	                                       UINT32 nHeight, BYTE* pData2, UINT32 nStep2,
312 	                                       RECTANGLE_16* rect);
313 
314 	FREERDP_API void shadow_subsystem_frame_update(rdpShadowSubsystem* subsystem);
315 
316 	FREERDP_API BOOL shadow_client_post_msg(rdpShadowClient* client, void* context, UINT32 type,
317 	                                        SHADOW_MSG_OUT* msg, void* lParam);
318 	FREERDP_API int shadow_client_boardcast_msg(rdpShadowServer* server, void* context, UINT32 type,
319 	                                            SHADOW_MSG_OUT* msg, void* lParam);
320 	FREERDP_API int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitCode);
321 
322 	FREERDP_API int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder);
323 	FREERDP_API UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder);
324 
325 	FREERDP_API BOOL shadow_screen_resize(rdpShadowScreen* screen);
326 
327 #ifdef __cplusplus
328 }
329 #endif
330 
331 #endif /* FREERDP_SERVER_SHADOW_H */
332