mirror of https://github.com/FreeRDP/FreeRDP
Fixed shadow server color encoding.
This commit is contained in:
parent
f5fff7658a
commit
9ab04711fa
|
@ -65,19 +65,30 @@ typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem);
|
|||
|
||||
typedef int (*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, int maxMonitors);
|
||||
|
||||
typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
|
||||
const char* user, const char* domain, const char* password);
|
||||
typedef BOOL (*pfnShadowClientConnect)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
|
||||
typedef void (*pfnShadowClientDisconnect)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
|
||||
typedef BOOL (*pfnShadowClientCapabilities)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
|
||||
typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client,
|
||||
const char* user, const char* domain, const char* password);
|
||||
typedef BOOL (*pfnShadowClientConnect)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client);
|
||||
typedef void (*pfnShadowClientDisconnect)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client);
|
||||
typedef BOOL (*pfnShadowClientCapabilities)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client);
|
||||
|
||||
typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client, UINT32 flags);
|
||||
typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 code);
|
||||
typedef int (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 code);
|
||||
typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
|
||||
typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
|
||||
typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT32 flags);
|
||||
typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 code);
|
||||
typedef int (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 code);
|
||||
typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
|
||||
typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
|
||||
|
||||
typedef void (*pfnShadowChannelAudinServerReceiveSamples)(rdpShadowSubsystem* subsystem, rdpShadowClient* client, const void* buf, int nframes);
|
||||
typedef void (*pfnShadowChannelAudinServerReceiveSamples)(
|
||||
rdpShadowSubsystem* subsystem, rdpShadowClient* client, const void* buf,
|
||||
int nframes);
|
||||
|
||||
struct rdp_shadow_client
|
||||
{
|
||||
|
@ -152,6 +163,7 @@ struct rdp_shadow_surface
|
|||
int width;
|
||||
int height;
|
||||
int scanline;
|
||||
DWORD format;
|
||||
BYTE* data;
|
||||
|
||||
CRITICAL_SECTION lock;
|
||||
|
@ -218,7 +230,8 @@ struct rdp_shadow_subsystem
|
|||
#define SHADOW_MSG_IN_REFRESH_REQUEST_ID 1001
|
||||
|
||||
typedef struct _SHADOW_MSG_OUT SHADOW_MSG_OUT;
|
||||
typedef void (*MSG_OUT_FREE_FN)(UINT32 id, SHADOW_MSG_OUT* msg); /* function to free SHADOW_MSG_OUT */
|
||||
typedef void (*MSG_OUT_FREE_FN)(UINT32 id,
|
||||
SHADOW_MSG_OUT* msg); /* function to free SHADOW_MSG_OUT */
|
||||
#define RDP_SHADOW_MSG_OUT_COMMON() \
|
||||
int refCount; \
|
||||
MSG_OUT_FREE_FN Free
|
||||
|
@ -239,7 +252,8 @@ struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
|
|||
UINT32 xPos;
|
||||
UINT32 yPos;
|
||||
};
|
||||
typedef struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
|
||||
typedef struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
|
||||
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
|
||||
|
||||
struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
||||
{
|
||||
|
@ -253,7 +267,8 @@ struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
|||
BYTE* xorMaskData;
|
||||
BYTE* andMaskData;
|
||||
};
|
||||
typedef struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
|
||||
typedef struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
||||
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
|
||||
|
||||
struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
|
||||
{
|
||||
|
@ -263,7 +278,8 @@ struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
|
|||
int nFrames;
|
||||
UINT16 wTimestamp;
|
||||
};
|
||||
typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
|
||||
typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
|
||||
SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
|
||||
|
||||
struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME
|
||||
{
|
||||
|
@ -280,11 +296,14 @@ extern "C" {
|
|||
FREERDP_API void shadow_subsystem_set_entry_builtin(const char* name);
|
||||
FREERDP_API void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry);
|
||||
|
||||
FREERDP_API int shadow_subsystem_pointer_convert_alpha_pointer_data(BYTE* pixels, BOOL premultiplied,
|
||||
UINT32 width, UINT32 height, SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor);
|
||||
FREERDP_API int shadow_subsystem_pointer_convert_alpha_pointer_data(
|
||||
BYTE* pixels, BOOL premultiplied,
|
||||
UINT32 width, UINT32 height, SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor);
|
||||
|
||||
FREERDP_API int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** argv);
|
||||
FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status);
|
||||
FREERDP_API int shadow_server_parse_command_line(rdpShadowServer* server,
|
||||
int argc, char** argv);
|
||||
FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server,
|
||||
int argc, char** argv, int status);
|
||||
|
||||
FREERDP_API int shadow_server_start(rdpShadowServer* server);
|
||||
FREERDP_API int shadow_server_stop(rdpShadowServer* server);
|
||||
|
@ -297,14 +316,19 @@ FREERDP_API int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors);
|
|||
FREERDP_API rdpShadowServer* shadow_server_new();
|
||||
FREERDP_API void shadow_server_free(rdpShadowServer* server);
|
||||
|
||||
FREERDP_API int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip);
|
||||
FREERDP_API int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect);
|
||||
FREERDP_API int shadow_capture_align_clip_rect(RECTANGLE_16* rect,
|
||||
RECTANGLE_16* clip);
|
||||
FREERDP_API int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth,
|
||||
int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect);
|
||||
|
||||
FREERDP_API void shadow_subsystem_frame_update(rdpShadowSubsystem* subsystem);
|
||||
|
||||
FREERDP_API BOOL shadow_client_post_msg(rdpShadowClient* client, void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
|
||||
FREERDP_API int shadow_client_boardcast_msg(rdpShadowServer* server, void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
|
||||
FREERDP_API int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitCode);
|
||||
FREERDP_API BOOL shadow_client_post_msg(rdpShadowClient* client, void* context,
|
||||
UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
|
||||
FREERDP_API int shadow_client_boardcast_msg(rdpShadowServer* server,
|
||||
void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
|
||||
FREERDP_API int shadow_client_boardcast_quit(rdpShadowServer* server,
|
||||
int nExitCode);
|
||||
|
||||
FREERDP_API int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder);
|
||||
FREERDP_API UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder);
|
||||
|
|
|
@ -83,28 +83,28 @@ static void rfx_profiler_create(RFX_CONTEXT* context)
|
|||
{
|
||||
PROFILER_CREATE(context->priv->prof_rfx_decode_rgb, "rfx_decode_rgb");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_decode_component,
|
||||
"rfx_decode_component");
|
||||
"rfx_decode_component");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_rlgr_decode, "rfx_rlgr_decode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_differential_decode,
|
||||
"rfx_differential_decode");
|
||||
"rfx_differential_decode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_quantization_decode,
|
||||
"rfx_quantization_decode");
|
||||
"rfx_quantization_decode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_ycbcr_to_rgb, "prims->yCbCrToRGB");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_decode_format_rgb,
|
||||
"rfx_decode_format_rgb");
|
||||
"rfx_decode_format_rgb");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_encode_component,
|
||||
"rfx_encode_component");
|
||||
"rfx_encode_component");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_rlgr_encode, "rfx_rlgr_encode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_differential_encode,
|
||||
"rfx_differential_encode");
|
||||
"rfx_differential_encode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_quantization_encode,
|
||||
"rfx_quantization_encode");
|
||||
"rfx_quantization_encode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_encode, "rfx_dwt_2d_encode");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_rgb_to_ycbcr, "prims->RGBToYCbCr");
|
||||
PROFILER_CREATE(context->priv->prof_rfx_encode_format_rgb,
|
||||
"rfx_encode_format_rgb");
|
||||
"rfx_encode_format_rgb");
|
||||
}
|
||||
|
||||
static void rfx_profiler_free(RFX_CONTEXT* context)
|
||||
|
@ -275,7 +275,7 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
|
|||
verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
GetVersionExA(&verinfo);
|
||||
isVistaOrLater = ((verinfo.dwMajorVersion >= 6)
|
||||
&& (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE;
|
||||
&& (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE;
|
||||
priv->UseThreads = isVistaOrLater;
|
||||
}
|
||||
#else
|
||||
|
@ -285,22 +285,22 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
|
|||
priv->MinThreadCount = sysinfo.dwNumberOfProcessors;
|
||||
priv->MaxThreadCount = 0;
|
||||
status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, RFX_KEY, 0,
|
||||
KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||
KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
dwSize = sizeof(dwValue);
|
||||
|
||||
if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue,
|
||||
&dwSize) == ERROR_SUCCESS)
|
||||
&dwSize) == ERROR_SUCCESS)
|
||||
priv->UseThreads = dwValue ? 1 : 0;
|
||||
|
||||
if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue,
|
||||
&dwSize) == ERROR_SUCCESS)
|
||||
&dwSize) == ERROR_SUCCESS)
|
||||
priv->MinThreadCount = dwValue;
|
||||
|
||||
if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue,
|
||||
&dwSize) == ERROR_SUCCESS)
|
||||
&dwSize) == ERROR_SUCCESS)
|
||||
priv->MaxThreadCount = dwValue;
|
||||
|
||||
RegCloseKey(hKey);
|
||||
|
@ -378,7 +378,7 @@ void rfx_context_free(RFX_CONTEXT* context)
|
|||
free(priv->tileWorkParams);
|
||||
#ifdef WITH_PROFILER
|
||||
WLog_VRB(TAG,
|
||||
"WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!");
|
||||
"WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -436,7 +436,7 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s)
|
|||
}
|
||||
|
||||
Stream_Read_UINT16(s,
|
||||
context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */
|
||||
context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */
|
||||
|
||||
if (context->version != WF_VERSION_1_0)
|
||||
{
|
||||
|
@ -462,9 +462,9 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s)
|
|||
|
||||
Stream_Read_UINT8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */
|
||||
Stream_Read_UINT8(s,
|
||||
context->codec_id); /* codecId (1 byte), must be set to 0x01 */
|
||||
context->codec_id); /* codecId (1 byte), must be set to 0x01 */
|
||||
Stream_Read_UINT16(s,
|
||||
context->codec_version); /* version (2 bytes), must be set to WF_VERSION_1_0 (0x0100) */
|
||||
context->codec_version); /* version (2 bytes), must be set to WF_VERSION_1_0 (0x0100) */
|
||||
|
||||
if (numCodecs != 1)
|
||||
{
|
||||
|
@ -481,12 +481,12 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s)
|
|||
if (context->codec_version != WF_VERSION_1_0)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: invalid codec version (0x%04X)", __FUNCTION__,
|
||||
context->codec_version);
|
||||
context->codec_version);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG, "id %d version 0x%X.",
|
||||
context->codec_id, context->codec_version);
|
||||
context->codec_id, context->codec_version);
|
||||
context->decodedHeaderBlocks |= _RFX_DECODED_VERSIONS;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
|
|||
}
|
||||
|
||||
Stream_Read_UINT8(s,
|
||||
numChannels); /* numChannels (1 byte), must bet set to 0x01 */
|
||||
numChannels); /* numChannels (1 byte), must bet set to 0x01 */
|
||||
|
||||
/* In RDVH sessions, numChannels will represent the number of virtual monitors
|
||||
* configured and does not always be set to 0x01 as [MS-RDPRFX] said.
|
||||
|
@ -518,7 +518,7 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
|
|||
if (Stream_GetRemainingLength(s) < (size_t)(numChannels * 5))
|
||||
{
|
||||
WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%d",
|
||||
numChannels);
|
||||
numChannels);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -537,14 +537,14 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
|
|||
if (!context->width || !context->height)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: invalid channel with/height: %ux%u", __FUNCTION__,
|
||||
context->width, context->height);
|
||||
context->width, context->height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now, only the first monitor can be used, therefore the other channels will be ignored. */
|
||||
Stream_Seek(s, 5 * (numChannels - 1));
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG, "numChannels %d id %d, %dx%d.",
|
||||
numChannels, channelId, context->width, context->height);
|
||||
numChannels, channelId, context->width, context->height);
|
||||
context->decodedHeaderBlocks |= _RFX_DECODED_CHANNELS;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -564,11 +564,11 @@ static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s)
|
|||
|
||||
Stream_Read_UINT8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */
|
||||
Stream_Read_UINT16(s,
|
||||
tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
|
||||
tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
|
||||
Stream_Read_UINT16(s, properties); /* properties (2 bytes) */
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG,
|
||||
"ctxId %d tileSize %d properties 0x%X.",
|
||||
ctxId, tileSize, properties);
|
||||
"ctxId %d tileSize %d properties 0x%X.",
|
||||
ctxId, tileSize, properties);
|
||||
context->properties = properties;
|
||||
context->flags = (properties & 0x0007);
|
||||
|
||||
|
@ -603,7 +603,7 @@ static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s)
|
|||
}
|
||||
|
||||
static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context,
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
|
||||
{
|
||||
UINT32 frameIdx;
|
||||
UINT16 numRegions;
|
||||
|
@ -623,15 +623,15 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context,
|
|||
}
|
||||
|
||||
Stream_Read_UINT32(s,
|
||||
frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */
|
||||
frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */
|
||||
Stream_Read_UINT16(s, numRegions); /* numRegions (2 bytes) */
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG,
|
||||
"RFX_FRAME_BEGIN: frameIdx: %d numRegions: %d", frameIdx, numRegions);
|
||||
"RFX_FRAME_BEGIN: frameIdx: %d numRegions: %d", frameIdx, numRegions);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL rfx_process_message_frame_end(RFX_CONTEXT* context,
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
|
||||
{
|
||||
if (*pExpectedBlockType != WBT_FRAME_END)
|
||||
{
|
||||
|
@ -645,7 +645,7 @@ static BOOL rfx_process_message_frame_end(RFX_CONTEXT* context,
|
|||
}
|
||||
|
||||
static BOOL rfx_process_message_region(RFX_CONTEXT* context,
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
|
||||
{
|
||||
int i;
|
||||
UINT16 regionType;
|
||||
|
@ -690,7 +690,7 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
|
|||
if (Stream_GetRemainingLength(s) < (size_t)(8 * message->numRects))
|
||||
{
|
||||
WLog_ERR(TAG, "%s: packet too small for num_rects=%d", __FUNCTION__,
|
||||
message->numRects);
|
||||
message->numRects);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -701,15 +701,14 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
|
|||
for (i = 0; i < message->numRects; i++)
|
||||
{
|
||||
RFX_RECT* rect = rfx_message_get_rect(message, i);
|
||||
|
||||
/* RFX_RECT */
|
||||
Stream_Read_UINT16(s, rect->x); /* x (2 bytes) */
|
||||
Stream_Read_UINT16(s, rect->y); /* y (2 bytes) */
|
||||
Stream_Read_UINT16(s, rect->width); /* width (2 bytes) */
|
||||
Stream_Read_UINT16(s, rect->height); /* height (2 bytes) */
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%d,%d w,h=%d %d).", i,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height);
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height);
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
|
@ -719,9 +718,9 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
|
|||
}
|
||||
|
||||
Stream_Read_UINT16(s,
|
||||
regionType); /* regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1) */
|
||||
regionType); /* regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1) */
|
||||
Stream_Read_UINT16(s,
|
||||
numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */
|
||||
numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */
|
||||
|
||||
if (regionType != CBT_REGION)
|
||||
{
|
||||
|
@ -754,7 +753,7 @@ static void CALLBACK rfx_process_message_tile_work_callback(
|
|||
}
|
||||
|
||||
static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType)
|
||||
RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType)
|
||||
{
|
||||
BOOL rc;
|
||||
int i, close_cnt;
|
||||
|
@ -785,7 +784,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
}
|
||||
|
||||
Stream_Read_UINT16(s,
|
||||
subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */
|
||||
subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */
|
||||
|
||||
if (subtype != CBT_TILESET)
|
||||
{
|
||||
|
@ -815,7 +814,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
|
||||
|
||||
if (!(pmem = realloc((void*) context->quants,
|
||||
context->numQuant * 10 * sizeof(UINT32))))
|
||||
context->numQuant * 10 * sizeof(UINT32))))
|
||||
return FALSE;
|
||||
|
||||
quants = context->quants = (UINT32*) pmem;
|
||||
|
@ -824,7 +823,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
if (Stream_GetRemainingLength(s) < (size_t)(context->numQuant * 5))
|
||||
{
|
||||
WLog_ERR(TAG, "RfxMessageTileSet packet too small for num_quants=%d",
|
||||
context->numQuant);
|
||||
context->numQuant);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -847,16 +846,16 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
*quants++ = (quant & 0x0F);
|
||||
*quants++ = (quant >> 4);
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG,
|
||||
"quant %d (%d %d %d %d %d %d %d %d %d %d).",
|
||||
i, context->quants[i * 10], context->quants[i * 10 + 1],
|
||||
context->quants[i * 10 + 2], context->quants[i * 10 + 3],
|
||||
context->quants[i * 10 + 4], context->quants[i * 10 + 5],
|
||||
context->quants[i * 10 + 6], context->quants[i * 10 + 7],
|
||||
context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
|
||||
"quant %d (%d %d %d %d %d %d %d %d %d %d).",
|
||||
i, context->quants[i * 10], context->quants[i * 10 + 1],
|
||||
context->quants[i * 10 + 2], context->quants[i * 10 + 3],
|
||||
context->quants[i * 10 + 4], context->quants[i * 10 + 5],
|
||||
context->quants[i * 10 + 6], context->quants[i * 10 + 7],
|
||||
context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
|
||||
}
|
||||
|
||||
if (!(message->tiles = (RFX_TILE**) calloc(message->numTiles,
|
||||
sizeof(RFX_TILE*))))
|
||||
sizeof(RFX_TILE*))))
|
||||
{
|
||||
message->numTiles = 0;
|
||||
return FALSE;
|
||||
|
@ -866,7 +865,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
{
|
||||
work_objects = (PTP_WORK*) calloc(message->numTiles, sizeof(PTP_WORK));
|
||||
params = (RFX_TILE_PROCESS_WORK_PARAM*) calloc(message->numTiles,
|
||||
sizeof(RFX_TILE_PROCESS_WORK_PARAM));
|
||||
sizeof(RFX_TILE_PROCESS_WORK_PARAM));
|
||||
|
||||
if (!work_objects)
|
||||
{
|
||||
|
@ -900,20 +899,20 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
if (Stream_GetRemainingLength(s) < 6)
|
||||
{
|
||||
WLog_ERR(TAG, "RfxMessageTileSet packet too small to read tile %d/%d", i,
|
||||
message->numTiles);
|
||||
message->numTiles);
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
Stream_Read_UINT16(s,
|
||||
blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
|
||||
blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
|
||||
Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < blockLen - 6)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d",
|
||||
i, message->numTiles, blockLen);
|
||||
"RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d",
|
||||
i, message->numTiles, blockLen);
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -923,7 +922,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
if (blockType != CBT_TILE)
|
||||
{
|
||||
WLog_ERR(TAG, "unknown block type 0x%X, expected CBT_TILE (0xCAC3).",
|
||||
blockType);
|
||||
blockType);
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -952,8 +951,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
params[i].tile = message->tiles[i];
|
||||
|
||||
if (!(work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK)
|
||||
rfx_process_message_tile_work_callback,
|
||||
(void*) ¶ms[i], &context->priv->ThreadPoolEnv)))
|
||||
rfx_process_message_tile_work_callback,
|
||||
(void*) ¶ms[i], &context->priv->ThreadPoolEnv)))
|
||||
{
|
||||
WLog_ERR(TAG, "CreateThreadpoolWork failed.");
|
||||
rc = FALSE;
|
||||
|
@ -996,11 +995,11 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
|
|||
}
|
||||
|
||||
BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
||||
UINT32 format, UINT32 length,
|
||||
UINT32 left, UINT32 top,
|
||||
BYTE* dst, UINT32 dstFormat,
|
||||
UINT32 dstStride, UINT32 dstHeight,
|
||||
REGION16* invalidRegion)
|
||||
UINT32 format, UINT32 length,
|
||||
UINT32 left, UINT32 top,
|
||||
BYTE* dst, UINT32 dstFormat,
|
||||
UINT32 dstStride, UINT32 dstHeight,
|
||||
REGION16* invalidRegion)
|
||||
{
|
||||
int pos;
|
||||
REGION16 updateRegion;
|
||||
|
@ -1028,7 +1027,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */
|
||||
Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG, "blockType 0x%X blockLen %d",
|
||||
blockType, blockLen);
|
||||
blockType, blockLen);
|
||||
|
||||
if (blockLen == 0)
|
||||
{
|
||||
|
@ -1062,7 +1061,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
|
||||
Stream_Read_UINT8(s, codecId); /* codecId (1 byte) must be set to 0x01 */
|
||||
Stream_Read_UINT8(s,
|
||||
channelId); /* channelId (1 byte) 0xFF or 0x00, see below */
|
||||
channelId); /* channelId (1 byte) 0xFF or 0x00, see below */
|
||||
|
||||
if (codecId != 0x01)
|
||||
{
|
||||
|
@ -1076,7 +1075,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
if (channelId != 0xFF)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType 0x%04X", __FUNCTION__,
|
||||
channelId, blockType);
|
||||
channelId, blockType);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -1086,7 +1085,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
if (channelId != 0x00)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType WBT_CONTEXT",
|
||||
__FUNCTION__, channelId);
|
||||
__FUNCTION__, channelId);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -1123,7 +1122,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
|
||||
case WBT_FRAME_BEGIN:
|
||||
ok = rfx_process_message_frame_begin(context, message, s,
|
||||
&expectedDataBlockType);
|
||||
&expectedDataBlockType);
|
||||
break;
|
||||
|
||||
case WBT_REGION:
|
||||
|
@ -1152,7 +1151,6 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
UINT32 nbUpdateRects;
|
||||
REGION16 clippingRects;
|
||||
const RECTANGLE_16* updateRects;
|
||||
|
||||
region16_init(&clippingRects);
|
||||
|
||||
for (i = 0; i < message->numRects; i++)
|
||||
|
@ -1170,7 +1168,6 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
{
|
||||
RECTANGLE_16 updateRect;
|
||||
const RFX_TILE* tile = rfx_message_get_tile(message, i);
|
||||
|
||||
updateRect.left = left + tile->x;
|
||||
updateRect.top = top + tile->y;
|
||||
updateRect.right = updateRect.left + 64;
|
||||
|
@ -1185,9 +1182,10 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
|
|||
UINT32 nYDst = updateRects[j].top;
|
||||
UINT32 nWidth = updateRects[j].right - updateRects[j].left;
|
||||
UINT32 nHeight = updateRects[j].bottom - updateRects[j].top;
|
||||
|
||||
if (!freerdp_image_copy(dst, dstFormat, dstStride,
|
||||
nXDst, nYDst, nWidth, nHeight,
|
||||
tile->data, format, 64 * GetBytesPerPixel(format), 0, 0, NULL))
|
||||
nXDst, nYDst, nWidth, nHeight,
|
||||
tile->data, format, 64 * GetBytesPerPixel(format), 0, 0, NULL))
|
||||
goto fail;
|
||||
|
||||
if (invalidRegion)
|
||||
|
@ -1265,7 +1263,7 @@ static void rfx_update_context_properties(RFX_CONTEXT* context)
|
|||
properties |= (COL_CONV_ICT << 4); /* cct */
|
||||
properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */
|
||||
properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3)
|
||||
<< 10); /* et */
|
||||
<< 10); /* et */
|
||||
properties |= (SCALAR_QUANTIZATION << 14); /* qt */
|
||||
context->properties = properties;
|
||||
}
|
||||
|
@ -1311,7 +1309,7 @@ static void rfx_write_message_context(RFX_CONTEXT* context, wStream* s)
|
|||
properties |= (COL_CONV_ICT << 3); /* cct */
|
||||
properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */
|
||||
properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3)
|
||||
<< 9); /* et */
|
||||
<< 9); /* et */
|
||||
properties |= (SCALAR_QUANTIZATION << 13); /* qt */
|
||||
Stream_Write_UINT16(s, properties); /* properties (2 bytes) */
|
||||
rfx_update_context_properties(context);
|
||||
|
@ -1365,7 +1363,7 @@ struct _RFX_TILE_COMPOSE_WORK_PARAM
|
|||
};
|
||||
|
||||
void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE
|
||||
instance, void* context, PTP_WORK work)
|
||||
instance, void* context, PTP_WORK work)
|
||||
{
|
||||
RFX_TILE_COMPOSE_WORK_PARAM* param = (RFX_TILE_COMPOSE_WORK_PARAM*) context;
|
||||
rfx_encode_rgb(param->context, param->tile);
|
||||
|
@ -1373,7 +1371,7 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE
|
|||
|
||||
|
||||
static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16* region,
|
||||
int width, int height)
|
||||
int width, int height)
|
||||
{
|
||||
int i;
|
||||
const RFX_RECT* rect = rects;
|
||||
|
@ -1410,7 +1408,7 @@ BOOL setupWorkers(RFX_CONTEXT* context, int nbTiles)
|
|||
priv->workObjects = (PTP_WORK*) pmem;
|
||||
|
||||
if (!(pmem = realloc((void*) priv->tileWorkParams,
|
||||
sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles)))
|
||||
sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles)))
|
||||
return FALSE;
|
||||
|
||||
priv->tileWorkParams = (RFX_TILE_COMPOSE_WORK_PARAM*) pmem;
|
||||
|
@ -1418,8 +1416,8 @@ BOOL setupWorkers(RFX_CONTEXT* context, int nbTiles)
|
|||
}
|
||||
|
||||
RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
|
||||
int numRects,
|
||||
BYTE* data, int width, int height, int scanline)
|
||||
int numRects,
|
||||
BYTE* data, int width, int height, int scanline)
|
||||
{
|
||||
UINT32 i, maxNbTiles, maxTilesX, maxTilesY;
|
||||
UINT32 xIdx, yIdx, regionNbRects;
|
||||
|
@ -1455,11 +1453,11 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
|
|||
if (!context->numQuant)
|
||||
{
|
||||
if (!(context->quants = (UINT32*) malloc(sizeof(
|
||||
rfx_default_quantization_values))))
|
||||
rfx_default_quantization_values))))
|
||||
goto skip_encoding_loop;
|
||||
|
||||
CopyMemory(context->quants, &rfx_default_quantization_values,
|
||||
sizeof(rfx_default_quantization_values));
|
||||
sizeof(rfx_default_quantization_values));
|
||||
context->numQuant = 1;
|
||||
context->quantIdxY = 0;
|
||||
context->quantIdxCb = 0;
|
||||
|
@ -1577,9 +1575,9 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
|
|||
workParam->tile = tile;
|
||||
|
||||
if (!(*workObject = CreateThreadpoolWork(
|
||||
(PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback,
|
||||
(void*) workParam,
|
||||
&context->priv->ThreadPoolEnv)))
|
||||
(PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback,
|
||||
(void*) workParam,
|
||||
&context->priv->ThreadPoolEnv)))
|
||||
{
|
||||
goto skip_encoding_loop;
|
||||
}
|
||||
|
@ -1607,7 +1605,7 @@ skip_encoding_loop:
|
|||
if (message->numTiles > 0)
|
||||
{
|
||||
void* pmem = realloc((void*) message->tiles,
|
||||
sizeof(RFX_TILE*) * message->numTiles);
|
||||
sizeof(RFX_TILE*) * message->numTiles);
|
||||
|
||||
if (pmem)
|
||||
message->tiles = (RFX_TILE**) pmem;
|
||||
|
@ -1656,7 +1654,7 @@ skip_encoding_loop:
|
|||
}
|
||||
|
||||
RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message,
|
||||
int* numMessages, int maxDataSize)
|
||||
int* numMessages, int maxDataSize)
|
||||
{
|
||||
int i, j;
|
||||
UINT32 tileDataSize;
|
||||
|
@ -1687,7 +1685,7 @@ RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message,
|
|||
messages[j].freeArray = TRUE;
|
||||
|
||||
if (!(messages[j].tiles = (RFX_TILE**) calloc(message->numTiles,
|
||||
sizeof(RFX_TILE*))))
|
||||
sizeof(RFX_TILE*))))
|
||||
goto free_messages;
|
||||
}
|
||||
|
||||
|
@ -1710,19 +1708,19 @@ free_messages:
|
|||
}
|
||||
|
||||
RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects,
|
||||
int numRects,
|
||||
BYTE* data, int width, int height, int scanline, int* numMessages,
|
||||
int maxDataSize)
|
||||
int numRects,
|
||||
BYTE* data, int width, int height, int scanline, int* numMessages,
|
||||
int maxDataSize)
|
||||
{
|
||||
RFX_MESSAGE* message;
|
||||
RFX_MESSAGE* messageList;
|
||||
|
||||
if (!(message = rfx_encode_message(context, rects, numRects, data, width,
|
||||
height, scanline)))
|
||||
height, scanline)))
|
||||
return NULL;
|
||||
|
||||
if (!(messageList = rfx_split_message(context, message, numMessages,
|
||||
maxDataSize)))
|
||||
maxDataSize)))
|
||||
{
|
||||
message->freeRects = TRUE;
|
||||
rfx_message_free(context, message);
|
||||
|
@ -1734,7 +1732,7 @@ RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects,
|
|||
}
|
||||
|
||||
static BOOL rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s,
|
||||
RFX_MESSAGE* message)
|
||||
RFX_MESSAGE* message)
|
||||
{
|
||||
int i;
|
||||
RFX_TILE* tile;
|
||||
|
@ -1775,14 +1773,14 @@ static BOOL rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s,
|
|||
|
||||
#ifdef WITH_DEBUG_RFX
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG,
|
||||
"numQuant: %d numTiles: %d tilesDataSize: %d",
|
||||
message->numQuant, message->numTiles, message->tilesDataSize);
|
||||
"numQuant: %d numTiles: %d tilesDataSize: %d",
|
||||
message->numQuant, message->numTiles, message->tilesDataSize);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL rfx_write_message_frame_begin(RFX_CONTEXT* context, wStream* s,
|
||||
RFX_MESSAGE* message)
|
||||
RFX_MESSAGE* message)
|
||||
{
|
||||
if (!Stream_EnsureRemainingCapacity(s, 14))
|
||||
return FALSE;
|
||||
|
@ -1797,7 +1795,7 @@ static BOOL rfx_write_message_frame_begin(RFX_CONTEXT* context, wStream* s,
|
|||
}
|
||||
|
||||
static BOOL rfx_write_message_region(RFX_CONTEXT* context, wStream* s,
|
||||
RFX_MESSAGE* message)
|
||||
RFX_MESSAGE* message)
|
||||
{
|
||||
int i;
|
||||
UINT32 blockLen;
|
||||
|
@ -1816,7 +1814,6 @@ static BOOL rfx_write_message_region(RFX_CONTEXT* context, wStream* s,
|
|||
for (i = 0; i < message->numRects; i++)
|
||||
{
|
||||
const RFX_RECT* rect = rfx_message_get_rect(message, i);
|
||||
|
||||
/* Clipping rectangles are relative to destLeft, destTop */
|
||||
Stream_Write_UINT16(s, rect->x); /* x (2 bytes) */
|
||||
Stream_Write_UINT16(s, rect->y); /* y (2 bytes) */
|
||||
|
@ -1830,7 +1827,7 @@ static BOOL rfx_write_message_region(RFX_CONTEXT* context, wStream* s,
|
|||
}
|
||||
|
||||
BOOL rfx_write_message_frame_end(RFX_CONTEXT* context, wStream* s,
|
||||
RFX_MESSAGE* message)
|
||||
RFX_MESSAGE* message)
|
||||
{
|
||||
if (!Stream_EnsureRemainingCapacity(s, 8))
|
||||
return FALSE;
|
||||
|
@ -1864,14 +1861,14 @@ BOOL rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message)
|
|||
}
|
||||
|
||||
BOOL rfx_compose_message(RFX_CONTEXT* context, wStream* s,
|
||||
const RFX_RECT* rects, int numRects, BYTE* data, int width, int height,
|
||||
int scanline)
|
||||
const RFX_RECT* rects, int numRects, BYTE* data, int width, int height,
|
||||
int scanline)
|
||||
{
|
||||
RFX_MESSAGE* message;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (!(message = rfx_encode_message(context, rects, numRects, data, width,
|
||||
height, scanline)))
|
||||
height, scanline)))
|
||||
return FALSE;
|
||||
|
||||
ret = rfx_write_message(context, s, message);
|
||||
|
|
|
@ -35,7 +35,6 @@ static macShadowSubsystem* g_Subsystem = NULL;
|
|||
static void mac_shadow_input_synchronize_event(macShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT32 flags)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
|
||||
|
@ -46,26 +45,24 @@ static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
|
|||
BOOL extended;
|
||||
CGEventRef kbdEvent;
|
||||
CGEventSourceRef source;
|
||||
|
||||
extended = (flags & KBD_FLAGS_EXTENDED) ? TRUE : FALSE;
|
||||
|
||||
|
||||
if (extended)
|
||||
code |= KBDEXT;
|
||||
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4);
|
||||
|
||||
|
||||
if (extended)
|
||||
vkcode |= KBDEXT;
|
||||
|
||||
|
||||
keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_APPLE);
|
||||
|
||||
|
||||
if (keycode < 8)
|
||||
return;
|
||||
|
||||
keycode -= 8;
|
||||
|
||||
keycode -= 8;
|
||||
source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
|
||||
|
||||
if (flags & KBD_FLAGS_DOWN)
|
||||
{
|
||||
kbdEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode) keycode, TRUE);
|
||||
|
@ -78,14 +75,13 @@ static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
|
|||
CGEventPost(kCGHIDEventTap, kbdEvent);
|
||||
CFRelease(kbdEvent);
|
||||
}
|
||||
|
||||
|
||||
CFRelease(source);
|
||||
}
|
||||
|
||||
static void mac_shadow_input_unicode_keyboard_event(macShadowSubsystem*
|
||||
subsystem, rdpShadowClient* client, UINT16 flags, UINT16 code)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
||||
|
@ -94,11 +90,11 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
UINT32 scrollX = 0;
|
||||
UINT32 scrollY = 0;
|
||||
CGWheelCount wheelCount = 2;
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_WHEEL)
|
||||
{
|
||||
scrollY = flags & WheelRotationMask;
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
|
||||
{
|
||||
scrollY = -(flags & WheelRotationMask) / 392;
|
||||
|
@ -107,21 +103,23 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
{
|
||||
scrollY = (flags & WheelRotationMask) / 120;
|
||||
}
|
||||
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGEventRef scroll = CGEventCreateScrollWheelEvent(source, kCGScrollEventUnitLine,
|
||||
wheelCount, scrollY, scrollX);
|
||||
|
||||
CGEventSourceRef source = CGEventSourceCreate(
|
||||
kCGEventSourceStateHIDSystemState);
|
||||
CGEventRef scroll = CGEventCreateScrollWheelEvent(source,
|
||||
kCGScrollEventUnitLine,
|
||||
wheelCount, scrollY, scrollX);
|
||||
CGEventPost(kCGHIDEventTap, scroll);
|
||||
|
||||
CFRelease(scroll);
|
||||
CFRelease(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGEventSourceRef source = CGEventSourceCreate(
|
||||
kCGEventSourceStateHIDSystemState);
|
||||
CGEventType mouseType = kCGEventNull;
|
||||
CGMouseButton mouseButton = kCGMouseButtonLeft;
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_MOVE)
|
||||
{
|
||||
if (subsystem->mouseDownLeft)
|
||||
|
@ -132,16 +130,17 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
mouseType = kCGEventOtherMouseDragged;
|
||||
else
|
||||
mouseType = kCGEventMouseMoved;
|
||||
|
||||
CGEventRef move = CGEventCreateMouseEvent(source, mouseType, CGPointMake(x, y), mouseButton);
|
||||
|
||||
CGEventRef move = CGEventCreateMouseEvent(source, mouseType, CGPointMake(x, y),
|
||||
mouseButton);
|
||||
CGEventPost(kCGHIDEventTap, move);
|
||||
CFRelease(move);
|
||||
}
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_BUTTON1)
|
||||
{
|
||||
mouseButton = kCGMouseButtonLeft;
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_DOWN)
|
||||
{
|
||||
mouseType = kCGEventLeftMouseDown;
|
||||
|
@ -156,7 +155,7 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
else if (flags & PTR_FLAGS_BUTTON2)
|
||||
{
|
||||
mouseButton = kCGMouseButtonRight;
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_DOWN)
|
||||
{
|
||||
mouseType = kCGEventRightMouseDown;
|
||||
|
@ -167,12 +166,11 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
mouseType = kCGEventRightMouseUp;
|
||||
subsystem->mouseDownRight = FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
else if (flags & PTR_FLAGS_BUTTON3)
|
||||
{
|
||||
mouseButton = kCGMouseButtonCenter;
|
||||
|
||||
|
||||
if (flags & PTR_FLAGS_DOWN)
|
||||
{
|
||||
mouseType = kCGEventOtherMouseDown;
|
||||
|
@ -184,10 +182,10 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
subsystem->mouseDownOther = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
CGEventRef mouseEvent = CGEventCreateMouseEvent(source, mouseType, CGPointMake(x, y), mouseButton);
|
||||
|
||||
CGEventRef mouseEvent = CGEventCreateMouseEvent(source, mouseType,
|
||||
CGPointMake(x, y), mouseButton);
|
||||
CGEventPost(kCGHIDEventTap, mouseEvent);
|
||||
|
||||
CFRelease(mouseEvent);
|
||||
CFRelease(source);
|
||||
}
|
||||
|
@ -196,7 +194,6 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
|
|||
static void mac_shadow_input_extended_mouse_event(macShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int mac_shadow_detect_monitors(macShadowSubsystem* subsystem)
|
||||
|
@ -204,21 +201,15 @@ static int mac_shadow_detect_monitors(macShadowSubsystem* subsystem)
|
|||
size_t wide, high;
|
||||
MONITOR_DEF* monitor;
|
||||
CGDirectDisplayID displayId;
|
||||
|
||||
displayId = CGMainDisplayID();
|
||||
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
|
||||
|
||||
subsystem->pixelWidth = CGDisplayModeGetPixelWidth(mode);
|
||||
subsystem->pixelHeight = CGDisplayModeGetPixelHeight(mode);
|
||||
|
||||
wide = CGDisplayPixelsWide(displayId);
|
||||
high = CGDisplayPixelsHigh(displayId);
|
||||
|
||||
CGDisplayModeRelease(mode);
|
||||
|
||||
subsystem->retina = ((subsystem->pixelWidth / wide) == 2) ? TRUE : FALSE;
|
||||
|
||||
|
||||
if (subsystem->retina)
|
||||
{
|
||||
subsystem->width = wide;
|
||||
|
@ -229,41 +220,36 @@ static int mac_shadow_detect_monitors(macShadowSubsystem* subsystem)
|
|||
subsystem->width = subsystem->pixelWidth;
|
||||
subsystem->height = subsystem->pixelHeight;
|
||||
}
|
||||
|
||||
|
||||
subsystem->numMonitors = 1;
|
||||
|
||||
monitor = &(subsystem->monitors[0]);
|
||||
|
||||
monitor->left = 0;
|
||||
monitor->top = 0;
|
||||
monitor->right = subsystem->width;
|
||||
monitor->bottom = subsystem->height;
|
||||
monitor->flags = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mac_shadow_capture_start(macShadowSubsystem* subsystem)
|
||||
{
|
||||
CGError err;
|
||||
|
||||
err = CGDisplayStreamStart(subsystem->stream);
|
||||
|
||||
|
||||
if (err != kCGErrorSuccess)
|
||||
return -1;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mac_shadow_capture_stop(macShadowSubsystem* subsystem)
|
||||
{
|
||||
CGError err;
|
||||
|
||||
err = CGDisplayStreamStop(subsystem->stream);
|
||||
|
||||
|
||||
if (err != kCGErrorSuccess)
|
||||
return -1;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -274,19 +260,19 @@ static int mac_shadow_capture_get_dirty_region(macShadowSubsystem* subsystem)
|
|||
const CGRect* rects;
|
||||
RECTANGLE_16 invalidRect;
|
||||
rdpShadowSurface* surface = subsystem->server->surface;
|
||||
|
||||
rects = CGDisplayStreamUpdateGetRects(subsystem->lastUpdate, kCGDisplayStreamUpdateDirtyRects, &numRects);
|
||||
|
||||
rects = CGDisplayStreamUpdateGetRects(subsystem->lastUpdate,
|
||||
kCGDisplayStreamUpdateDirtyRects, &numRects);
|
||||
|
||||
if (!numRects)
|
||||
return -1;
|
||||
|
||||
|
||||
for (index = 0; index < numRects; index++)
|
||||
{
|
||||
invalidRect.left = (UINT16) rects[index].origin.x;
|
||||
invalidRect.top = (UINT16) rects[index].origin.y;
|
||||
invalidRect.right = invalidRect.left + (UINT16) rects[index].size.width;
|
||||
invalidRect.bottom = invalidRect.top + (UINT16) rects[index].size.height;
|
||||
|
||||
|
||||
if (subsystem->retina)
|
||||
{
|
||||
/* scale invalid rect */
|
||||
|
@ -295,10 +281,11 @@ static int mac_shadow_capture_get_dirty_region(macShadowSubsystem* subsystem)
|
|||
invalidRect.right /= 2;
|
||||
invalidRect.bottom /= 2;
|
||||
}
|
||||
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&invalidRect);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -374,86 +361,77 @@ static void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t,
|
|||
macShadowSubsystem* subsystem = g_Subsystem;
|
||||
rdpShadowServer* server = subsystem->server;
|
||||
rdpShadowSurface* surface = server->surface;
|
||||
|
||||
count = ArrayList_Count(server->clients);
|
||||
|
||||
|
||||
if (count < 1)
|
||||
return;
|
||||
|
||||
mac_shadow_capture_get_dirty_region(subsystem);
|
||||
|
||||
surfaceRect.left = 0;
|
||||
surfaceRect.top = 0;
|
||||
surfaceRect.right = surface->width;
|
||||
surfaceRect.bottom = surface->height;
|
||||
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
|
||||
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&surfaceRect);
|
||||
|
||||
if (!region16_is_empty(&(surface->invalidRegion)))
|
||||
{
|
||||
extents = region16_extents(&(surface->invalidRegion));
|
||||
|
||||
x = extents->left;
|
||||
y = extents->top;
|
||||
width = extents->right - extents->left;
|
||||
height = extents->bottom - extents->top;
|
||||
|
||||
IOSurfaceLock(frameSurface, kIOSurfaceLockReadOnly, NULL);
|
||||
|
||||
pSrcData = (BYTE*) IOSurfaceGetBaseAddress(frameSurface);
|
||||
nSrcStep = (int) IOSurfaceGetBytesPerRow(frameSurface);
|
||||
|
||||
if (subsystem->retina)
|
||||
{
|
||||
freerdp_image_copy_from_retina(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
|
||||
x, y, width, height, pSrcData, nSrcStep, x, y);
|
||||
freerdp_image_copy_from_retina(surface->data, surface->format,
|
||||
surface->scanline,
|
||||
x, y, width, height, pSrcData, nSrcStep, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
|
||||
x, y, width, height, pSrcData, PIXEL_FORMAT_XRGB32, nSrcStep, x, y, NULL);
|
||||
freerdp_image_copy(surface->data, surface->format, surface->scanline,
|
||||
x, y, width, height, pSrcData, PIXEL_FORMAT_BGRX32, nSrcStep, x, y, NULL);
|
||||
}
|
||||
|
||||
|
||||
IOSurfaceUnlock(frameSurface, kIOSurfaceLockReadOnly, NULL);
|
||||
|
||||
ArrayList_Lock(server->clients);
|
||||
|
||||
count = ArrayList_Count(server->clients);
|
||||
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem);
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
rdpShadowClient* client;
|
||||
|
||||
client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0);
|
||||
|
||||
|
||||
if (client)
|
||||
{
|
||||
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ArrayList_Unlock(server->clients);
|
||||
|
||||
region16_clear(&(surface->invalidRegion));
|
||||
}
|
||||
|
||||
|
||||
if (status != kCGDisplayStreamFrameStatusFrameComplete)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case kCGDisplayStreamFrameStatusFrameIdle:
|
||||
break;
|
||||
|
||||
|
||||
case kCGDisplayStreamFrameStatusStopped:
|
||||
break;
|
||||
|
||||
|
||||
case kCGDisplayStreamFrameStatusFrameBlank:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -466,7 +444,8 @@ static void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t,
|
|||
else
|
||||
{
|
||||
CGDisplayStreamUpdateRef tmpRef = subsystem->lastUpdate;
|
||||
subsystem->lastUpdate = CGDisplayStreamUpdateCreateMergedUpdate(tmpRef, updateRef);
|
||||
subsystem->lastUpdate = CGDisplayStreamUpdateCreateMergedUpdate(tmpRef,
|
||||
updateRef);
|
||||
CFRelease(tmpRef);
|
||||
}
|
||||
};
|
||||
|
@ -477,26 +456,22 @@ static int mac_shadow_capture_init(macShadowSubsystem* subsystem)
|
|||
void* values[2];
|
||||
CFDictionaryRef opts;
|
||||
CGDirectDisplayID displayId;
|
||||
|
||||
displayId = CGMainDisplayID();
|
||||
|
||||
subsystem->updateBuffer = (BYTE*) malloc(subsystem->pixelWidth * subsystem->pixelHeight * 4);
|
||||
|
||||
subsystem->updateBuffer = (BYTE*) malloc(subsystem->pixelWidth *
|
||||
subsystem->pixelHeight * 4);
|
||||
|
||||
if (!subsystem->updateBuffer)
|
||||
return -1;
|
||||
|
||||
|
||||
subsystem->captureQueue = dispatch_queue_create("mac.shadow.capture", NULL);
|
||||
|
||||
keys[0] = (void*) kCGDisplayStreamShowCursor;
|
||||
values[0] = (void*) kCFBooleanFalse;
|
||||
|
||||
opts = CFDictionaryCreate(kCFAllocatorDefault, (const void**) keys, (const void**) values, 1, NULL, NULL);
|
||||
|
||||
subsystem->stream = CGDisplayStreamCreateWithDispatchQueue(displayId, subsystem->pixelWidth, subsystem->pixelHeight,
|
||||
'BGRA', opts, subsystem->captureQueue, mac_capture_stream_handler);
|
||||
|
||||
opts = CFDictionaryCreate(kCFAllocatorDefault, (const void**) keys,
|
||||
(const void**) values, 1, NULL, NULL);
|
||||
subsystem->stream = CGDisplayStreamCreateWithDispatchQueue(displayId,
|
||||
subsystem->pixelWidth, subsystem->pixelHeight,
|
||||
'BGRA', opts, subsystem->captureQueue, mac_capture_stream_handler);
|
||||
CFRelease(opts);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -508,13 +483,14 @@ static int mac_shadow_screen_grab(macShadowSubsystem* subsystem)
|
|||
static int mac_shadow_subsystem_process_message(macShadowSubsystem* subsystem,
|
||||
wMessage* message)
|
||||
{
|
||||
switch(message->id)
|
||||
switch (message->id)
|
||||
{
|
||||
case SHADOW_MSG_IN_REFRESH_REQUEST_ID:
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem);
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unknown message id: %u", message->id);
|
||||
break;
|
||||
|
@ -537,43 +513,38 @@ static void* mac_shadow_subsystem_thread(macShadowSubsystem* subsystem)
|
|||
HANDLE events[32];
|
||||
wMessage message;
|
||||
wMessagePipe* MsgPipe;
|
||||
|
||||
MsgPipe = subsystem->MsgPipe;
|
||||
|
||||
nCount = 0;
|
||||
events[nCount++] = MessageQueue_Event(MsgPipe->In);
|
||||
|
||||
subsystem->captureFrameRate = 16;
|
||||
dwInterval = 1000 / subsystem->captureFrameRate;
|
||||
frameTime = GetTickCount64() + dwInterval;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
cTime = GetTickCount64();
|
||||
dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime;
|
||||
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
|
||||
|
||||
|
||||
if (WaitForSingleObject(MessageQueue_Event(MsgPipe->In), 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (MessageQueue_Peek(MsgPipe->In, &message, TRUE))
|
||||
{
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
|
||||
mac_shadow_subsystem_process_message(subsystem, &message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
|
||||
{
|
||||
mac_shadow_screen_grab(subsystem);
|
||||
|
||||
dwInterval = 1000 / subsystem->captureFrameRate;
|
||||
frameTime += dwInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -585,37 +556,27 @@ static int mac_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
|
|||
int numMonitors = 0;
|
||||
MONITOR_DEF* monitor;
|
||||
CGDirectDisplayID displayId;
|
||||
|
||||
displayId = CGMainDisplayID();
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
|
||||
|
||||
wide = CGDisplayPixelsWide(displayId);
|
||||
high = CGDisplayPixelsHigh(displayId);
|
||||
|
||||
CGDisplayModeRelease(mode);
|
||||
|
||||
index = 0;
|
||||
numMonitors = 1;
|
||||
|
||||
monitor = &monitors[index];
|
||||
|
||||
monitor->left = 0;
|
||||
monitor->top = 0;
|
||||
monitor->right = (int) wide;
|
||||
monitor->bottom = (int) high;
|
||||
monitor->flags = 1;
|
||||
|
||||
return numMonitors;
|
||||
}
|
||||
|
||||
static int mac_shadow_subsystem_init(macShadowSubsystem* subsystem)
|
||||
{
|
||||
g_Subsystem = subsystem;
|
||||
|
||||
mac_shadow_detect_monitors(subsystem);
|
||||
|
||||
mac_shadow_capture_init(subsystem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -623,7 +584,7 @@ static int mac_shadow_subsystem_uninit(macShadowSubsystem* subsystem)
|
|||
{
|
||||
if (!subsystem)
|
||||
return -1;
|
||||
|
||||
|
||||
if (subsystem->lastUpdate)
|
||||
{
|
||||
CFRelease(subsystem->lastUpdate);
|
||||
|
@ -641,10 +602,10 @@ static int mac_shadow_subsystem_start(macShadowSubsystem* subsystem)
|
|||
return -1;
|
||||
|
||||
mac_shadow_capture_start(subsystem);
|
||||
|
||||
|
||||
if (!(thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) mac_shadow_subsystem_thread,
|
||||
(void*) subsystem, 0, NULL)))
|
||||
(LPTHREAD_START_ROUTINE) mac_shadow_subsystem_thread,
|
||||
(void*) subsystem, 0, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create thread");
|
||||
return -1;
|
||||
|
@ -667,25 +628,26 @@ static void mac_shadow_subsystem_free(macShadowSubsystem* subsystem)
|
|||
return;
|
||||
|
||||
mac_shadow_subsystem_uninit(subsystem);
|
||||
|
||||
free(subsystem);
|
||||
}
|
||||
|
||||
static macShadowSubsystem* mac_shadow_subsystem_new(void)
|
||||
{
|
||||
macShadowSubsystem* subsystem;
|
||||
|
||||
subsystem = (macShadowSubsystem*) calloc(1, sizeof(macShadowSubsystem));
|
||||
|
||||
if (!subsystem)
|
||||
return NULL;
|
||||
|
||||
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) mac_shadow_input_synchronize_event;
|
||||
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) mac_shadow_input_keyboard_event;
|
||||
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) mac_shadow_input_unicode_keyboard_event;
|
||||
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent)
|
||||
mac_shadow_input_synchronize_event;
|
||||
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent)
|
||||
mac_shadow_input_keyboard_event;
|
||||
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent)
|
||||
mac_shadow_input_unicode_keyboard_event;
|
||||
subsystem->MouseEvent = (pfnShadowMouseEvent) mac_shadow_input_mouse_event;
|
||||
subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) mac_shadow_input_extended_mouse_event;
|
||||
|
||||
subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent)
|
||||
mac_shadow_input_extended_mouse_event;
|
||||
return subsystem;
|
||||
}
|
||||
|
||||
|
@ -693,14 +655,10 @@ FREERDP_API int Mac_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
|
|||
{
|
||||
pEntryPoints->New = (pfnShadowSubsystemNew) mac_shadow_subsystem_new;
|
||||
pEntryPoints->Free = (pfnShadowSubsystemFree) mac_shadow_subsystem_free;
|
||||
|
||||
pEntryPoints->Init = (pfnShadowSubsystemInit) mac_shadow_subsystem_init;
|
||||
pEntryPoints->Uninit = (pfnShadowSubsystemInit) mac_shadow_subsystem_uninit;
|
||||
|
||||
pEntryPoints->Start = (pfnShadowSubsystemStart) mac_shadow_subsystem_start;
|
||||
pEntryPoints->Stop = (pfnShadowSubsystemStop) mac_shadow_subsystem_stop;
|
||||
|
||||
pEntryPoints->EnumMonitors = (pfnShadowEnumMonitors) mac_shadow_enum_monitors;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -28,15 +28,15 @@
|
|||
|
||||
#define TAG SERVER_TAG("shadow.win")
|
||||
|
||||
void win_shadow_input_synchronize_event(winShadowSubsystem* subsystem, rdpShadowClient* client, UINT32 flags)
|
||||
void win_shadow_input_synchronize_event(winShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT32 flags)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void win_shadow_input_keyboard_event(winShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 code)
|
||||
void win_shadow_input_keyboard_event(winShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 code)
|
||||
{
|
||||
INPUT event;
|
||||
|
||||
event.type = INPUT_KEYBOARD;
|
||||
event.ki.wVk = 0;
|
||||
event.ki.wScan = code;
|
||||
|
@ -53,10 +53,10 @@ void win_shadow_input_keyboard_event(winShadowSubsystem* subsystem, rdpShadowCli
|
|||
SendInput(1, &event, sizeof(INPUT));
|
||||
}
|
||||
|
||||
void win_shadow_input_unicode_keyboard_event(winShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 code)
|
||||
void win_shadow_input_unicode_keyboard_event(winShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 code)
|
||||
{
|
||||
INPUT event;
|
||||
|
||||
event.type = INPUT_KEYBOARD;
|
||||
event.ki.wVk = 0;
|
||||
event.ki.wScan = code;
|
||||
|
@ -70,14 +70,13 @@ void win_shadow_input_unicode_keyboard_event(winShadowSubsystem* subsystem, rdpS
|
|||
SendInput(1, &event, sizeof(INPUT));
|
||||
}
|
||||
|
||||
void win_shadow_input_mouse_event(winShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
|
||||
void win_shadow_input_mouse_event(winShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
INPUT event;
|
||||
float width;
|
||||
float height;
|
||||
|
||||
ZeroMemory(&event, sizeof(INPUT));
|
||||
|
||||
event.type = INPUT_MOUSE;
|
||||
|
||||
if (flags & PTR_FLAGS_WHEEL)
|
||||
|
@ -94,9 +93,8 @@ void win_shadow_input_mouse_event(winShadowSubsystem* subsystem, rdpShadowClient
|
|||
{
|
||||
width = (float) GetSystemMetrics(SM_CXSCREEN);
|
||||
height = (float) GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
event.mi.dx = (LONG) ((float) x * (65535.0f / width));
|
||||
event.mi.dy = (LONG) ((float) y * (65535.0f / height));
|
||||
event.mi.dx = (LONG)((float) x * (65535.0f / width));
|
||||
event.mi.dy = (LONG)((float) y * (65535.0f / height));
|
||||
event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
|
||||
|
||||
if (flags & PTR_FLAGS_MOVE)
|
||||
|
@ -137,12 +135,12 @@ void win_shadow_input_mouse_event(winShadowSubsystem* subsystem, rdpShadowClient
|
|||
}
|
||||
}
|
||||
|
||||
void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem, rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
|
||||
void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
INPUT event;
|
||||
float width;
|
||||
float height;
|
||||
|
||||
ZeroMemory(&event, sizeof(INPUT));
|
||||
|
||||
if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2))
|
||||
|
@ -153,11 +151,9 @@ void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem, rdpSha
|
|||
{
|
||||
width = (float) GetSystemMetrics(SM_CXSCREEN);
|
||||
height = (float) GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
event.mi.dx = (LONG)((float) x * (65535.0f / width));
|
||||
event.mi.dy = (LONG)((float) y * (65535.0f / height));
|
||||
event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||
|
||||
SendInput(1, &event, sizeof(INPUT));
|
||||
}
|
||||
|
||||
|
@ -178,24 +174,22 @@ void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem, rdpSha
|
|||
}
|
||||
|
||||
|
||||
int win_shadow_invalidate_region(winShadowSubsystem* subsystem, int x, int y, int width, int height)
|
||||
int win_shadow_invalidate_region(winShadowSubsystem* subsystem, int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
rdpShadowServer* server;
|
||||
rdpShadowSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
server = subsystem->server;
|
||||
surface = server->surface;
|
||||
|
||||
invalidRect.left = x;
|
||||
invalidRect.top = y;
|
||||
invalidRect.right = x + width;
|
||||
invalidRect.bottom = y + height;
|
||||
|
||||
EnterCriticalSection(&(surface->lock));
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&invalidRect);
|
||||
LeaveCriticalSection(&(surface->lock));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -207,13 +201,13 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)
|
|||
int count;
|
||||
int status = 1;
|
||||
int nDstStep = 0;
|
||||
DWORD DstFormat;
|
||||
BYTE* pDstData = NULL;
|
||||
rdpShadowServer* server;
|
||||
rdpShadowSurface* surface;
|
||||
RECTANGLE_16 surfaceRect;
|
||||
RECTANGLE_16 invalidRect;
|
||||
const RECTANGLE_16* extents;
|
||||
|
||||
server = subsystem->server;
|
||||
surface = server->surface;
|
||||
|
||||
|
@ -227,17 +221,15 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)
|
|||
surfaceRect.top = surface->y;
|
||||
surfaceRect.right = surface->x + surface->width;
|
||||
surfaceRect.bottom = surface->y + surface->height;
|
||||
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
|
||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion),
|
||||
&surfaceRect);
|
||||
|
||||
if (region16_is_empty(&(surface->invalidRegion)))
|
||||
return 1;
|
||||
|
||||
extents = region16_extents(&(surface->invalidRegion));
|
||||
CopyMemory(&invalidRect, extents, sizeof(RECTANGLE_16));
|
||||
|
||||
shadow_capture_align_clip_rect(&invalidRect, &surfaceRect);
|
||||
|
||||
x = invalidRect.left;
|
||||
y = invalidRect.top;
|
||||
width = invalidRect.right - invalidRect.left;
|
||||
|
@ -251,43 +243,38 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)
|
|||
height = surface->height;
|
||||
}
|
||||
|
||||
WLog_INFO(TAG, "SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d",
|
||||
x, y, width, height, x + width, y + height);
|
||||
|
||||
WLog_INFO(TAG,
|
||||
"SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d",
|
||||
x, y, width, height, x + width, y + height);
|
||||
#if defined(WITH_WDS_API)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
shwContext* shw;
|
||||
rdpContext* context;
|
||||
|
||||
shw = subsystem->shw;
|
||||
context = (rdpContext*) shw;
|
||||
gdi = context->gdi;
|
||||
|
||||
pDstData = gdi->primary_buffer;
|
||||
nDstStep = gdi->width * 4;
|
||||
DstFormat = gdi->dstFormat;
|
||||
}
|
||||
#elif defined(WITH_DXGI_1_2)
|
||||
status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y, width, height);
|
||||
DstFormat = PIXEL_FORMAT_BGRX32;
|
||||
status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y,
|
||||
width, height);
|
||||
#endif
|
||||
|
||||
if (status <= 0)
|
||||
return status;
|
||||
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
|
||||
surface->scanline, x - surface->x, y - surface->y, width, height,
|
||||
pDstData, PIXEL_FORMAT_XRGB32, nDstStep, 0, 0, NULL);
|
||||
|
||||
freerdp_image_copy(surface->data, surface->format,
|
||||
surface->scanline, x - surface->x, y - surface->y, width, height,
|
||||
pDstData, DstFormat, nDstStep, 0, 0, NULL);
|
||||
ArrayList_Lock(server->clients);
|
||||
|
||||
count = ArrayList_Count(server->clients);
|
||||
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem);
|
||||
|
||||
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
|
||||
ArrayList_Unlock(server->clients);
|
||||
|
||||
region16_clear(&(surface->invalidRegion));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -299,9 +286,7 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
|
|||
DWORD nCount;
|
||||
HANDLE events[32];
|
||||
HANDLE StopEvent;
|
||||
|
||||
StopEvent = subsystem->server->StopEvent;
|
||||
|
||||
nCount = 0;
|
||||
events[nCount++] = StopEvent;
|
||||
events[nCount++] = subsystem->RdpUpdateEnterEvent;
|
||||
|
@ -340,12 +325,9 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
|
|||
UINT64 frameTime;
|
||||
HANDLE events[32];
|
||||
HANDLE StopEvent;
|
||||
|
||||
StopEvent = subsystem->server->StopEvent;
|
||||
|
||||
nCount = 0;
|
||||
events[nCount++] = StopEvent;
|
||||
|
||||
fps = 16;
|
||||
dwInterval = 1000 / fps;
|
||||
frameTime = GetTickCount64() + dwInterval;
|
||||
|
@ -353,10 +335,8 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
|
|||
while (1)
|
||||
{
|
||||
dwTimeout = INFINITE;
|
||||
|
||||
cTime = GetTickCount64();
|
||||
dwTimeout = (DWORD) ((cTime > frameTime) ? 0 : frameTime - cTime);
|
||||
|
||||
dwTimeout = (DWORD)((cTime > frameTime) ? 0 : frameTime - cTime);
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
|
||||
|
||||
if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
|
||||
|
@ -367,9 +347,8 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
|
|||
if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
|
||||
{
|
||||
int dxgi_status;
|
||||
|
||||
dxgi_status = win_shadow_dxgi_get_next_frame(subsystem);
|
||||
|
||||
|
||||
if (dxgi_status > 0)
|
||||
dxgi_status = win_shadow_dxgi_get_invalid_region(subsystem);
|
||||
|
||||
|
@ -397,28 +376,22 @@ int win_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
|
|||
int numMonitors = 0;
|
||||
MONITOR_DEF* monitor;
|
||||
DISPLAY_DEVICE displayDevice;
|
||||
|
||||
ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
|
||||
displayDevice.cb = sizeof(DISPLAY_DEVICE);
|
||||
|
||||
if (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0))
|
||||
{
|
||||
hdc = CreateDC(displayDevice.DeviceName, NULL, NULL, NULL);
|
||||
|
||||
desktopWidth = GetDeviceCaps(hdc, HORZRES);
|
||||
desktopHeight = GetDeviceCaps(hdc, VERTRES);
|
||||
|
||||
index = 0;
|
||||
numMonitors = 1;
|
||||
|
||||
monitor = &monitors[index];
|
||||
|
||||
monitor->left = 0;
|
||||
monitor->top = 0;
|
||||
monitor->right = desktopWidth;
|
||||
monitor->bottom = desktopHeight;
|
||||
monitor->flags = 1;
|
||||
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
|
||||
|
@ -429,25 +402,19 @@ int win_shadow_subsystem_init(winShadowSubsystem* subsystem)
|
|||
{
|
||||
int status;
|
||||
MONITOR_DEF* virtualScreen;
|
||||
|
||||
subsystem->numMonitors = win_shadow_enum_monitors(subsystem->monitors, 16);
|
||||
|
||||
#if defined(WITH_WDS_API)
|
||||
status = win_shadow_wds_init(subsystem);
|
||||
#elif defined(WITH_DXGI_1_2)
|
||||
status = win_shadow_dxgi_init(subsystem);
|
||||
#endif
|
||||
|
||||
virtualScreen = &(subsystem->virtualScreen);
|
||||
|
||||
virtualScreen->left = 0;
|
||||
virtualScreen->top = 0;
|
||||
virtualScreen->right = subsystem->width;
|
||||
virtualScreen->bottom = subsystem->height;
|
||||
virtualScreen->flags = 1;
|
||||
|
||||
WLog_INFO(TAG, "width: %d height: %d", subsystem->width, subsystem->height);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -461,7 +428,6 @@ int win_shadow_subsystem_uninit(winShadowSubsystem* subsystem)
|
|||
#elif defined(WITH_DXGI_1_2)
|
||||
win_shadow_dxgi_uninit(subsystem);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -473,8 +439,8 @@ int win_shadow_subsystem_start(winShadowSubsystem* subsystem)
|
|||
return -1;
|
||||
|
||||
if (!(thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) win_shadow_subsystem_thread,
|
||||
(void*) subsystem, 0, NULL)))
|
||||
(LPTHREAD_START_ROUTINE) win_shadow_subsystem_thread,
|
||||
(void*) subsystem, 0, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create thread");
|
||||
return -1;
|
||||
|
@ -497,25 +463,26 @@ void win_shadow_subsystem_free(winShadowSubsystem* subsystem)
|
|||
return;
|
||||
|
||||
win_shadow_subsystem_uninit(subsystem);
|
||||
|
||||
free(subsystem);
|
||||
}
|
||||
|
||||
winShadowSubsystem* win_shadow_subsystem_new()
|
||||
{
|
||||
winShadowSubsystem* subsystem;
|
||||
|
||||
subsystem = (winShadowSubsystem*) calloc(1, sizeof(winShadowSubsystem));
|
||||
|
||||
if (!subsystem)
|
||||
return NULL;
|
||||
|
||||
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) win_shadow_input_synchronize_event;
|
||||
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) win_shadow_input_keyboard_event;
|
||||
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) win_shadow_input_unicode_keyboard_event;
|
||||
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent)
|
||||
win_shadow_input_synchronize_event;
|
||||
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent)
|
||||
win_shadow_input_keyboard_event;
|
||||
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent)
|
||||
win_shadow_input_unicode_keyboard_event;
|
||||
subsystem->MouseEvent = (pfnShadowMouseEvent) win_shadow_input_mouse_event;
|
||||
subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) win_shadow_input_extended_mouse_event;
|
||||
|
||||
subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent)
|
||||
win_shadow_input_extended_mouse_event;
|
||||
return subsystem;
|
||||
}
|
||||
|
||||
|
@ -523,14 +490,10 @@ FREERDP_API int Win_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
|
|||
{
|
||||
pEntryPoints->New = (pfnShadowSubsystemNew) win_shadow_subsystem_new;
|
||||
pEntryPoints->Free = (pfnShadowSubsystemFree) win_shadow_subsystem_free;
|
||||
|
||||
pEntryPoints->Init = (pfnShadowSubsystemInit) win_shadow_subsystem_init;
|
||||
pEntryPoints->Uninit = (pfnShadowSubsystemInit) win_shadow_subsystem_uninit;
|
||||
|
||||
pEntryPoints->Start = (pfnShadowSubsystemStart) win_shadow_subsystem_start;
|
||||
pEntryPoints->Stop = (pfnShadowSubsystemStop) win_shadow_subsystem_stop;
|
||||
|
||||
pEntryPoints->EnumMonitors = (pfnShadowEnumMonitors) win_shadow_enum_monitors;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -46,14 +46,13 @@ UINT32 shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
|
|||
{
|
||||
UINT32 frameId;
|
||||
int inFlightFrames;
|
||||
|
||||
inFlightFrames = shadow_encoder_inflight_frames(encoder);
|
||||
|
||||
/*
|
||||
* Calculate preferred fps according to how much frames are
|
||||
/*
|
||||
* Calculate preferred fps according to how much frames are
|
||||
* in-progress. Note that it only works when subsytem implementation
|
||||
* calls shadow_encoder_preferred_fps and takes the suggestion.
|
||||
*/
|
||||
*/
|
||||
if (inFlightFrames > 1)
|
||||
{
|
||||
encoder->fps = (100 / (inFlightFrames + 1) * encoder->maxFps) / 100;
|
||||
|
@ -70,22 +69,20 @@ UINT32 shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
|
|||
encoder->fps = 1;
|
||||
|
||||
frameId = ++encoder->frameId;
|
||||
|
||||
return frameId;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_grid(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init_grid(rdpShadowEncoder* encoder)
|
||||
{
|
||||
int i, j, k;
|
||||
int tileSize;
|
||||
int tileCount;
|
||||
|
||||
encoder->gridWidth = ((encoder->width + (encoder->maxTileWidth - 1)) / encoder->maxTileWidth);
|
||||
encoder->gridHeight = ((encoder->height + (encoder->maxTileHeight - 1)) / encoder->maxTileHeight);
|
||||
|
||||
encoder->gridWidth = ((encoder->width + (encoder->maxTileWidth - 1)) /
|
||||
encoder->maxTileWidth);
|
||||
encoder->gridHeight = ((encoder->height + (encoder->maxTileHeight - 1)) /
|
||||
encoder->maxTileHeight);
|
||||
tileSize = encoder->maxTileWidth * encoder->maxTileHeight * 4;
|
||||
tileCount = encoder->gridWidth * encoder->gridHeight;
|
||||
|
||||
encoder->gridBuffer = (BYTE*) malloc(tileSize * tileCount);
|
||||
|
||||
if (!encoder->gridBuffer)
|
||||
|
@ -108,7 +105,7 @@ int shadow_encoder_init_grid(rdpShadowEncoder* encoder)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit_grid(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit_grid(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (encoder->gridBuffer)
|
||||
{
|
||||
|
@ -124,11 +121,10 @@ int shadow_encoder_uninit_grid(rdpShadowEncoder* encoder)
|
|||
|
||||
encoder->gridWidth = 0;
|
||||
encoder->gridHeight = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (!encoder->rfx)
|
||||
encoder->rfx = rfx_context_new(TRUE);
|
||||
|
@ -140,19 +136,15 @@ int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
|
|||
goto fail;
|
||||
|
||||
encoder->rfx->mode = encoder->server->rfxMode;
|
||||
|
||||
rfx_context_set_pixel_format(encoder->rfx, PIXEL_FORMAT_BGR24);
|
||||
|
||||
rfx_context_set_pixel_format(encoder->rfx, PIXEL_FORMAT_BGRX32);
|
||||
encoder->codecs |= FREERDP_CODEC_REMOTEFX;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
rfx_context_free(encoder->rfx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
|
||||
{
|
||||
rdpContext* context = (rdpContext*) encoder->client;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
@ -167,21 +159,18 @@ int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
|
|||
goto fail;
|
||||
|
||||
encoder->nsc->ColorLossLevel = settings->NSCodecColorLossLevel;
|
||||
encoder->nsc->ChromaSubsamplingLevel = settings->NSCodecAllowSubsampling ? 1 : 0;
|
||||
encoder->nsc->ChromaSubsamplingLevel = settings->NSCodecAllowSubsampling ? 1 :
|
||||
0;
|
||||
encoder->nsc->DynamicColorFidelity = settings->NSCodecAllowDynamicColorFidelity;
|
||||
|
||||
nsc_context_set_pixel_format(encoder->nsc, PIXEL_FORMAT_BGR24);
|
||||
|
||||
nsc_context_set_pixel_format(encoder->nsc, PIXEL_FORMAT_BGRX32);
|
||||
encoder->codecs |= FREERDP_CODEC_NSCODEC;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
nsc_context_free(encoder->nsc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_planar(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init_planar(rdpShadowEncoder* encoder)
|
||||
{
|
||||
DWORD planarFlags = 0;
|
||||
rdpContext* context = (rdpContext*) encoder->client;
|
||||
|
@ -195,27 +184,25 @@ int shadow_encoder_init_planar(rdpShadowEncoder* encoder)
|
|||
if (!encoder->planar)
|
||||
{
|
||||
encoder->planar = freerdp_bitmap_planar_context_new(planarFlags,
|
||||
encoder->maxTileWidth, encoder->maxTileHeight);
|
||||
encoder->maxTileWidth, encoder->maxTileHeight);
|
||||
}
|
||||
|
||||
if (!encoder->planar)
|
||||
goto fail;
|
||||
|
||||
if (!freerdp_bitmap_planar_context_reset(encoder->planar,
|
||||
encoder->maxTileWidth,
|
||||
encoder->maxTileHeight))
|
||||
encoder->maxTileWidth,
|
||||
encoder->maxTileHeight))
|
||||
goto fail;
|
||||
|
||||
encoder->codecs |= FREERDP_CODEC_PLANAR;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
freerdp_bitmap_planar_context_free(encoder->planar);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_interleaved(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init_interleaved(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (!encoder->interleaved)
|
||||
encoder->interleaved = bitmap_interleaved_context_new(TRUE);
|
||||
|
@ -227,15 +214,13 @@ int shadow_encoder_init_interleaved(rdpShadowEncoder* encoder)
|
|||
goto fail;
|
||||
|
||||
encoder->codecs |= FREERDP_CODEC_INTERLEAVED;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
bitmap_interleaved_context_free(encoder->interleaved);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_h264(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init_h264(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (!encoder->h264)
|
||||
encoder->h264 = h264_context_new(TRUE);
|
||||
|
@ -250,28 +235,24 @@ int shadow_encoder_init_h264(rdpShadowEncoder* encoder)
|
|||
encoder->h264->BitRate = encoder->server->h264BitRate;
|
||||
encoder->h264->FrameRate = encoder->server->h264FrameRate;
|
||||
encoder->h264->QP = encoder->server->h264QP;
|
||||
|
||||
encoder->codecs |= FREERDP_CODEC_AVC420;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
h264_context_free(encoder->h264);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadow_encoder_init(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_init(rdpShadowEncoder* encoder)
|
||||
{
|
||||
encoder->width = encoder->server->screen->width;
|
||||
encoder->height = encoder->server->screen->height;
|
||||
|
||||
encoder->maxTileWidth = 64;
|
||||
encoder->maxTileHeight = 64;
|
||||
|
||||
shadow_encoder_init_grid(encoder);
|
||||
|
||||
if (!encoder->bs)
|
||||
encoder->bs = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4);
|
||||
encoder->bs = Stream_New(NULL,
|
||||
encoder->maxTileWidth * encoder->maxTileHeight * 4);
|
||||
|
||||
if (!encoder->bs)
|
||||
return -1;
|
||||
|
@ -279,7 +260,7 @@ int shadow_encoder_init(rdpShadowEncoder* encoder)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (encoder->rfx)
|
||||
{
|
||||
|
@ -288,11 +269,10 @@ int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder)
|
|||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_REMOTEFX;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (encoder->nsc)
|
||||
{
|
||||
|
@ -301,11 +281,10 @@ int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder)
|
|||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_NSCODEC;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit_planar(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit_planar(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (encoder->planar)
|
||||
{
|
||||
|
@ -314,11 +293,10 @@ int shadow_encoder_uninit_planar(rdpShadowEncoder* encoder)
|
|||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_PLANAR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit_interleaved(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit_interleaved(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (encoder->interleaved)
|
||||
{
|
||||
|
@ -327,24 +305,22 @@ int shadow_encoder_uninit_interleaved(rdpShadowEncoder* encoder)
|
|||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_INTERLEAVED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit_h264(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit_h264(rdpShadowEncoder* encoder)
|
||||
{
|
||||
if (encoder->h264)
|
||||
{
|
||||
h264_context_free(encoder->h264);
|
||||
encoder->h264= NULL;
|
||||
encoder->h264 = NULL;
|
||||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_AVC420;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shadow_encoder_uninit(rdpShadowEncoder* encoder)
|
||||
static int shadow_encoder_uninit(rdpShadowEncoder* encoder)
|
||||
{
|
||||
shadow_encoder_uninit_grid(encoder);
|
||||
|
||||
|
@ -388,7 +364,6 @@ int shadow_encoder_reset(rdpShadowEncoder* encoder)
|
|||
UINT32 codecs = encoder->codecs;
|
||||
rdpContext* context = (rdpContext*) encoder->client;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
status = shadow_encoder_uninit(encoder);
|
||||
|
||||
if (status < 0)
|
||||
|
@ -409,7 +384,6 @@ int shadow_encoder_reset(rdpShadowEncoder* encoder)
|
|||
encoder->frameId = 0;
|
||||
encoder->lastAckframeId = 0;
|
||||
encoder->frameAck = settings->SurfaceFrameMarkerEnabled;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -417,7 +391,8 @@ int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
|
|||
{
|
||||
int status;
|
||||
|
||||
if ((codecs & FREERDP_CODEC_REMOTEFX) && !(encoder->codecs & FREERDP_CODEC_REMOTEFX))
|
||||
if ((codecs & FREERDP_CODEC_REMOTEFX)
|
||||
&& !(encoder->codecs & FREERDP_CODEC_REMOTEFX))
|
||||
{
|
||||
status = shadow_encoder_init_rfx(encoder);
|
||||
|
||||
|
@ -425,7 +400,8 @@ int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((codecs & FREERDP_CODEC_NSCODEC) && !(encoder->codecs & FREERDP_CODEC_NSCODEC))
|
||||
if ((codecs & FREERDP_CODEC_NSCODEC)
|
||||
&& !(encoder->codecs & FREERDP_CODEC_NSCODEC))
|
||||
{
|
||||
status = shadow_encoder_init_nsc(encoder);
|
||||
|
||||
|
@ -433,7 +409,8 @@ int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((codecs & FREERDP_CODEC_PLANAR) && !(encoder->codecs & FREERDP_CODEC_PLANAR))
|
||||
if ((codecs & FREERDP_CODEC_PLANAR)
|
||||
&& !(encoder->codecs & FREERDP_CODEC_PLANAR))
|
||||
{
|
||||
status = shadow_encoder_init_planar(encoder);
|
||||
|
||||
|
@ -441,7 +418,8 @@ int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((codecs & FREERDP_CODEC_INTERLEAVED) && !(encoder->codecs & FREERDP_CODEC_INTERLEAVED))
|
||||
if ((codecs & FREERDP_CODEC_INTERLEAVED)
|
||||
&& !(encoder->codecs & FREERDP_CODEC_INTERLEAVED))
|
||||
{
|
||||
status = shadow_encoder_init_interleaved(encoder);
|
||||
|
||||
|
@ -449,7 +427,8 @@ int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((codecs & FREERDP_CODEC_AVC420) && !(encoder->codecs & FREERDP_CODEC_AVC420))
|
||||
if ((codecs & FREERDP_CODEC_AVC420)
|
||||
&& !(encoder->codecs & FREERDP_CODEC_AVC420))
|
||||
{
|
||||
status = shadow_encoder_init_h264(encoder);
|
||||
|
||||
|
@ -464,7 +443,6 @@ rdpShadowEncoder* shadow_encoder_new(rdpShadowClient* client)
|
|||
{
|
||||
rdpShadowEncoder* encoder;
|
||||
rdpShadowServer* server = client->server;
|
||||
|
||||
encoder = (rdpShadowEncoder*) calloc(1, sizeof(rdpShadowEncoder));
|
||||
|
||||
if (!encoder)
|
||||
|
@ -472,13 +450,12 @@ rdpShadowEncoder* shadow_encoder_new(rdpShadowClient* client)
|
|||
|
||||
encoder->client = client;
|
||||
encoder->server = server;
|
||||
|
||||
encoder->fps = 16;
|
||||
encoder->maxFps = 32;
|
||||
|
||||
if (shadow_encoder_init(encoder) < 0)
|
||||
{
|
||||
free (encoder);
|
||||
free(encoder);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -491,6 +468,5 @@ void shadow_encoder_free(rdpShadowEncoder* encoder)
|
|||
return;
|
||||
|
||||
shadow_encoder_uninit(encoder);
|
||||
|
||||
free(encoder);
|
||||
}
|
||||
|
|
|
@ -24,39 +24,39 @@
|
|||
|
||||
#include "shadow_surface.h"
|
||||
#define ALIGN_SCREEN_SIZE(size, align) ((size + align - 1) & (~(align - 1)))
|
||||
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height)
|
||||
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
rdpShadowSurface* surface;
|
||||
|
||||
surface = (rdpShadowSurface*) calloc(1, sizeof(rdpShadowSurface));
|
||||
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
surface->server = server;
|
||||
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->scanline = ALIGN_SCREEN_SIZE(surface->width, 4) * 4;
|
||||
surface->format = PIXEL_FORMAT_BGRX32;
|
||||
surface->data = (BYTE*) calloc(1,
|
||||
surface->scanline * ALIGN_SCREEN_SIZE(surface->height, 4));
|
||||
|
||||
surface->data = (BYTE*) calloc(1, surface->scanline * ALIGN_SCREEN_SIZE(surface->height, 4));
|
||||
if (!surface->data)
|
||||
{
|
||||
free (surface);
|
||||
free(surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!InitializeCriticalSectionAndSpinCount(&(surface->lock), 4000))
|
||||
{
|
||||
free (surface->data);
|
||||
free (surface);
|
||||
free(surface->data);
|
||||
free(surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
region16_init(&(surface->invalidRegion));
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
@ -66,15 +66,13 @@ void shadow_surface_free(rdpShadowSurface* surface)
|
|||
return;
|
||||
|
||||
free(surface->data);
|
||||
|
||||
DeleteCriticalSection(&(surface->lock));
|
||||
|
||||
region16_uninit(&(surface->invalidRegion));
|
||||
|
||||
free(surface);
|
||||
}
|
||||
|
||||
BOOL shadow_surface_resize(rdpShadowSurface *surface, int x, int y, int width, int height)
|
||||
BOOL shadow_surface_resize(rdpShadowSurface* surface, int x, int y, int width,
|
||||
int height)
|
||||
{
|
||||
BYTE* buffer = NULL;
|
||||
int scanline = ALIGN_SCREEN_SIZE(width, 4) * 4;
|
||||
|
@ -90,7 +88,9 @@ BOOL shadow_surface_resize(rdpShadowSurface *surface, int x, int y, int width, i
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
buffer = (BYTE*) realloc(surface->data, scanline * ALIGN_SCREEN_SIZE(height, 4));
|
||||
buffer = (BYTE*) realloc(surface->data, scanline * ALIGN_SCREEN_SIZE(height,
|
||||
4));
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
surface->x = x;
|
||||
|
@ -99,7 +99,6 @@ BOOL shadow_surface_resize(rdpShadowSurface *surface, int x, int y, int width, i
|
|||
surface->height = height;
|
||||
surface->scanline = scanline;
|
||||
surface->data = buffer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue