Fixed shadow server color encoding.

This commit is contained in:
Armin Novak 2016-09-20 09:25:13 +02:00
parent f5fff7658a
commit 9ab04711fa
8 changed files with 704 additions and 875 deletions

View File

@ -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);

View File

@ -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*) &params[i], &context->priv->ThreadPoolEnv)))
rfx_process_message_tile_work_callback,
(void*) &params[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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}