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