Merge pull request #2169 from awakecoding/master

Clipboard, RemoteApp, Cursor + Color Conversion
This commit is contained in:
Marc-André Moreau 2014-10-25 10:46:28 -04:00
commit 8330b03a0e
76 changed files with 6722 additions and 3464 deletions

View File

@ -102,7 +102,7 @@ static int audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, w
out = Stream_New(NULL, 5);
Stream_Write_UINT8(out, MSG_SNDIN_VERSION);
Stream_Write_UINT32(out, Version);
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(s), Stream_Buffer(s), NULL);
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out), Stream_Buffer(out), NULL);
Stream_Free(out, TRUE);
return error;

View File

@ -225,7 +225,7 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
formatList.msgFlags = msgFlags;
formatList.dataLen = dataLen;
formatList.cFormats = 0;
formatList.numFormats = 0;
while (dataLen)
{
@ -235,14 +235,14 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
formatNameLength = _wcslen((WCHAR*) Stream_Pointer(s));
Stream_Seek(s, (formatNameLength + 1) * 2);
dataLen -= ((formatNameLength + 1) * 2);
formatList.cFormats++;
formatList.numFormats++;
}
index = 0;
dataLen = formatList.dataLen;
Stream_Rewind(s, dataLen);
formats = (CLIPRDR_FORMAT*) malloc(sizeof(CLIPRDR_FORMAT) * formatList.cFormats);
formats = (CLIPRDR_FORMAT*) malloc(sizeof(CLIPRDR_FORMAT) * formatList.numFormats);
formatList.formats = formats;
while (dataLen)
@ -270,10 +270,13 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
index++;
}
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatList: numFormats: %d",
formatList.numFormats);
if (context->ServerFormatList)
context->ServerFormatList(context, &formatList);
for (index = 0; index < formatList.cFormats; index++)
for (index = 0; index < formatList.numFormats; index++)
free(formats[index].formatName);
free(formats);
@ -315,9 +318,9 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
switch (format)
{
case CB_FORMAT_TEXT:
case CB_FORMAT_DIB:
case CB_FORMAT_UNICODETEXT:
case CF_TEXT:
case CF_DIB:
case CF_UNICODETEXT:
break;
default:
@ -367,6 +370,9 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
cliprdr->num_format_names = 0;
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatList: numFormats: %d",
cb_event->num_formats);
cliprdr_send_format_list_response(cliprdr);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
@ -376,6 +382,8 @@ void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UI
{
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatListResponse");
/* http://msdn.microsoft.com/en-us/library/hh872154.aspx */
if (context->custom)
@ -406,6 +414,8 @@ void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UIN
{
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataRequest");
if (context->custom)
{
CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
@ -465,6 +475,8 @@ void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI
{
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataResponse");
if (context->custom)
{
CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse;

View File

@ -36,7 +36,6 @@
#include "cliprdr_main.h"
#include "cliprdr_format.h"
#ifdef WITH_DEBUG_CLIPRDR
static const char* const CB_MSG_TYPE_STRINGS[] =
{
"",
@ -52,7 +51,6 @@ static const char* const CB_MSG_TYPE_STRINGS[] =
"CB_LOCK_CLIPDATA"
"CB_UNLOCK_CLIPDATA"
};
#endif
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr)
{
@ -113,7 +111,7 @@ void cliprdr_print_general_capability_flags(UINT32 flags)
WLog_INFO(TAG, "}");
}
static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
static int cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
{
UINT32 version;
UINT32 generalFlags;
@ -161,9 +159,11 @@ static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream*
caps_event->capabilities = generalFlags;
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) caps_event);
}
return 1;
}
static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
static int cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
int i;
UINT16 lengthCapability;
@ -171,7 +171,8 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16
UINT16 capabilitySetType;
Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
Stream_Seek_UINT16(s); /* pad1 (2 bytes) */
DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerCapabilities");
for (i = 0; i < cCapabilitiesSets; i++)
{
@ -188,6 +189,8 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16
break;
}
}
return 1;
}
static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr)
@ -211,10 +214,12 @@ static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr)
cliprdr_packet_send(cliprdr, s);
}
static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
static int cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "MonitorReady");
if (context->custom)
{
CLIPRDR_MONITOR_READY monitorReady;
@ -235,56 +240,178 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI
event = (RDP_CB_MONITOR_READY_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) event);
}
return 1;
}
static void cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
static int cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_FILECONTENTS_REQUEST_EVENT* cb_event;
cb_event = (RDP_CB_FILECONTENTS_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FilecontentsRequest, NULL, NULL);
Stream_Read_UINT32(s, cb_event->streamId);
Stream_Read_UINT32(s, cb_event->lindex);
Stream_Read_UINT32(s, cb_event->dwFlags);
Stream_Read_UINT32(s, cb_event->nPositionLow);
Stream_Read_UINT32(s, cb_event->nPositionHigh);
Stream_Read_UINT32(s, cb_event->cbRequested);
//Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
static void cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_FILECONTENTS_RESPONSE_EVENT* cb_event;
cb_event = (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FilecontentsResponse, NULL, NULL);
Stream_Read_UINT32(s, cb_event->streamId);
WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsRequest");
if (length > 0)
if (context->custom)
{
cb_event->size = length - 4;
cb_event->data = (BYTE*) malloc(cb_event->size);
CopyMemory(cb_event->data, Stream_Pointer(s), cb_event->size);
CLIPRDR_FILE_CONTENTS_REQUEST request;
if (Stream_GetRemainingLength(s) < 28)
return -1;
request.msgType = CB_FILECONTENTS_REQUEST;
request.msgFlags = flags;
request.dataLen = length;
Stream_Read_UINT32(s, request.streamId); /* streamId (4 bytes) */
Stream_Read_UINT32(s, request.listIndex); /* listIndex (4 bytes) */
Stream_Read_UINT32(s, request.dwFlags); /* dwFlags (4 bytes) */
Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */
Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */
Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */
Stream_Read_UINT32(s, request.clipDataId); /* clipDataId (4 bytes) */
if (context->ServerFileContentsRequest)
context->ServerFileContentsRequest(context, &request);
}
else
{
RDP_CB_FILECONTENTS_REQUEST_EVENT* cb_event;
cb_event = (RDP_CB_FILECONTENTS_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FilecontentsRequest, NULL, NULL);
Stream_Read_UINT32(s, cb_event->streamId);
Stream_Read_UINT32(s, cb_event->lindex);
Stream_Read_UINT32(s, cb_event->dwFlags);
Stream_Read_UINT32(s, cb_event->nPositionLow);
Stream_Read_UINT32(s, cb_event->nPositionHigh);
Stream_Read_UINT32(s, cb_event->cbRequested);
//Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
return 1;
}
static void cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
static int cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_LOCK_CLIPDATA_EVENT* cb_event;
cb_event = (RDP_CB_LOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_LockClipdata, NULL, NULL);
Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsResponse");
if (context->custom)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response;
if (Stream_GetRemainingLength(s) < 4)
return -1;
response.msgType = CB_FILECONTENTS_RESPONSE;
response.msgFlags = flags;
response.dataLen = length;
Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */
response.cbRequested = length - 4;
response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */
if (context->ServerFileContentsResponse)
context->ServerFileContentsResponse(context, &response);
}
else
{
RDP_CB_FILECONTENTS_RESPONSE_EVENT* cb_event;
cb_event = (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FilecontentsResponse, NULL, NULL);
Stream_Read_UINT32(s, cb_event->streamId);
if (length > 0)
{
cb_event->size = length - 4;
cb_event->data = (BYTE*) malloc(cb_event->size);
CopyMemory(cb_event->data, Stream_Pointer(s), cb_event->size);
}
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
return 1;
}
static void cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
static int cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_UNLOCK_CLIPDATA_EVENT* cb_event;
cb_event = (RDP_CB_UNLOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_UnLockClipdata, NULL, NULL);
Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "LockClipData");
if (context->custom)
{
CLIPRDR_LOCK_CLIPBOARD_DATA lockClipboardData;
if (Stream_GetRemainingLength(s) < 4)
return -1;
lockClipboardData.msgType = CB_LOCK_CLIPDATA;
lockClipboardData.msgFlags = flags;
lockClipboardData.dataLen = length;
Stream_Read_UINT32(s, lockClipboardData.clipDataId); /* clipDataId (4 bytes) */
if (context->ServerLockClipboardData)
context->ServerLockClipboardData(context, &lockClipboardData);
}
else
{
RDP_CB_LOCK_CLIPDATA_EVENT* cb_event;
cb_event = (RDP_CB_LOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_LockClipdata, NULL, NULL);
Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
return 1;
}
static int cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData");
if (context->custom)
{
CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData;
if (Stream_GetRemainingLength(s) < 4)
return -1;
unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA;
unlockClipboardData.msgFlags = flags;
unlockClipboardData.dataLen = length;
Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */
if (context->ServerUnlockClipboardData)
context->ServerUnlockClipboardData(context, &unlockClipboardData);
}
else
{
RDP_CB_UNLOCK_CLIPDATA_EVENT* cb_event;
cb_event = (RDP_CB_UNLOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_UnLockClipdata, NULL, NULL);
Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
return 1;
}
static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
@ -296,6 +423,7 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
Stream_Read_UINT16(s, msgType);
Stream_Read_UINT16(s, msgFlags);
Stream_Read_UINT32(s, dataLen);
DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
#ifdef WITH_DEBUG_CLIPRDR
@ -452,18 +580,54 @@ int cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILIT
wStream* s;
CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */
Stream_Write_UINT16(s, 0); /* pad1 */
generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilities->capabilitySets;
Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType */
Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability */
Stream_Write_UINT32(s, generalCapabilitySet->version); /* version */
Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags */
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientCapabilities");
cliprdr_packet_send(cliprdr, s);
return 0;
}
int cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTORY* tempDirectory)
{
int length;
wStream* s;
WCHAR* wszTempDir = NULL;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 520 * 2);
length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, 0);
if (length < 0)
return -1;
if (length > 520)
length = 520;
Stream_Write(s, tempDirectory->szTempDir, length * 2);
Stream_Zero(s, (520 - length) * 2);
free(wszTempDir);
WLog_Print(cliprdr->log, WLOG_DEBUG, "TempDirectory: %s",
tempDirectory->szTempDir);
cliprdr_packet_send(cliprdr, s);
return 1;
}
int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
{
wStream* s;
@ -473,7 +637,7 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
CLIPRDR_FORMAT* format;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
for (index = 0; index < formatList->cFormats; index++)
for (index = 0; index < formatList->numFormats; index++)
{
format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
length += 4;
@ -487,7 +651,7 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);
for (index = 0; index < formatList->cFormats; index++)
for (index = 0; index < formatList->numFormats; index++)
{
format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
@ -499,7 +663,7 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
lpWideCharStr = (LPWSTR) Stream_Pointer(s);
cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2;
formatNameSize = MultiByteToWideChar(CP_UTF8, 0,
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
Stream_Seek(s, formatNameSize);
}
else
@ -508,7 +672,10 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
}
}
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatList: numFormats: %d",
formatList->numFormats);
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -516,23 +683,67 @@ int cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_F
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
formatListResponse->msgType = CB_FORMAT_LIST_RESPONSE;
formatListResponse->dataLen = 0;
s = cliprdr_packet_new(formatListResponse->msgType, formatListResponse->msgFlags, formatListResponse->dataLen);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatListResponse");
cliprdr_packet_send(cliprdr, s);
return 0;
}
int cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
Stream_Write_UINT32(s, lockClipboardData->clipDataId); /* clipDataId (4 bytes) */
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientLockClipboardData: clipDataId: 0x%04X",
lockClipboardData->clipDataId);
cliprdr_packet_send(cliprdr, s);
return 1;
}
int cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
Stream_Write_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientUnlockClipboardData: clipDataId: 0x%04X",
unlockClipboardData->clipDataId);
cliprdr_packet_send(cliprdr, s);
return 1;
}
int cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
formatDataRequest->msgType = CB_FORMAT_DATA_REQUEST;
formatDataRequest->msgFlags = 0;
formatDataRequest->dataLen = 4;
s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, formatDataRequest->dataLen);
Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataRequest");
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -540,13 +751,71 @@ int cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_F
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
formatDataResponse->msgType = CB_FORMAT_DATA_RESPONSE;
s = cliprdr_packet_new(formatDataResponse->msgType, formatDataResponse->msgFlags, formatDataResponse->dataLen);
Stream_Write(s, formatDataResponse->requestedFormatData, formatDataResponse->dataLen);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataResponse");
cliprdr_packet_send(cliprdr, s);
return 0;
}
int cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 28);
Stream_Write_UINT32(s, fileContentsRequest->streamId); /* streamId (4 bytes) */
Stream_Write_UINT32(s, fileContentsRequest->listIndex); /* listIndex (4 bytes) */
Stream_Write_UINT32(s, fileContentsRequest->dwFlags); /* dwFlags (4 bytes) */
Stream_Write_UINT32(s, fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */
Stream_Write_UINT32(s, fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */
Stream_Write_UINT32(s, fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */
Stream_Write_UINT32(s, fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFileContentsRequest: streamId: 0x%04X",
fileContentsRequest->streamId);
cliprdr_packet_send(cliprdr, s);
return 1;
}
int cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
if (fileContentsResponse->dwFlags & FILECONTENTS_SIZE)
fileContentsResponse->cbRequested = sizeof(UINT64);
s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0,
4 + fileContentsResponse->cbRequested);
Stream_Write_UINT32(s, fileContentsResponse->streamId); /* streamId (4 bytes) */
/**
* requestedFileContentsData:
* FILECONTENTS_SIZE: file size as UINT64
* FILECONTENTS_RANGE: file data from requested range
*/
Stream_Write(s, fileContentsResponse->requestedData, fileContentsResponse->cbRequested);
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFileContentsResponse: streamId: 0x%04X",
fileContentsResponse->streamId);
cliprdr_packet_send(cliprdr, s);
return 1;
}
/* cliprdr is always built-in */
#define VirtualChannelEntry cliprdr_VirtualChannelEntry
@ -555,17 +824,24 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
cliprdrPlugin* cliprdr;
CliprdrClientContext* context;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin));
cliprdr->plugin.channel_def.options =
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(cliprdr->plugin.channel_def.name, "cliprdr");
cliprdr->log = WLog_Get("com.freerdp.channels.cliprdr.client");
cliprdr->plugin.connect_callback = cliprdr_process_connect;
cliprdr->plugin.receive_callback = cliprdr_process_receive;
cliprdr->plugin.event_callback = cliprdr_process_event;
cliprdr->plugin.terminate_callback = cliprdr_process_terminate;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
@ -574,10 +850,15 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext));
context->handle = (void*) cliprdr;
context->ClientCapabilities = cliprdr_client_capabilities;
context->TempDirectory = cliprdr_temp_directory;
context->ClientFormatList = cliprdr_client_format_list;
context->ClientFormatListResponse = cliprdr_client_format_list_response;
context->ClientLockClipboardData = cliprdr_client_lock_clipboard_data;
context->ClientUnlockClipboardData = cliprdr_client_unlock_clipboard_data;
context->ClientFormatDataRequest = cliprdr_client_format_data_request;
context->ClientFormatDataResponse = cliprdr_client_format_data_response;
context->ClientFileContentsRequest = cliprdr_client_file_contents_request;
context->ClientFileContentsResponse = cliprdr_client_file_contents_response;
*(pEntryPointsEx->ppInterface) = (void*) context;
}

View File

@ -31,6 +31,8 @@
struct cliprdr_plugin
{
rdpSvcPlugin plugin;
wLog* log;
BOOL received_caps;
BOOL use_long_format_names;
BOOL stream_fileclip_enabled;

View File

@ -141,8 +141,8 @@ void android_cliprdr_init(freerdp* inst)
cb->channels = inst->context->channels;
cb->android_formats = (UINT32*)malloc(sizeof(UINT32) * 3);
cb->android_formats[0] = CB_FORMAT_TEXT;
cb->android_formats[1] = CB_FORMAT_UNICODETEXT;
cb->android_formats[0] = CF_TEXT;
cb->android_formats[1] = CF_UNICODETEXT;
cb->android_formats[2] = CB_FORMAT_HTML;
cb->android_num_formats = 3;
@ -381,21 +381,18 @@ static void android_cliprdr_process_cb_data_request_event(clipboardContext* cb,
switch (event->format)
{
case CB_FORMAT_RAW:
case CB_FORMAT_PNG:
case CB_FORMAT_JPEG:
case CB_FORMAT_GIF:
case CB_FORMAT_DIB:
case 0:
case CF_DIB:
default:
DEBUG_ANDROID("unsupported format %x\n", event->format);
outbuf = NULL;
break;
case CB_FORMAT_UNICODETEXT:
case CF_UNICODETEXT:
outbuf = android_cliprdr_process_requested_unicodetext(cb->android_data, &size);
break;
case CB_FORMAT_TEXT:
case CF_TEXT:
outbuf = android_cliprdr_process_requested_text(cb->android_data, &size);
break;
@ -436,21 +433,21 @@ static void android_cliprdr_process_cb_format_list_event(clipboardContext* cb, R
if (cb->formats)
free(cb->formats);
cb->data_format = CB_FORMAT_RAW;
cb->data_format = 0;
cb->formats = event->formats;
cb->num_formats = event->num_formats;
event->formats = NULL;
event->num_formats = 0;
if (android_cliprdr_has_format(cb->formats, cb->num_formats, CB_FORMAT_TEXT))
if (android_cliprdr_has_format(cb->formats, cb->num_formats, CF_TEXT))
{
cb->data_format = CB_FORMAT_TEXT;
android_cliprdr_send_data_request(cb, CB_FORMAT_TEXT);
cb->data_format = CF_TEXT;
android_cliprdr_send_data_request(cb, CF_TEXT);
}
else if (android_cliprdr_has_format(cb->formats, cb->num_formats, CB_FORMAT_UNICODETEXT))
else if (android_cliprdr_has_format(cb->formats, cb->num_formats, CF_UNICODETEXT))
{
cb->data_format = CB_FORMAT_UNICODETEXT;
android_cliprdr_send_data_request(cb, CB_FORMAT_UNICODETEXT);
cb->data_format = CF_UNICODETEXT;
android_cliprdr_send_data_request(cb, CF_UNICODETEXT);
}
else if (android_cliprdr_has_format(cb->formats, cb->num_formats, CB_FORMAT_HTML))
{
@ -518,20 +515,17 @@ static void android_cliprdr_process_cb_data_response_event(clipboardContext* cb,
}
switch (cb->data_format)
{
case CB_FORMAT_RAW:
case CB_FORMAT_PNG:
case CB_FORMAT_JPEG:
case CB_FORMAT_GIF:
case CB_FORMAT_DIB:
case 0:
case CF_DIB:
default:
DEBUG_ANDROID("unsupported format\n");
break;
case CB_FORMAT_TEXT:
case CF_TEXT:
android_cliprdr_process_text(cb, event->data, event->size - 1);
break;
case CB_FORMAT_UNICODETEXT:
case CF_UNICODETEXT:
android_cliprdr_process_unicodetext(cb, event->data, event->size - 2);
break;

View File

@ -944,10 +944,10 @@ BOOL mac_post_connect(freerdp* instance)
flags = CLRCONV_ALPHA | CLRCONV_RGB555;
if (settings->ColorDepth > 16)
//if (settings->ColorDepth > 16)
flags |= CLRBUF_32BPP;
else
flags |= CLRBUF_16BPP;
//else
// flags |= CLRBUF_16BPP;
gdi_init(instance, flags, NULL);
gdi = instance->context->gdi;
@ -1021,13 +1021,9 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
cursor_data = (BYTE*) malloc(rect.size.width * rect.size.height * 4);
mrdpCursor->cursor_data = cursor_data;
if (pointer->xorBpp > 24)
{
freerdp_image_swap_color_order(pointer->xorMaskData, pointer->width, pointer->height);
}
freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData,
pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv);
freerdp_image_copy_from_pointer_data(cursor_data, PIXEL_FORMAT_ARGB32,
pointer->width * 4, 0, 0, pointer->width, pointer->height,
pointer->xorMaskData, pointer->andMaskData, pointer->xorBpp, NULL);
/* store cursor bitmap image in representation - required by NSImage */
bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &cursor_data
@ -1120,17 +1116,17 @@ CGContextRef mac_create_bitmap_context(rdpContext* context)
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (gdi->dstBpp == 16)
if (gdi->bytesPerPixel == 2)
{
bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
gdi->width, gdi->height, 5, gdi->width * 2, colorSpace,
kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
gdi->width, gdi->height, 5, gdi->width * gdi->bytesPerPixel,
colorSpace, kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
}
else
{
bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
gdi->width, gdi->height, 8, gdi->width * 4, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
gdi->width, gdi->height, 8, gdi->width * gdi->bytesPerPixel,
colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
}
CGColorSpaceRelease(colorSpace);
@ -1353,8 +1349,8 @@ void cliprdr_send_data_request(freerdp* instance, UINT32 format)
/**
* at the moment, only the following formats are supported
* CB_FORMAT_TEXT
* CB_FORMAT_UNICODETEXT
* CF_TEXT
* CF_UNICODETEXT
*/
void cliprdr_process_cb_data_response_event(freerdp* instance, RDP_CB_DATA_RESPONSE_EVENT* event)
@ -1367,7 +1363,7 @@ void cliprdr_process_cb_data_response_event(freerdp* instance, RDP_CB_DATA_RESPO
if (event->size == 0)
return;
if (view->pasteboard_format == CB_FORMAT_TEXT || view->pasteboard_format == CB_FORMAT_UNICODETEXT)
if (view->pasteboard_format == CF_TEXT || view->pasteboard_format == CF_UNICODETEXT)
{
str = [[NSString alloc] initWithCharacters:(unichar *) event->data length:event->size / 2];
types = [[NSArray alloc] initWithObjects:NSStringPboardType, nil];
@ -1391,8 +1387,8 @@ void cliprdr_process_cb_monitor_ready_event(freerdp* instance)
/**
* list of supported clipboard formats; currently only the following are supported
* CB_FORMAT_TEXT
* CB_FORMAT_UNICODETEXT
* CF_TEXT
* CF_UNICODETEXT
*/
void cliprdr_process_cb_format_list_event(freerdp* instance, RDP_CB_FORMAT_LIST_EVENT* event)
@ -1408,36 +1404,12 @@ void cliprdr_process_cb_format_list_event(freerdp* instance, RDP_CB_FORMAT_LIST_
{
switch (event->formats[i])
{
case CB_FORMAT_RAW:
WLog_ERR(TAG, "CB_FORMAT_RAW: not yet supported");
break;
case CB_FORMAT_TEXT:
case CB_FORMAT_UNICODETEXT:
view->pasteboard_format = CB_FORMAT_UNICODETEXT;
cliprdr_send_data_request(instance, CB_FORMAT_UNICODETEXT);
case CF_TEXT:
case CF_UNICODETEXT:
view->pasteboard_format = CF_UNICODETEXT;
cliprdr_send_data_request(instance, CF_UNICODETEXT);
return;
break;
case CB_FORMAT_DIB:
WLog_ERR(TAG, "CB_FORMAT_DIB: not yet supported");
break;
case CB_FORMAT_HTML:
WLog_ERR(TAG, "CB_FORMAT_HTML");
break;
case CB_FORMAT_PNG:
WLog_ERR(TAG, "CB_FORMAT_PNG: not yet supported");
break;
case CB_FORMAT_JPEG:
WLog_ERR(TAG, "CB_FORMAT_JPEG: not yet supported");
break;
case CB_FORMAT_GIF:
WLog_ERR(TAG, "CB_FORMAT_GIF: not yet supported");
break;
}
}
}
@ -1501,7 +1473,7 @@ void cliprdr_send_supported_format_list(freerdp* instance)
event->formats = (UINT32*) malloc(sizeof(UINT32) * 1);
event->num_formats = 1;
event->formats[0] = CB_FORMAT_UNICODETEXT;
event->formats[0] = CF_UNICODETEXT;
freerdp_channels_send_event(instance->context->channels, (wMessage*) event);
}

View File

@ -19,12 +19,6 @@ set(MODULE_NAME "wfreerdp-client")
set(MODULE_PREFIX "FREERDP_CLIENT_WINDOWS_CONTROL")
set(${MODULE_PREFIX}_SRCS
wf_cliprdr_DataObject.c
wf_cliprdr_DataObject.h
wf_cliprdr_EnumFORMATETC.c
wf_cliprdr_EnumFORMATETC.h
wf_cliprdr_Stream.c
wf_cliprdr_Stream.h
wf_gdi.c
wf_gdi.h
wf_event.c

View File

@ -30,7 +30,6 @@
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/event.h>
#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>

View File

@ -22,6 +22,9 @@
#include "wf_channels.h"
#include "wf_rail.h"
#include "wf_cliprdr.h"
#include <freerdp/gdi/gfx.h>
void wf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
@ -38,6 +41,14 @@ void wf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0)
{
wf_rail_init(wfc, (RailClientContext*) e->pInterface);
}
else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
{
wf_cliprdr_init(wfc, (CliprdrClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
@ -58,6 +69,14 @@ void wf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnect
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0)
{
wf_rail_uninit(wfc, (RailClientContext*) e->pInterface);
}
else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
{
wf_cliprdr_uninit(wfc, (CliprdrClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{

View File

@ -24,6 +24,7 @@
#include <freerdp/client/rdpei.h>
#include <freerdp/client/rdpgfx.h>
#include <freerdp/client/encomsp.h>
#include <freerdp/client/cliprdr.h>
#include "wf_client.h"

View File

@ -37,16 +37,17 @@
#include <sys/types.h>
#include <freerdp/log.h>
#include <freerdp/event.h>
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/event.h>
#include <freerdp/codec/region.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
#include <freerdp/event.h>
#include "wf_gdi.h"
#include "wf_rail.h"
#include "wf_channels.h"
#include "wf_graphics.h"
#include "wf_cliprdr.h"
@ -79,34 +80,50 @@ void wf_sw_end_paint(wfContext* wfc)
{
int i;
rdpGdi* gdi;
INT32 x, y;
UINT32 w, h;
int ninvalid;
RECT update_rect;
RECT updateRect;
HGDI_RGN cinvalid;
REGION16 invalidRegion;
RECTANGLE_16 invalidRect;
const RECTANGLE_16* extents;
rdpContext* context = (rdpContext*) wfc;
gdi = ((rdpContext*) wfc)->gdi;
if (gdi->primary->hdc->hwnd->ninvalid < 1)
return;
gdi = context->gdi;
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
if (ninvalid < 1)
return;
region16_init(&invalidRegion);
for (i = 0; i < ninvalid; i++)
{
x = cinvalid[i].x;
y = cinvalid[i].y;
w = cinvalid[i].w;
h = cinvalid[i].h;
invalidRect.left = cinvalid[i].x;
invalidRect.top = cinvalid[i].y;
invalidRect.right = cinvalid[i].x + cinvalid[i].w;
invalidRect.bottom = cinvalid[i].y + cinvalid[i].h;
update_rect.left = x;
update_rect.top = y;
update_rect.right = x + w;
update_rect.bottom = y + h;
InvalidateRect(wfc->hwnd, &update_rect, FALSE);
region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect);
}
if (!region16_is_empty(&invalidRegion))
{
extents = region16_extents(&invalidRegion);
updateRect.left = extents->left;
updateRect.top = extents->top;
updateRect.right = extents->right;
updateRect.bottom = extents->bottom;
InvalidateRect(wfc->hwnd, &updateRect, FALSE);
if (wfc->rail)
wf_rail_invalidate_region(wfc, &invalidRegion);
}
region16_uninit(&invalidRegion);
}
void wf_sw_desktop_resize(wfContext* wfc)
@ -406,7 +423,7 @@ BOOL wf_post_connect(freerdp* instance)
wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName, dwStyle,
0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL);
SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc);
SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc);
}
wf_resize_window(wfc);
@ -451,8 +468,6 @@ BOOL wf_post_connect(freerdp* instance)
freerdp_channels_post_connect(context->channels, instance);
wf_cliprdr_init(wfc, context->channels);
if (wfc->fullscreen)
floatbar_window_create(wfc);
@ -544,30 +559,6 @@ int wf_receive_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
}
void wf_process_channel_event(rdpChannels* channels, freerdp* instance)
{
wfContext* wfc;
wMessage* event;
wfc = (wfContext*) instance->context;
event = freerdp_channels_pop_event(channels);
if (event)
{
switch (GetMessageClass(event->id))
{
case CliprdrChannel_Class:
wf_process_cliprdr_event(wfc, event);
break;
default:
break;
}
freerdp_event_free(event);
}
}
BOOL wf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
{
return TRUE;
@ -659,7 +650,6 @@ void* wf_channels_thread(void* arg)
HANDLE event;
rdpChannels* channels;
freerdp* instance = (freerdp*) arg;
assert(NULL != instance);
channels = instance->context->channels;
event = freerdp_channels_get_event_handle(instance);
@ -667,10 +657,9 @@ void* wf_channels_thread(void* arg)
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
status = freerdp_channels_process_pending_messages(instance);
if (!status)
break;
wf_process_channel_event(channels, instance);
}
ExitThread(0);
@ -819,8 +808,6 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
WLog_ERR(TAG, "Failed to check channel manager file descriptor");
break;
}
wf_process_channel_event(channels, instance);
}
quit_msg = FALSE;
@ -1139,8 +1126,9 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
instance->ReceiveChannelData = wf_receive_channel_data;
wfc->instance = instance;
wfc->settings = instance->settings;
context->channels = freerdp_channels_new();
return 0;
}

View File

@ -24,6 +24,8 @@
#include <winpr/windows.h>
#include <winpr/collections.h>
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/gdi/gdi.h>
@ -32,13 +34,18 @@
#include <freerdp/cache/cache.h>
#include <freerdp/codec/color.h>
#include <freerdp/client/rail.h>
#include <freerdp/channels/channels.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/codec/nsc.h>
#include <freerdp/client/file.h>
typedef struct wf_context wfContext;
#include "wf_channels.h"
#include "wf_floatbar.h"
#include "wf_event.h"
#include "wf_cliprdr.h"
#ifdef __cplusplus
extern "C" {
@ -64,12 +71,13 @@ struct wf_pointer
};
typedef struct wf_pointer wfPointer;
typedef struct cliprdr_context cliprdrContext;
struct wf_context
{
rdpContext context;
DEFINE_RDP_CLIENT_COMMON();
rdpSettings* settings;
int width;
int height;
int offset_x;
@ -114,29 +122,29 @@ struct wf_context
DWORD mainThreadId;
DWORD keyboardThreadId;
//BOOL sw_gdi;
rdpFile* connectionRdpFile;
// Keep track of window size and position, disable when in fullscreen mode.
BOOL disablewindowtracking;
// These variables are required for horizontal scrolling.
BOOL updating_scrollbars;
BOOL xScrollVisible;
int xMinScroll; // minimum horizontal scroll value
int xCurrentScroll; // current horizontal scroll value
int xMaxScroll; // maximum horizontal scroll value
int xMinScroll;
int xCurrentScroll;
int xMaxScroll;
// These variables are required for vertical scrolling.
BOOL yScrollVisible;
int yMinScroll; // minimum vertical scroll value
int yCurrentScroll; // current vertical scroll value
int yMaxScroll; // maximum vertical scroll value
cliprdrContext *cliprdr_context;
int yMinScroll;
int yCurrentScroll;
int yMaxScroll;
wfClipboard* clipboard;
CliprdrClientContext* cliprdr;
FloatBar* floatbar;
RailClientContext* rail;
wHashTable* railWindows;
};
typedef struct wf_context wfContext;
/**
* Client Interface

File diff suppressed because it is too large Load Diff

View File

@ -25,40 +25,90 @@
#include <Ole2.h>
#include <ShlObj.h>
typedef struct wf_clipboard wfClipboard;
#include "wf_client.h"
#include <freerdp/log.h>
#define TAG CLIENT_TAG(WIN_CLIPRDR_TAG)
#ifdef WITH_DEBUG_CLIPRDR
#define DEBUG_CLIPRDR(fmt, ...) WLog_DBG(WIN_CLIPRDR_TAG, fmt, ## __VA_ARGS__)
#define DEBUG_CLIPRDR(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
#else
#define DEBUG_CLIPRDR(fmt, ...) do { } while (0)
#endif
typedef struct format_mapping formatMapping;
struct format_mapping {
struct _CliprdrStream
{
IStream iStream;
LONG m_lRefCount;
LONG m_lIndex;
ULARGE_INTEGER m_lSize;
ULARGE_INTEGER m_lOffset;
void* m_pData;
};
typedef struct _CliprdrStream CliprdrStream;
CliprdrStream* CliprdrStream_New(LONG index, void* pData);
void CliprdrStream_Delete(CliprdrStream* instance);
struct _CliprdrDataObject
{
IDataObject iDataObject;
LONG m_lRefCount;
FORMATETC* m_pFormatEtc;
STGMEDIUM* m_pStgMedium;
LONG m_nNumFormats;
LONG m_nStreams;
IStream** m_pStream;
void* m_pData;
};
typedef struct _CliprdrDataObject CliprdrDataObject;
CliprdrDataObject* CliprdrDataObject_New(FORMATETC* fmtetc, STGMEDIUM* stgmed, int count, void* data);
void CliprdrDataObject_Delete(CliprdrDataObject* instance);
struct _CliprdrEnumFORMATETC
{
IEnumFORMATETC iEnumFORMATETC;
LONG m_lRefCount;
LONG m_nIndex;
LONG m_nNumFormats;
FORMATETC* m_pFormatEtc;
};
typedef struct _CliprdrEnumFORMATETC CliprdrEnumFORMATETC;
CliprdrEnumFORMATETC* CliprdrEnumFORMATETC_New(int nFormats, FORMATETC* pFormatEtc);
void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC* This);
struct format_mapping
{
UINT32 remote_format_id;
UINT32 local_format_id;
void *name; /* Unicode or ASCII characters with NULL terminate */
void* name; /* Unicode or ASCII characters with NULL terminator */
};
typedef struct format_mapping formatMapping;
typedef struct cliprdr_context cliprdrContext;
struct cliprdr_context {
rdpChannels *channels;
struct wf_clipboard
{
wfContext* wfc;
rdpChannels* channels;
CliprdrClientContext* context;
BOOL sync;
UINT32 capabilities;
formatMapping *format_mappings;
int map_capacity;
int map_size;
int map_capacity;
formatMapping* format_mappings;
UINT32 request_format;
BOOL channel_initialized;
UINT32 requestedFormatId;
HWND hwndClipboard;
HANDLE cliprdr_thread;
HWND hwnd;
HANDLE hmem;
HANDLE thread;
HANDLE response_data_event;
/* file clipping */
@ -68,29 +118,22 @@ struct cliprdr_context {
LPDATAOBJECT data_obj;
ULONG req_fsize;
char *req_fdata;
char* req_fdata;
HANDLE req_fevent;
int nFiles;
int file_array_size;
wchar_t **file_names;
FILEDESCRIPTORW **fileDescriptor;
WCHAR** file_names;
FILEDESCRIPTORW** fileDescriptor;
};
void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels);
void wf_cliprdr_uninit(wfContext* wfc);
void wf_process_cliprdr_event(wfContext* wfc, wMessage* event);
BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfContext* wfc);
void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr);
void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr);
int cliprdr_send_data_request(cliprdrContext *cliprdr, UINT32 format);
int cliprdr_send_lock(cliprdrContext *cliprdr);
int cliprdr_send_unlock(cliprdrContext *cliprdr);
int cliprdr_send_request_filecontents(cliprdrContext *cliprdr, void *streamid,
int index, int flag, DWORD positionhigh,
DWORD positionlow, ULONG request);
int cliprdr_send_data_request(wfClipboard* clipboard, UINT32 format);
int cliprdr_send_lock(wfClipboard* clipboard);
int cliprdr_send_unlock(wfClipboard* clipboard);
int cliprdr_send_request_filecontents(wfClipboard* clipboard, void* streamid,
int index, int flag, DWORD positionhigh, DWORD positionlow, ULONG request);
#endif /* __WF_CLIPRDR_H */

View File

@ -1,361 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Implementation of the IDataObject COM interface
*
* Copyright 2014 Zhang Zhaolong <zhangzl2013@126.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wf_cliprdr.h"
#include "wf_cliprdr_Stream.h"
#include "wf_cliprdr_DataObject.h"
#include "wf_cliprdr_EnumFORMATETC.h"
static int cliprdr_lookup_format(CliprdrDataObject *instance, FORMATETC *pFormatEtc)
{
int i;
for (i = 0; i < instance->m_nNumFormats; i++)
{
if((pFormatEtc->tymed & instance->m_pFormatEtc[i].tymed) &&
pFormatEtc->cfFormat == instance->m_pFormatEtc[i].cfFormat &&
pFormatEtc->dwAspect == instance->m_pFormatEtc[i].dwAspect)
{
return i;
}
}
return -1;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryInterface(IDataObject *This, REFIID riid, void **ppvObject)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
{
IDataObject_AddRef(This);
*ppvObject = This;
return S_OK;
}
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE CliprdrDataObject_AddRef(IDataObject *This)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
return InterlockedIncrement(&instance->m_lRefCount);
}
ULONG STDMETHODCALLTYPE CliprdrDataObject_Release(IDataObject *This)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
LONG count;
count = InterlockedDecrement(&instance->m_lRefCount);
if(count == 0)
{
CliprdrDataObject_Delete(instance);
return 0;
}
else
{
return count;
}
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject *This, FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
cliprdrContext *cliprdr = (cliprdrContext *)instance->m_pData;
int idx;
int i;
if (pFormatEtc == NULL || pMedium == NULL)
{
return E_INVALIDARG;
}
if((idx = cliprdr_lookup_format(instance, pFormatEtc)) == -1)
{
return DV_E_FORMATETC;
}
pMedium->tymed = instance->m_pFormatEtc[idx].tymed;
pMedium->pUnkForRelease = 0;
if (instance->m_pFormatEtc[idx].cfFormat == cliprdr->ID_FILEDESCRIPTORW)
{
if (cliprdr_send_data_request(cliprdr, instance->m_pFormatEtc[idx].cfFormat) != 0)
return E_UNEXPECTED;
pMedium->hGlobal = cliprdr->hmem; /* points to a FILEGROUPDESCRIPTOR structure */
/* GlobalLock returns a pointer to the first byte of the memory block,
* in which is a FILEGROUPDESCRIPTOR structure, whose first UINT member
* is the number of FILEDESCRIPTOR's */
instance->m_nStreams = *(PUINT)GlobalLock(cliprdr->hmem);
GlobalUnlock(cliprdr->hmem);
if (instance->m_nStreams > 0)
{
if (!instance->m_pStream)
{
instance->m_pStream = (LPSTREAM *)calloc(instance->m_nStreams, sizeof(LPSTREAM));
if (instance->m_pStream)
for(i = 0; i < instance->m_nStreams; i++)
instance->m_pStream[i] = (IStream *)CliprdrStream_New(i, cliprdr);
}
}
if (!instance->m_pStream)
{
cliprdr->hmem = GlobalFree(cliprdr->hmem);
pMedium->hGlobal = cliprdr->hmem;
return E_OUTOFMEMORY;
}
}
else if (instance->m_pFormatEtc[idx].cfFormat == cliprdr->ID_FILECONTENTS)
{
if (pFormatEtc->lindex < instance->m_nStreams)
{
pMedium->pstm = instance->m_pStream[pFormatEtc->lindex];
IDataObject_AddRef(instance->m_pStream[pFormatEtc->lindex]);
}
else
{
return E_INVALIDARG;
}
}
else if (instance->m_pFormatEtc[idx].cfFormat == cliprdr->ID_PREFERREDDROPEFFECT)
{
if (cliprdr_send_data_request(cliprdr, instance->m_pFormatEtc[idx].cfFormat) != 0)
return E_UNEXPECTED;
pMedium->hGlobal = cliprdr->hmem;
}
else
{
return E_UNEXPECTED;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetDataHere(IDataObject *This, FORMATETC *pformatetc, STGMEDIUM *pmedium)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
return DATA_E_FORMATETC;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryGetData(IDataObject *This, FORMATETC *pformatetc)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
if (!pformatetc)
return E_INVALIDARG;
return (cliprdr_lookup_format(instance, pformatetc) == -1) ? DV_E_FORMATETC : S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(IDataObject *This, FORMATETC *pformatectIn, FORMATETC *pformatetcOut)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
if (!pformatetcOut)
return E_INVALIDARG;
pformatetcOut->ptd = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_SetData(IDataObject *This, FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumFormatEtc(IDataObject *This, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
if (!ppenumFormatEtc)
return E_INVALIDARG;
if(dwDirection == DATADIR_GET)
{
*ppenumFormatEtc = (IEnumFORMATETC *)CliprdrEnumFORMATETC_New(instance->m_nNumFormats, instance->m_pFormatEtc);
return (*ppenumFormatEtc) ? S_OK : E_OUTOFMEMORY;
}
else
{
return E_NOTIMPL;
}
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_DAdvise(IDataObject *This, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
return OLE_E_ADVISENOTSUPPORTED;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_DUnadvise(IDataObject *This, DWORD dwConnection)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
return OLE_E_ADVISENOTSUPPORTED;
}
HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumDAdvise(IDataObject *This, IEnumSTATDATA **ppenumAdvise)
{
CliprdrDataObject *instance = (CliprdrDataObject *)This;
return OLE_E_ADVISENOTSUPPORTED;
}
CliprdrDataObject *CliprdrDataObject_New(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count, void *data)
{
CliprdrDataObject *instance;
IDataObject *iDataObject;
int i;
instance = (CliprdrDataObject *)calloc(1, sizeof(CliprdrDataObject));
if (instance)
{
iDataObject = &instance->iDataObject;
iDataObject->lpVtbl = (IDataObjectVtbl *)calloc(1, sizeof(IDataObjectVtbl));
if (iDataObject->lpVtbl)
{
iDataObject->lpVtbl->QueryInterface = CliprdrDataObject_QueryInterface;
iDataObject->lpVtbl->AddRef = CliprdrDataObject_AddRef;
iDataObject->lpVtbl->Release = CliprdrDataObject_Release;
iDataObject->lpVtbl->GetData = CliprdrDataObject_GetData;
iDataObject->lpVtbl->GetDataHere = CliprdrDataObject_GetDataHere;
iDataObject->lpVtbl->QueryGetData = CliprdrDataObject_QueryGetData;
iDataObject->lpVtbl->GetCanonicalFormatEtc = CliprdrDataObject_GetCanonicalFormatEtc;
iDataObject->lpVtbl->SetData = CliprdrDataObject_SetData;
iDataObject->lpVtbl->EnumFormatEtc = CliprdrDataObject_EnumFormatEtc;
iDataObject->lpVtbl->DAdvise = CliprdrDataObject_DAdvise;
iDataObject->lpVtbl->DUnadvise = CliprdrDataObject_DUnadvise;
iDataObject->lpVtbl->EnumDAdvise = CliprdrDataObject_EnumDAdvise;
instance->m_lRefCount = 1;
instance->m_nNumFormats = count;
instance->m_pData = data;
instance->m_nStreams = 0;
instance->m_pStream = NULL;
instance->m_pFormatEtc = (FORMATETC *)calloc(count, sizeof(FORMATETC));
instance->m_pStgMedium = (STGMEDIUM *)calloc(count, sizeof(STGMEDIUM));
for(i = 0; i < count; i++)
{
instance->m_pFormatEtc[i] = fmtetc[i];
instance->m_pStgMedium[i] = stgmed[i];
}
}
else
{
free(instance);
instance = NULL;
}
}
return instance;
}
void CliprdrDataObject_Delete(CliprdrDataObject *instance)
{
if (instance)
{
if (instance->iDataObject.lpVtbl)
free(instance->iDataObject.lpVtbl);
if (instance->m_pFormatEtc)
free(instance->m_pFormatEtc);
if (instance->m_pStgMedium)
free(instance->m_pStgMedium);
if(instance->m_pStream)
{
int i;
for (i = 0; i < instance->m_nStreams; i++)
CliprdrStream_Release(instance->m_pStream[i]);
free(instance->m_pStream);
}
free(instance);
}
}
BOOL wf_create_file_obj(cliprdrContext *cliprdr, IDataObject **ppDataObject)
{
FORMATETC fmtetc[3];
STGMEDIUM stgmeds[3];
if(!ppDataObject)
return FALSE;
fmtetc[0].cfFormat = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW);
fmtetc[0].dwAspect = DVASPECT_CONTENT;
fmtetc[0].lindex = 0;
fmtetc[0].ptd = NULL;
fmtetc[0].tymed = TYMED_HGLOBAL;
stgmeds[0].tymed = TYMED_HGLOBAL;
stgmeds[0].hGlobal = NULL;
stgmeds[0].pUnkForRelease = NULL;
fmtetc[1].cfFormat = RegisterClipboardFormatW(CFSTR_FILECONTENTS);
fmtetc[1].dwAspect = DVASPECT_CONTENT;
fmtetc[1].lindex = 0;
fmtetc[1].ptd = NULL;
fmtetc[1].tymed = TYMED_ISTREAM;
stgmeds[1].tymed = TYMED_ISTREAM;
stgmeds[1].pstm = NULL;
stgmeds[1].pUnkForRelease = NULL;
fmtetc[2].cfFormat = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT);
fmtetc[2].dwAspect = DVASPECT_CONTENT;
fmtetc[2].lindex = 0;
fmtetc[2].ptd = NULL;
fmtetc[2].tymed = TYMED_HGLOBAL;
stgmeds[2].tymed = TYMED_HGLOBAL;
stgmeds[2].hGlobal = NULL;
stgmeds[2].pUnkForRelease = NULL;
*ppDataObject = (IDataObject *)CliprdrDataObject_New(fmtetc, stgmeds, 3, cliprdr);
return (*ppDataObject) ? TRUE : FALSE;
}
void wf_destroy_file_obj(IDataObject *instance)
{
if(instance)
IDataObject_Release(instance);
}

View File

@ -1,59 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Implementation of the IDataObject COM interface
*
* Copyright 2014 Zhang Zhaolong <zhangzl2013@126.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __WF_CLIPRDR_DATAOBJECT_H__
#define __WF_CLIPRDR_DATAOBJECT_H__
#define CINTERFACE
#define COBJMACROS
#include <windows.h>
#include <Ole2.h>
#include <ShlObj.h>
typedef struct _CliprdrDataObject {
IDataObject iDataObject;
// private
LONG m_lRefCount;
FORMATETC *m_pFormatEtc;
STGMEDIUM *m_pStgMedium;
LONG m_nNumFormats;
LONG m_nStreams;
IStream **m_pStream;
void *m_pData;
}CliprdrDataObject;
CliprdrDataObject *CliprdrDataObject_New(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count, void *data);
void CliprdrDataObject_Delete(CliprdrDataObject *instance);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryInterface(IDataObject *This, REFIID riid, void **ppvObject);
ULONG STDMETHODCALLTYPE CliprdrDataObject_AddRef(IDataObject *This);
ULONG STDMETHODCALLTYPE CliprdrDataObject_Release(IDataObject *This);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject *This, FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetDataHere(IDataObject *This, FORMATETC *pformatetc, STGMEDIUM *pmedium);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryGetData(IDataObject *This, FORMATETC *pformatetc);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(IDataObject *This, FORMATETC *pformatectIn, FORMATETC *pformatetcOut);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_SetData(IDataObject *This, FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumFormatEtc(IDataObject *This, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_DAdvise(IDataObject *This, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_DUnadvise(IDataObject *This, DWORD dwConnection);
HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumDAdvise(IDataObject *This, IEnumSTATDATA **ppenumAdvise);
#endif // __WF_CLIPRDR_DATAOBJECT_H__

View File

@ -1,200 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Implementation of the IEnumFORMATETC COM interface
*
* Copyright 2014 Zhang Zhaolong <zhangzl2013@126.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "wf_cliprdr_EnumFORMATETC.h"
static void cliprdr_format_deep_copy(FORMATETC *dest, FORMATETC *source)
{
*dest = *source;
if (source->ptd)
{
dest->ptd = (DVTARGETDEVICE *)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
*(dest->ptd) = *(source->ptd);
}
}
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_QueryInterface(IEnumFORMATETC *This, REFIID riid, void **ppvObject)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
if (IsEqualIID(riid, &IID_IEnumFORMATETC) || IsEqualIID(riid, &IID_IUnknown))
{
IEnumFORMATETC_AddRef(This);
*ppvObject = This;
return S_OK;
}
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_AddRef(IEnumFORMATETC *This)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
return InterlockedIncrement(&instance->m_lRefCount);
}
ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_Release(IEnumFORMATETC *This)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
LONG count;
count = InterlockedDecrement(&instance->m_lRefCount);
if(count == 0)
{
CliprdrEnumFORMATETC_Delete(instance);
return 0;
}
else
{
return count;
}
}
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Next(IEnumFORMATETC *This, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
ULONG copied = 0;
if (celt == 0 || !rgelt)
return E_INVALIDARG;
while (instance->m_nIndex < instance->m_nNumFormats && copied < celt)
cliprdr_format_deep_copy(&rgelt[copied++], &instance->m_pFormatEtc[instance->m_nIndex++]);
if (pceltFetched != 0)
*pceltFetched = copied;
return (copied == celt) ? S_OK : S_FALSE;
}
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC *This, ULONG celt)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
if (instance->m_nIndex + (LONG) celt > instance->m_nNumFormats)
return S_FALSE;
instance->m_nIndex += celt;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Reset(IEnumFORMATETC *This)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
instance->m_nIndex = 0;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Clone(IEnumFORMATETC *This, IEnumFORMATETC **ppEnum)
{
CliprdrEnumFORMATETC *instance = (CliprdrEnumFORMATETC *)This;
if (!ppEnum)
return E_INVALIDARG;
*ppEnum = (IEnumFORMATETC *)CliprdrEnumFORMATETC_New(instance->m_nNumFormats, instance->m_pFormatEtc);
if (!*ppEnum)
return E_OUTOFMEMORY;
((CliprdrEnumFORMATETC *) *ppEnum)->m_nIndex = instance->m_nIndex;
return S_OK;
}
CliprdrEnumFORMATETC *CliprdrEnumFORMATETC_New(int nFormats, FORMATETC *pFormatEtc)
{
CliprdrEnumFORMATETC *instance;
IEnumFORMATETC *iEnumFORMATETC;
int i;
if (!pFormatEtc)
return NULL;
instance = (CliprdrEnumFORMATETC *)calloc(1, sizeof(CliprdrEnumFORMATETC));
if (instance)
{
iEnumFORMATETC = &instance->iEnumFORMATETC;
iEnumFORMATETC->lpVtbl = (IEnumFORMATETCVtbl *)calloc(1, sizeof(IEnumFORMATETCVtbl));
if (iEnumFORMATETC->lpVtbl)
{
iEnumFORMATETC->lpVtbl->QueryInterface = CliprdrEnumFORMATETC_QueryInterface;
iEnumFORMATETC->lpVtbl->AddRef = CliprdrEnumFORMATETC_AddRef;
iEnumFORMATETC->lpVtbl->Release = CliprdrEnumFORMATETC_Release;
iEnumFORMATETC->lpVtbl->Next = CliprdrEnumFORMATETC_Next;
iEnumFORMATETC->lpVtbl->Skip = CliprdrEnumFORMATETC_Skip;
iEnumFORMATETC->lpVtbl->Reset = CliprdrEnumFORMATETC_Reset;
iEnumFORMATETC->lpVtbl->Clone = CliprdrEnumFORMATETC_Clone;
instance->m_lRefCount = 0;
instance->m_nIndex = 0;
instance->m_nNumFormats = nFormats;
instance->m_pFormatEtc = (FORMATETC *)calloc(nFormats, sizeof(FORMATETC));
for (i = 0; i < nFormats; i++)
{
cliprdr_format_deep_copy(&instance->m_pFormatEtc[i], &pFormatEtc[i]);
}
}
else
{
free(instance);
instance = NULL;
}
}
return instance;
}
void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC *instance)
{
int i;
if (instance)
{
if (instance->iEnumFORMATETC.lpVtbl)
free(instance->iEnumFORMATETC.lpVtbl);
if (instance->m_pFormatEtc)
{
for (i = 0; i < instance->m_nNumFormats; i++)
{
if (instance->m_pFormatEtc[i].ptd)
CoTaskMemFree(instance->m_pFormatEtc[i].ptd);
}
free(instance->m_pFormatEtc);
}
free(instance);
}
}

View File

@ -1,50 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Implementation of the IEnumFORMATETC COM interface
*
* Copyright 2014 Zhang Zhaolong <zhangzl2013@126.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __WF_CLIPRDR_ENUMFORMATETC_H__
#define __WF_CLIPRDR_ENUMFORMATETC_H__
#define CINTERFACE
#define COBJMACROS
#include <windows.h>
#include <Ole2.h>
typedef struct _CliprdrEnumFORMATETC {
IEnumFORMATETC iEnumFORMATETC;
// private
LONG m_lRefCount;
LONG m_nIndex;
LONG m_nNumFormats;
FORMATETC *m_pFormatEtc;
} CliprdrEnumFORMATETC;
CliprdrEnumFORMATETC *CliprdrEnumFORMATETC_New(int nFormats, FORMATETC *pFormatEtc);
void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC *This);
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_QueryInterface(IEnumFORMATETC *This, REFIID riid, void **ppvObject);
ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_AddRef(IEnumFORMATETC *This);
ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_Release(IEnumFORMATETC *This);
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Next(IEnumFORMATETC *This, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC *This, ULONG celt);
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Reset(IEnumFORMATETC *This);
HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Clone(IEnumFORMATETC *This, IEnumFORMATETC **ppenum);
#endif // __WF_CLIPRDR_ENUMFORMATETC_H__

View File

@ -1,281 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Implementation of the IStream COM interface
*
* Copyright 2014 Zhang Zhaolong <zhangzl2013@126.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wf_cliprdr.h"
#include "wf_cliprdr_Stream.h"
HRESULT STDMETHODCALLTYPE CliprdrStream_QueryInterface(IStream *This, REFIID riid, void **ppvObject)
{
CliprdrStream *instance = (CliprdrStream *)This;
if (IsEqualIID(riid, &IID_IStream) || IsEqualIID(riid, &IID_IUnknown))
{
IStream_AddRef(This);
*ppvObject = This;
return S_OK;
}
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE CliprdrStream_AddRef(IStream *This)
{
CliprdrStream *instance = (CliprdrStream *)This;
return InterlockedIncrement(&instance->m_lRefCount);
}
ULONG STDMETHODCALLTYPE CliprdrStream_Release(IStream * This)
{
CliprdrStream *instance = (CliprdrStream *)This;
LONG count;
count = InterlockedDecrement(&instance->m_lRefCount);
if(count == 0)
{
CliprdrStream_Delete(instance);
return 0;
}
else
{
return count;
}
}
#define FILECONTENTS_SIZE 0x00000001
#define FILECONTENTS_RANGE 0x00000002
HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream *This, void *pv, ULONG cb, ULONG *pcbRead)
{
CliprdrStream *instance = (CliprdrStream *)This;
cliprdrContext *cliprdr = (cliprdrContext *)instance->m_pData;
int ret;
if (pv == NULL || pcbRead == NULL)
return E_INVALIDARG;
*pcbRead = 0;
if (instance->m_lOffset.QuadPart >= instance->m_lSize.QuadPart)
return S_FALSE;
ret = cliprdr_send_request_filecontents(cliprdr, (void *)This,
instance->m_lIndex, FILECONTENTS_RANGE,
instance->m_lOffset.HighPart, instance->m_lOffset.LowPart,
cb);
if (ret < 0)
return S_FALSE;
if (cliprdr->req_fdata)
{
memcpy(pv, cliprdr->req_fdata, cliprdr->req_fsize);
free(cliprdr->req_fdata);
}
*pcbRead = cliprdr->req_fsize;
instance->m_lOffset.QuadPart += cliprdr->req_fsize;
if (cliprdr->req_fsize < cb)
return S_FALSE;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_Write(IStream *This, const void *pv, ULONG cb, ULONG *pcbWritten)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_ACCESSDENIED;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_Seek(IStream *This, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
CliprdrStream *instance = (CliprdrStream *)This;
ULONGLONG newoffset;
newoffset = instance->m_lOffset.QuadPart;
switch (dwOrigin)
{
case STREAM_SEEK_SET:
newoffset = dlibMove.QuadPart;
break;
case STREAM_SEEK_CUR:
newoffset += dlibMove.QuadPart;
break;
case STREAM_SEEK_END:
newoffset = instance->m_lSize.QuadPart + dlibMove.QuadPart;
break;
default:
return S_FALSE;
}
if (newoffset < 0 || newoffset >= instance->m_lSize.QuadPart)
return FALSE;
instance->m_lOffset.QuadPart = newoffset;
if (plibNewPosition)
plibNewPosition->QuadPart = instance->m_lOffset.QuadPart;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_SetSize(IStream *This, ULARGE_INTEGER libNewSize)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_INSUFFICIENTMEMORY;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_CopyTo(IStream *This, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
CliprdrStream *instance = (CliprdrStream *)This;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_Commit(IStream *This, DWORD grfCommitFlags)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_MEDIUMFULL;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_Revert(IStream *This)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_INSUFFICIENTMEMORY;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_LockRegion(IStream *This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_INSUFFICIENTMEMORY;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_UnlockRegion(IStream *This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_INSUFFICIENTMEMORY;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_Stat(IStream *This, STATSTG *pstatstg, DWORD grfStatFlag)
{
CliprdrStream *instance = (CliprdrStream *)This;
if (pstatstg == NULL)
return STG_E_INVALIDPOINTER;
ZeroMemory(pstatstg, sizeof(STATSTG));
switch (grfStatFlag)
{
case STATFLAG_DEFAULT:
return STG_E_INSUFFICIENTMEMORY;
case STATFLAG_NONAME:
pstatstg->cbSize.QuadPart = instance->m_lSize.QuadPart;
pstatstg->grfLocksSupported = LOCK_EXCLUSIVE;
pstatstg->grfMode = GENERIC_READ;
pstatstg->grfStateBits = 0;
pstatstg->type = STGTY_STREAM;
break;
case STATFLAG_NOOPEN:
return STG_E_INVALIDFLAG;
default:
return STG_E_INVALIDFLAG;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CliprdrStream_Clone(IStream *This, IStream **ppstm)
{
CliprdrStream *instance = (CliprdrStream *)This;
return STG_E_INSUFFICIENTMEMORY;
}
CliprdrStream *CliprdrStream_New(LONG index, void *pData)
{
cliprdrContext *cliprdr = (cliprdrContext *)pData;
CliprdrStream *instance;
IStream *iStream;
instance = (CliprdrStream *)calloc(1, sizeof(CliprdrStream));
if (instance)
{
iStream = &instance->iStream;
iStream->lpVtbl = (IStreamVtbl *)calloc(1, sizeof(IStreamVtbl));
if (iStream->lpVtbl)
{
iStream->lpVtbl->QueryInterface = CliprdrStream_QueryInterface;
iStream->lpVtbl->AddRef = CliprdrStream_AddRef;
iStream->lpVtbl->Release = CliprdrStream_Release;
iStream->lpVtbl->Read = CliprdrStream_Read;
iStream->lpVtbl->Write = CliprdrStream_Write;
iStream->lpVtbl->Seek = CliprdrStream_Seek;
iStream->lpVtbl->SetSize = CliprdrStream_SetSize;
iStream->lpVtbl->CopyTo = CliprdrStream_CopyTo;
iStream->lpVtbl->Commit = CliprdrStream_Commit;
iStream->lpVtbl->Revert = CliprdrStream_Revert;
iStream->lpVtbl->LockRegion = CliprdrStream_LockRegion;
iStream->lpVtbl->UnlockRegion = CliprdrStream_UnlockRegion;
iStream->lpVtbl->Stat = CliprdrStream_Stat;
iStream->lpVtbl->Clone = CliprdrStream_Clone;
instance->m_lRefCount = 1;
instance->m_lIndex = index;
instance->m_pData = pData;
instance->m_lOffset.QuadPart = 0;
/* get content size of this stream */
cliprdr_send_request_filecontents(cliprdr, (void *)instance, instance->m_lIndex, FILECONTENTS_SIZE, 0, 0, 8);
instance->m_lSize.QuadPart = *(LONGLONG *)cliprdr->req_fdata;
free(cliprdr->req_fdata);
}
else
{
free(instance);
instance = NULL;
}
}
return instance;
}
void CliprdrStream_Delete(CliprdrStream *instance)
{
if (instance)
{
if (instance->iStream.lpVtbl)
free(instance->iStream.lpVtbl);
free(instance);
}
}

View File

@ -1,58 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Implementation of the IStream COM interface
*
* Copyright 2014 Zhang Zhaolong <zhangzl2013@126.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __WF_CLIPRDR_STREAM_H__
#define __WF_CLIPRDR_STREAM_H__
#define CINTERFACE
#define COBJMACROS
#include <windows.h>
#include <Ole2.h>
typedef struct _CliprdrStream {
IStream iStream;
// private
LONG m_lRefCount;
LONG m_lIndex;
ULARGE_INTEGER m_lSize;
ULARGE_INTEGER m_lOffset;
void *m_pData;
} CliprdrStream;
CliprdrStream *CliprdrStream_New(LONG index, void *pData);
void CliprdrStream_Delete(CliprdrStream *instance);
HRESULT STDMETHODCALLTYPE CliprdrStream_QueryInterface(IStream *This, REFIID riid, void **ppvObject);
ULONG STDMETHODCALLTYPE CliprdrStream_AddRef(IStream *This);
ULONG STDMETHODCALLTYPE CliprdrStream_Release(IStream * This);
HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream *This, void *pv, ULONG cb, ULONG *pcbRead);
HRESULT STDMETHODCALLTYPE CliprdrStream_Write(IStream *This, const void *pv, ULONG cb, ULONG *pcbWritten);
HRESULT STDMETHODCALLTYPE CliprdrStream_Seek(IStream *This, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);
HRESULT STDMETHODCALLTYPE CliprdrStream_SetSize(IStream *This, ULARGE_INTEGER libNewSize);
HRESULT STDMETHODCALLTYPE CliprdrStream_CopyTo(IStream *This, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
HRESULT STDMETHODCALLTYPE CliprdrStream_Commit(IStream *This, DWORD grfCommitFlags);
HRESULT STDMETHODCALLTYPE CliprdrStream_Revert(IStream *This);
HRESULT STDMETHODCALLTYPE CliprdrStream_LockRegion(IStream *This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
HRESULT STDMETHODCALLTYPE CliprdrStream_UnlockRegion(IStream *This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
HRESULT STDMETHODCALLTYPE CliprdrStream_Stat(IStream *This, STATSTG *pstatstg, DWORD grfStatFlag);
HRESULT STDMETHODCALLTYPE CliprdrStream_Clone(IStream *This, IStream **ppstm);
#endif // __WF_CLIPRDR_STREAM_H__

View File

@ -28,6 +28,8 @@
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_event_focus_in(wfContext* wfc);
#define KBD_TAG CLIENT_TAG("windows")
#ifdef WITH_DEBUG_KBD
#define DEBUG_KBD(fmt, ...) WLog_DBG(KBD_TAG, fmt, ## __VA_ARGS__)

View File

@ -389,7 +389,7 @@ void wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);
if (wfc->bitmap_size < (nWidth * nHeight * 4))
if (wfc->bitmap_size < (UINT32) (nWidth * nHeight * 4))
{
wfc->bitmap_size = nWidth * nHeight * 4;
wfc->bitmap_buffer = (BYTE*) _aligned_realloc(wfc->bitmap_buffer, wfc->bitmap_size, 16);

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,7 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Windows RAIL
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.com>
* Copyright 2013-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,17 +15,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __WF_RAIL_H
#define __WF_RAIL_H
typedef struct wf_rail_window wfRailWindow;
#include "wf_client.h"
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail);
void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command);
void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled);
void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event);
void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window);
void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window);
#include <freerdp/client/rail.h>
struct wf_rail_window
{
wfContext* wfc;
HWND hWnd;
DWORD dwStyle;
DWORD dwExStyle;
int x;
int y;
int width;
int height;
char* title;
};
void wf_rail_init(wfContext* wfc, RailClientContext* rail);
void wf_rail_uninit(wfContext* wfc, RailClientContext* rail);
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion);
#endif

View File

@ -27,6 +27,7 @@
#include "xfreerdp.h"
#include "xf_gfx.h"
#include "xf_cliprdr.h"
void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
{
@ -44,6 +45,10 @@ void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven
else
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
{
xf_cliprdr_init(xfc, (CliprdrClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
xf_encomsp_init(xfc, (EncomspClientContext*) e->pInterface);
@ -66,6 +71,10 @@ void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnect
else
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
{
xf_cliprdr_uninit(xfc, (CliprdrClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
xf_encomsp_uninit(xfc, (EncomspClientContext*) e->pInterface);

View File

@ -23,6 +23,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/client/channels.h>
#include <freerdp/client/rdpei.h>
#include <freerdp/client/cliprdr.h>
#include <freerdp/client/rdpgfx.h>
#include <freerdp/client/encomsp.h>

View File

@ -611,38 +611,48 @@ BOOL xf_get_pixmap_info(xfContext *xfc)
XPixmapFormatValues *pfs;
XWindowAttributes window_attributes;
pfs = XListPixmapFormats(xfc->display, &pf_count);
if(pfs == NULL)
if (pfs == NULL)
{
WLog_ERR(TAG, "XListPixmapFormats failed");
return 1;
}
for(i = 0; i < pf_count; i++)
for (i = 0; i < pf_count; i++)
{
pf = pfs + i;
if(pf->depth == xfc->depth)
if (pf->depth == xfc->depth)
{
xfc->bpp = pf->bits_per_pixel;
xfc->scanline_pad = pf->scanline_pad;
break;
}
}
XFree(pfs);
ZeroMemory(&template, sizeof(template));
template.class = TrueColor;
template.screen = xfc->screen_number;
if(XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), &window_attributes) == 0)
if (XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), &window_attributes) == 0)
{
WLog_ERR(TAG, "XGetWindowAttributes failed");
return FALSE;
}
vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
if(vis == NULL)
if (vis == NULL)
{
WLog_ERR(TAG, "XGetVisualInfo failed");
return FALSE;
}
vi = NULL;
for(i = 0; i < vi_count; i++)
for (i = 0; i < vi_count; i++)
{
vi = vis + i;
if(vi->visual == window_attributes.visual)
@ -651,22 +661,26 @@ BOOL xf_get_pixmap_info(xfContext *xfc)
break;
}
}
if(vi)
if (vi)
{
/*
* Detect if the server visual has an inverted colormap
* (BGR vs RGB, or red being the least significant byte)
*/
if(vi->red_mask & 0xFF)
if (vi->red_mask & 0xFF)
{
xfc->clrconv->invert = TRUE;
xfc->invert = TRUE;
}
}
XFree(vis);
if((xfc->visual == NULL) || (xfc->scanline_pad == 0))
if ((xfc->visual == NULL) || (xfc->scanline_pad == 0))
{
return FALSE;
}
return TRUE;
}
@ -859,7 +873,6 @@ BOOL xf_pre_connect(freerdp* instance)
xf_keyboard_init(xfc);
xfc->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA);
instance->context->cache = cache_new(instance->settings);
xfc->xfds = ConnectionNumber(xfc->display);
@ -899,6 +912,7 @@ BOOL xf_pre_connect(freerdp* instance)
*/
BOOL xf_post_connect(freerdp *instance)
{
UINT32 flags;
XGCValues gcv;
rdpCache* cache;
rdpChannels* channels;
@ -915,16 +929,16 @@ BOOL xf_post_connect(freerdp *instance)
xf_register_graphics(instance->context->graphics);
flags = CLRCONV_ALPHA;
if (xfc->bpp > 16)
flags |= CLRBUF_32BPP;
else
flags |= CLRBUF_16BPP;
if (settings->SoftwareGdi)
{
rdpGdi* gdi;
UINT32 flags;
flags = CLRCONV_ALPHA;
if (xfc->bpp > 16)
flags |= CLRBUF_32BPP;
else
flags |= CLRBUF_16BPP;
gdi_init(instance, flags, NULL);
@ -935,7 +949,7 @@ BOOL xf_post_connect(freerdp *instance)
{
xfc->srcBpp = settings->ColorDepth;
xf_gdi_register_update_callbacks(instance->update);
xfc->hdc = gdi_CreateDC(xfc->clrconv, xfc->bpp);
xfc->hdc = gdi_CreateDC(flags, xfc->bpp);
}
xfc->originalWidth = settings->DesktopWidth;
@ -1003,9 +1017,10 @@ BOOL xf_post_connect(freerdp *instance)
instance->context->rail = rail_new(instance->settings);
rail_register_update_callbacks(instance->context->rail, instance->update);
xf_rail_register_callbacks(xfc, instance->context->rail);
xfc->clipboard = xf_clipboard_new(xfc);
freerdp_channels_post_connect(channels, instance);
xf_tsmf_init(xfc, xv_port);
xf_cliprdr_init(xfc, channels);
EventArgsInit(&e, "xfreerdp");
e.width = settings->DesktopWidth;
@ -1090,31 +1105,30 @@ int xf_logon_error_info(freerdp *instance, UINT32 data, UINT32 type)
return 1;
}
void xf_process_channel_event(rdpChannels *channels, freerdp *instance)
void xf_process_channel_event(rdpChannels* channels, freerdp* instance)
{
xfContext *xfc;
wMessage *event;
xfc = (xfContext *) instance->context;
xfContext* xfc;
wMessage* event;
xfc = (xfContext*) instance->context;
event = freerdp_channels_pop_event(channels);
if(event)
if (event)
{
switch(GetMessageClass(event->id))
{
case RailChannel_Class:
xf_process_rail_event(xfc, channels, event);
break;
case TsmfChannel_Class:
xf_process_tsmf_event(xfc, event);
break;
case CliprdrChannel_Class:
xf_process_cliprdr_event(xfc, event);
break;
case RdpeiChannel_Class:
xf_process_rdpei_event(xfc, event);
break;
default:
break;
}
freerdp_event_free(event);
}
}
@ -1174,12 +1188,6 @@ void xf_window_free(xfContext *xfc)
context->rail = NULL;
}
if (xfc->clrconv)
{
freerdp_clrconv_free(xfc->clrconv);
xfc->clrconv = NULL;
}
if (xfc->hdc)
{
gdi_DeleteDC(xfc->hdc);
@ -1191,14 +1199,14 @@ void xf_window_free(xfContext *xfc)
xfc->xv_context = NULL;
}
if (xfc->clipboard_context)
if (xfc->clipboard)
{
xf_cliprdr_uninit(xfc);
xfc->clipboard_context = NULL;
xf_clipboard_free(xfc->clipboard);
xfc->clipboard = NULL;
}
}
void *xf_input_thread(void *arg)
void* xf_input_thread(void *arg)
{
xfContext *xfc;
HANDLE event;
@ -1212,34 +1220,39 @@ void *xf_input_thread(void *arg)
assert(NULL != xfc);
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds);
while(WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
do
{
xf_lock_x11(xfc, FALSE);
pending_status = XPending(xfc->display);
xf_unlock_x11(xfc, FALSE);
if(pending_status)
if (pending_status)
{
xf_lock_x11(xfc, FALSE);
ZeroMemory(&xevent, sizeof(xevent));
XNextEvent(xfc->display, &xevent);
process_status = xf_event_process(instance, &xevent);
xf_unlock_x11(xfc, FALSE);
if(!process_status)
break;
}
}
while(pending_status);
if(!process_status)
while (pending_status);
if (!process_status)
break;
}
MessageQueue_PostQuit(queue, 0);
ExitThread(0);
return NULL;
}
void *xf_channels_thread(void *arg)
void* xf_channels_thread(void *arg)
{
int status;
xfContext *xfc;
@ -1251,13 +1264,17 @@ void *xf_channels_thread(void *arg)
assert(NULL != xfc);
channels = instance->context->channels;
event = freerdp_channels_get_event_handle(instance);
while(WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
status = freerdp_channels_process_pending_messages(instance);
if(!status)
if (!status)
break;
xf_process_channel_event(channels, instance);
}
ExitThread(0);
return NULL;
}
@ -1305,7 +1322,7 @@ BOOL xf_auto_reconnect(freerdp *instance)
* @param instance - pointer to the rdp_freerdp structure that contains the session's settings
* @return A code from the enum XF_EXIT_CODE (0 if successful)
*/
void *xf_thread(void *param)
void* xf_thread(void *param)
{
int i;
int fds;

File diff suppressed because it is too large Load Diff

View File

@ -23,8 +23,14 @@
#include "xf_client.h"
#include "xfreerdp.h"
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels);
void xf_cliprdr_uninit(xfContext* xfc);
void xf_process_cliprdr_event(xfContext* xfc, wMessage* event);
#include <freerdp/client/cliprdr.h>
xfClipboard* xf_clipboard_new(xfContext* xfc);
void xf_clipboard_free(xfClipboard* clipboard);
void xf_cliprdr_init(xfContext* xfc, CliprdrClientContext* cliprdr);
void xf_cliprdr_uninit(xfContext* xfc, CliprdrClientContext* cliprdr);
void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event);
#endif /* __XF_CLIPRDR_H */

View File

@ -241,20 +241,25 @@ unsigned long xf_gdi_get_color(xfContext* xfc, GDI_COLOR color)
Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data)
{
GC gc;
Pixmap bitmap;
BYTE* cdata;
XImage* image;
UINT32 brushFormat;
bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, xfc->depth);
if (data)
{
GC gc;
brushFormat = gdi_get_pixel_format(bpp, FALSE);
cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfc->bpp, xfc->clrconv);
cdata = (BYTE*) _aligned_malloc(width * height * 4, 16);
freerdp_image_copy(cdata, xfc->format, -1, 0, 0,
width, height, data, brushFormat, -1, 0, 0, xfc->palette);
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0);
ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0);
gc = XCreateGC(xfc->display, xfc->drawable, 0, NULL);
XPutImage(xfc->display, bitmap, gc, image, 0, 0, 0, 0, width, height);
@ -408,8 +413,6 @@ void xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
xf_lock_x11(xfc, FALSE);
CopyMemory(xfc->clrconv->palette, palette, sizeof(rdpPalette));
palette32 = (UINT32*) xfc->palette;
for (index = 0; index < palette->number; index++)

View File

@ -227,8 +227,9 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0))
{
freerdp_alpha_cursor_convert((BYTE*) (ci.pixels), pointer->xorMaskData, pointer->andMaskData,
pointer->width, pointer->height, pointer->xorBpp, xfc->clrconv);
freerdp_image_copy_from_pointer_data((BYTE*) ci.pixels, PIXEL_FORMAT_ARGB32,
pointer->width * 4, 0, 0, pointer->width, pointer->height,
pointer->xorMaskData, pointer->andMaskData, pointer->xorBpp, xfc->palette);
}
((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfc->display, &ci);

View File

@ -709,21 +709,6 @@ int xf_input_init(xfContext* xfc, Window window)
#endif
void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
{
switch (GetMessageType(event->id))
{
case RdpeiChannel_ServerReady:
break;
case RdpeiChannel_SuspendTouch:
break;
case RdpeiChannel_ResumeTouch:
break;
}
}
int xf_input_handle_event(xfContext* xfc, XEvent* event)
{
#ifdef WITH_XI

View File

@ -28,8 +28,6 @@
#endif
int xf_input_init(xfContext* xfc, Window window);
int xf_input_handle_event(xfContext* xfc, XEvent* event);
void xf_process_rdpei_event(xfContext* xfc, wMessage* event);
#endif

View File

@ -186,7 +186,7 @@ static void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* ico
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
icon->extra = freerdp_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask,
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
xf_SetWindowIcon(xfc, xfw, icon);
}

View File

@ -68,6 +68,8 @@ struct xf_glyph
};
typedef struct xf_glyph xfGlyph;
typedef struct xf_clipboard xfClipboard;
struct xf_context
{
rdpContext context;
@ -109,7 +111,6 @@ struct xf_context
int current_desktop;
BOOL remote_app;
BOOL disconnect;
HCLRCONV clrconv;
HANDLE mutex;
BOOL UseXThreads;
BOOL cursorHidden;
@ -157,7 +158,8 @@ struct xf_context
BOOL complex_regions;
VIRTUAL_SCREEN vscreen;
void* xv_context;
void* clipboard_context;
xfClipboard* clipboard;
CliprdrClientContext* cliprdr;
Atom _NET_WM_ICON;
Atom _MOTIF_WM_HINTS;

View File

@ -29,30 +29,6 @@
* Clipboard Formats
*/
#define CLIPRDR_FORMAT_RAW 0
#define CLIPRDR_FORMAT_TEXT 1 /* "Plain Text" */
#define CLIPRDR_FORMAT_BITMAP 2 /* "Bitmap" */
#define CLIPRDR_FORMAT_METAFILEPICT 3 /* "Windows Metafile" */
#define CLIPRDR_FORMAT_SYLK 4
#define CLIPRDR_FORMAT_DIF 5
#define CLIPRDR_FORMAT_TIFF 6
#define CLIPRDR_FORMAT_OEMTEXT 7 /* "OEM Text" */
#define CLIPRDR_FORMAT_DIB 8 /* "Device Independent Bitmap (DIB)" */
#define CLIPRDR_FORMAT_PALETTE 9
#define CLIPRDR_FORMAT_PENDATA 10
#define CLIPRDR_FORMAT_RIFF 11
#define CLIPRDR_FORMAT_WAVE 12
#define CLIPRDR_FORMAT_UNICODETEXT 13 /* "Unicode Text" */
#define CLIPRDR_FORMAT_ENHMETAFILE 14 /* "Enhanced Metafile" */
#define CLIPRDR_FORMAT_HDROP 15 /* "File List" */
#define CLIPRDR_FORMAT_LOCALE 16 /* "Locale Identifier" */
#define CLIPRDR_FORMAT_DIBV5 17
#define CLIPRDR_FORMAT_MAX 18
#define CB_FORMAT_RAW 0x0000
#define CB_FORMAT_TEXT 0x0001
#define CB_FORMAT_DIB 0x0008
#define CB_FORMAT_UNICODETEXT 0x000D
#define CB_FORMAT_HTML 0xD010
#define CB_FORMAT_PNG 0xD011
#define CB_FORMAT_JPEG 0xD012
@ -92,8 +68,43 @@
#define CB_FILECLIP_NO_FILE_PATHS 0x00000008
#define CB_CAN_LOCK_CLIPDATA 0x00000010
#define FORMAT_ID_PALETTE 9
#define FORMAT_ID_METAFILE 3
/* File Contents Request Flags */
#define FILECONTENTS_SIZE 0x00000001
#define FILECONTENTS_RANGE 0x00000002
/* Special Clipboard Response Formats */
struct _CLIPRDR_MFPICT
{
UINT32 mappingMode;
UINT32 xExt;
UINT32 yExt;
UINT32 metaFileSize;
BYTE* metaFileData;
};
typedef struct _CLIPRDR_MFPICT CLIPRDR_MFPICT;
struct _CLIPRDR_FILEDESCRIPTOR
{
UINT32 flags;
BYTE reserved1[32];
UINT32 fileAttributes;
BYTE reserved2[16];
UINT64 lastWriteTime;
UINT32 fileSizeHigh;
UINT32 fileSizeLow;
char fileName[520];
};
typedef struct _CLIPRDR_FILEDESCRIPTOR CLIPRDR_FILEDESCRIPTOR;
struct _CLIPRDR_FILELIST
{
UINT32 cItems;
CLIPRDR_FILEDESCRIPTOR* fileDescriptorArray;
};
typedef struct _CLIPRDR_FILELIST CLIPRDR_FILELIST;
/* Clipboard Messages */
#define DEFINE_CLIPRDR_HEADER_COMMON() \
UINT16 msgType; \
@ -138,6 +149,14 @@ struct _CLIPRDR_MONITOR_READY
};
typedef struct _CLIPRDR_MONITOR_READY CLIPRDR_MONITOR_READY;
struct _CLIPRDR_TEMP_DIRECTORY
{
DEFINE_CLIPRDR_HEADER_COMMON();
char szTempDir[520];
};
typedef struct _CLIPRDR_TEMP_DIRECTORY CLIPRDR_TEMP_DIRECTORY;
struct _CLIPRDR_FORMAT
{
UINT32 formatId;
@ -149,7 +168,7 @@ struct _CLIPRDR_FORMAT_LIST
{
DEFINE_CLIPRDR_HEADER_COMMON();
UINT32 cFormats;
UINT32 numFormats;
CLIPRDR_FORMAT* formats;
};
typedef struct _CLIPRDR_FORMAT_LIST CLIPRDR_FORMAT_LIST;
@ -160,6 +179,22 @@ struct _CLIPRDR_FORMAT_LIST_RESPONSE
};
typedef struct _CLIPRDR_FORMAT_LIST_RESPONSE CLIPRDR_FORMAT_LIST_RESPONSE;
struct _CLIPRDR_LOCK_CLIPBOARD_DATA
{
DEFINE_CLIPRDR_HEADER_COMMON();
UINT32 clipDataId;
};
typedef struct _CLIPRDR_LOCK_CLIPBOARD_DATA CLIPRDR_LOCK_CLIPBOARD_DATA;
struct _CLIPRDR_UNLOCK_CLIPBOARD_DATA
{
DEFINE_CLIPRDR_HEADER_COMMON();
UINT32 clipDataId;
};
typedef struct _CLIPRDR_UNLOCK_CLIPBOARD_DATA CLIPRDR_UNLOCK_CLIPBOARD_DATA;
struct _CLIPRDR_FORMAT_DATA_REQUEST
{
DEFINE_CLIPRDR_HEADER_COMMON();
@ -176,5 +211,30 @@ struct _CLIPRDR_FORMAT_DATA_RESPONSE
};
typedef struct _CLIPRDR_FORMAT_DATA_RESPONSE CLIPRDR_FORMAT_DATA_RESPONSE;
struct _CLIPRDR_FILE_CONTENTS_REQUEST
{
DEFINE_CLIPRDR_HEADER_COMMON();
UINT32 streamId;
UINT32 listIndex;
UINT32 dwFlags;
UINT32 nPositionLow;
UINT32 nPositionHigh;
UINT32 cbRequested;
UINT32 clipDataId;
};
typedef struct _CLIPRDR_FILE_CONTENTS_REQUEST CLIPRDR_FILE_CONTENTS_REQUEST;
struct _CLIPRDR_FILE_CONTENTS_RESPONSE
{
DEFINE_CLIPRDR_HEADER_COMMON();
UINT32 streamId;
UINT32 dwFlags;
UINT32 cbRequested;
BYTE* requestedData;
};
typedef struct _CLIPRDR_FILE_CONTENTS_RESPONSE CLIPRDR_FILE_CONTENTS_RESPONSE;
#endif /* FREERDP_CHANNEL_CLIPRDR_H */

View File

@ -34,14 +34,23 @@ typedef struct _cliprdr_client_context CliprdrClientContext;
typedef int (*pcCliprdrServerCapabilities)(CliprdrClientContext* context, CLIPRDR_CAPABILITIES* capabilities);
typedef int (*pcCliprdrClientCapabilities)(CliprdrClientContext* context, CLIPRDR_CAPABILITIES* capabilities);
typedef int (*pcCliprdrMonitorReady)(CliprdrClientContext* context, CLIPRDR_MONITOR_READY* monitorReady);
typedef int (*pcCliprdrTempDirectory)(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTORY* tempDirectory);
typedef int (*pcCliprdrClientFormatList)(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList);
typedef int (*pcCliprdrServerFormatList)(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList);
typedef int (*pcCliprdrClientFormatListResponse)(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse);
typedef int (*pcCliprdrServerFormatListResponse)(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse);
typedef int (*pcCliprdrClientLockClipboardData)(CliprdrClientContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
typedef int (*pcCliprdrServerLockClipboardData)(CliprdrClientContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
typedef int (*pcCliprdrClientUnlockClipboardData)(CliprdrClientContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);
typedef int (*pcCliprdrServerUnlockClipboardData)(CliprdrClientContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);
typedef int (*pcCliprdrClientFormatDataRequest)(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest);
typedef int (*pcCliprdrServerFormatDataRequest)(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest);
typedef int (*pcCliprdrClientFormatDataResponse)(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse);
typedef int (*pcCliprdrServerFormatDataResponse)(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse);
typedef int (*pcCliprdrClientFileContentsRequest)(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest);
typedef int (*pcCliprdrServerFileContentsRequest)(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest);
typedef int (*pcCliprdrClientFileContentsResponse)(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse);
typedef int (*pcCliprdrServerFileContentsResponse)(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse);
struct _cliprdr_client_context
{
@ -51,14 +60,23 @@ struct _cliprdr_client_context
pcCliprdrServerCapabilities ServerCapabilities;
pcCliprdrClientCapabilities ClientCapabilities;
pcCliprdrMonitorReady MonitorReady;
pcCliprdrTempDirectory TempDirectory;
pcCliprdrClientFormatList ClientFormatList;
pcCliprdrServerFormatList ServerFormatList;
pcCliprdrClientFormatListResponse ClientFormatListResponse;
pcCliprdrServerFormatListResponse ServerFormatListResponse;
pcCliprdrClientLockClipboardData ClientLockClipboardData;
pcCliprdrServerLockClipboardData ServerLockClipboardData;
pcCliprdrClientUnlockClipboardData ClientUnlockClipboardData;
pcCliprdrServerUnlockClipboardData ServerUnlockClipboardData;
pcCliprdrClientFormatDataRequest ClientFormatDataRequest;
pcCliprdrServerFormatDataRequest ServerFormatDataRequest;
pcCliprdrClientFormatDataResponse ClientFormatDataResponse;
pcCliprdrServerFormatDataResponse ServerFormatDataResponse;
pcCliprdrClientFileContentsRequest ClientFileContentsRequest;
pcCliprdrServerFileContentsRequest ServerFileContentsRequest;
pcCliprdrClientFileContentsResponse ClientFileContentsResponse;
pcCliprdrServerFileContentsResponse ServerFileContentsResponse;
};
struct _CLIPRDR_FORMAT_NAME

View File

@ -449,6 +449,12 @@ FREERDP_API UINT32 freerdp_convert_gdi_order_color(UINT32 color, int bpp, UINT32
FREERDP_API HCLRCONV freerdp_clrconv_new(UINT32 flags);
FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv);
FREERDP_API int freerdp_image_copy_from_monochrome(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst,
int nWidth, int nHeight, BYTE* pSrcData, UINT32 backColor, UINT32 foreColor, BYTE* palette);
FREERDP_API int freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst,
int nWidth, int nHeight, BYTE* xorMask, BYTE* andMask, UINT32 xorBpp, BYTE* palette);
FREERDP_API int freerdp_image8_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst,
int nWidth, int nHeight, BYTE* pSrcData, DWORD SrcFormat, int nSrcStep, int nXSrc, int nYSrc, BYTE* palette);
FREERDP_API int freerdp_image15_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst,

View File

@ -25,7 +25,7 @@
#include <freerdp/codec/mppc.h>
#pragma pack(push,1)
#pragma pack(push, 1)
struct _XCRUSH_MATCH_INFO
{

View File

@ -24,7 +24,7 @@
#include <freerdp/gdi/gdi.h>
FREERDP_API HGDI_DC gdi_GetDC(void);
FREERDP_API HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp);
FREERDP_API HGDI_DC gdi_CreateDC(UINT32 flags, int bpp);
FREERDP_API HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc);
FREERDP_API HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject);
FREERDP_API int gdi_DeleteObject(HGDIOBJECT hgdiobject);

View File

@ -287,7 +287,6 @@ struct rdp_gdi
BOOL invert;
HGDI_DC hdc;
UINT32 format;
HCLRCONV clrconv;
gdiBitmap* primary;
gdiBitmap* drawing;
UINT32 bitmap_size;

View File

@ -1131,7 +1131,7 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp
int bitIndex;
BYTE redBg, greenBg, blueBg;
BYTE redFg, greenFg, blueFg;
GetRGB32(redBg, greenBg, blueBg, bgcolor);
GetRGB32(redFg, greenFg, blueFg, fgcolor);
@ -1223,41 +1223,349 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp
return srcData;
}
int freerdp_image_copy_from_monochrome(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst,
int nWidth, int nHeight, BYTE* pSrcData, UINT32 backColor, UINT32 foreColor, BYTE* palette)
{
int x, y;
BOOL vFlip;
BOOL invert;
int srcFlip;
int dstFlip;
int nDstPad;
int monoStep;
UINT32 monoBit;
BYTE* monoBits;
UINT32 monoPixel;
BYTE a, r, g, b;
int dstBitsPerPixel;
int dstBytesPerPixel;
dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(DstFormat);
dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(DstFormat) / 8);
dstFlip = FREERDP_PIXEL_FORMAT_FLIP(DstFormat);
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
nDstPad = (nDstStep - (nWidth * dstBytesPerPixel));
srcFlip = FREERDP_PIXEL_FLIP_NONE;
vFlip = (srcFlip != dstFlip) ? TRUE : FALSE;
invert = (FREERDP_PIXEL_FORMAT_IS_ABGR(DstFormat)) ? TRUE : FALSE;
backColor |= 0xFF000000;
foreColor |= 0xFF000000;
monoStep = (nWidth + 7) / 8;
if (dstBytesPerPixel == 4)
{
UINT32* pDstPixel;
if (invert)
{
GetARGB32(a, r, g, b, backColor);
backColor = ABGR32(a, r, g, b);
GetARGB32(a, r, g, b, foreColor);
foreColor = ABGR32(a, r, g, b);
}
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
monoBit = 0x80;
if (!vFlip)
monoBits = &pSrcData[monoStep * y];
else
monoBits = &pSrcData[monoStep * (nHeight - y - 1)];
for (x = 0; x < nWidth; x++)
{
monoPixel = (*monoBits & monoBit) ? 1 : 0;
if (!(monoBit >>= 1)) { monoBits++; monoBit = 0x80; }
if (monoPixel)
*pDstPixel++ = backColor;
else
*pDstPixel++ = foreColor;
}
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
else if (dstBytesPerPixel == 2)
{
UINT16* pDstPixel;
UINT16 backColor16;
UINT16 foreColor16;
if (!invert)
{
if (dstBitsPerPixel == 15)
{
GetRGB32(r, g, b, backColor);
backColor16 = RGB15(r, g, b);
GetRGB32(r, g, b, foreColor);
foreColor16 = RGB15(r, g, b);
}
else
{
GetRGB32(r, g, b, backColor);
backColor16 = RGB16(r, g, b);
GetRGB32(r, g, b, foreColor);
foreColor16 = RGB16(r, g, b);
}
}
else
{
if (dstBitsPerPixel == 15)
{
GetRGB32(r, g, b, backColor);
backColor16 = BGR15(r, g, b);
GetRGB32(r, g, b, foreColor);
foreColor16 = BGR15(r, g, b);
}
else
{
GetRGB32(r, g, b, backColor);
backColor16 = BGR16(r, g, b);
GetRGB32(r, g, b, foreColor);
foreColor16 = BGR16(r, g, b);
}
}
pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * 2)];
for (y = 0; y < nHeight; y++)
{
monoBit = 0x80;
if (!vFlip)
monoBits = &pSrcData[monoStep * y];
else
monoBits = &pSrcData[monoStep * (nHeight - y - 1)];
for (x = 0; x < nWidth; x++)
{
monoPixel = (*monoBits & monoBit) ? 1 : 0;
if (!(monoBit >>= 1)) { monoBits++; monoBit = 0x80; }
if (monoPixel)
*pDstPixel++ = backColor16;
else
*pDstPixel++ = foreColor16;
}
pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
fprintf(stderr, "freerdp_image_copy_from_monochrome failure: dstBytesPerPixel: %d dstBitsPerPixel: %d\n",
dstBytesPerPixel, dstBitsPerPixel);
return -1;
}
void freerdp_alpha_cursor_convert(BYTE* alphaData, BYTE* xorMask, BYTE* andMask, int width, int height, int bpp, HCLRCONV clrconv)
{
int xpixel;
int apixel;
int i, j, jj;
UINT32 xorPixel;
UINT32 andPixel;
UINT32 x, y, jj;
for (j = 0; j < height; j++)
for (y = 0; y < height; y++)
{
jj = (bpp == 1) ? j : (height - 1) - j;
for (i = 0; i < width; i++)
{
xpixel = freerdp_get_pixel(xorMask, i, jj, width, height, bpp);
xpixel = freerdp_color_convert_rgb(xpixel, bpp, 32, clrconv);
apixel = freerdp_get_pixel(andMask, i, jj, width, height, 1);
jj = (bpp == 1) ? y : (height - 1) - y;
if (apixel != 0)
for (x = 0; x < width; x++)
{
xorPixel = freerdp_get_pixel(xorMask, x, jj, width, height, bpp);
xorPixel = freerdp_color_convert_rgb(xorPixel, bpp, 32, clrconv);
andPixel = freerdp_get_pixel(andMask, x, jj, width, height, 1);
if (andPixel)
{
if ((xpixel & 0xffffff) == 0xffffff)
if ((xorPixel & 0xFFFFFF) == 0xFFFFFF)
{
/* use pattern (not solid black) for xor area */
xpixel = (i & 1) == (j & 1);
xpixel = xpixel ? 0xFFFFFF : 0;
xpixel |= 0xFF000000;
xorPixel = (x & 1) == (y & 1);
xorPixel = xorPixel ? 0xFFFFFF : 0;
xorPixel |= 0xFF000000;
}
else if (xpixel == 0xFF000000)
else if (xorPixel == 0xFF000000)
{
xpixel = 0;
xorPixel = 0;
}
}
freerdp_set_pixel(alphaData, i, j, width, height, 32, xpixel);
freerdp_set_pixel(alphaData, x, y, width, height, 32, xorPixel);
}
}
}
/**
* Drawing Monochrome Pointers:
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff556143/
*
* Drawing Color Pointers:
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff556138/
*/
int freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst,
int nWidth, int nHeight, BYTE* xorMask, BYTE* andMask, UINT32 xorBpp, BYTE* palette)
{
int x, y;
BOOL vFlip;
BOOL invert;
int srcFlip;
int dstFlip;
int nDstPad;
int xorStep;
int andStep;
UINT32 xorBit;
UINT32 andBit;
BYTE* xorBits;
BYTE* andBits;
UINT32 xorPixel;
UINT32 andPixel;
int dstBitsPerPixel;
int dstBytesPerPixel;
dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(DstFormat);
dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(DstFormat) / 8);
dstFlip = FREERDP_PIXEL_FORMAT_FLIP(DstFormat);
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
nDstPad = (nDstStep - (nWidth * dstBytesPerPixel));
srcFlip = (xorBpp == 1) ? FREERDP_PIXEL_FLIP_NONE : FREERDP_PIXEL_FLIP_VERTICAL;
vFlip = (srcFlip != dstFlip) ? TRUE : FALSE;
invert = (FREERDP_PIXEL_FORMAT_IS_ABGR(DstFormat)) ? TRUE : FALSE;
andStep = (nWidth + 7) / 8;
andStep += (andStep % 2);
if (dstBytesPerPixel == 4)
{
UINT32* pDstPixel;
if (xorBpp == 1)
{
xorStep = (nWidth + 7) / 8;
xorStep += (xorStep % 2);
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
xorBit = andBit = 0x80;
if (!vFlip)
{
xorBits = &xorMask[xorStep * y];
andBits = &andMask[andStep * y];
}
else
{
xorBits = &xorMask[xorStep * (nHeight - y - 1)];
andBits = &andMask[andStep * (nHeight - y - 1)];
}
for (x = 0; x < nWidth; x++)
{
xorPixel = (*xorBits & xorBit) ? 1 : 0;
if (!(xorBit >>= 1)) { xorBits++; xorBit = 0x80; }
andPixel = (*andBits & andBit) ? 1 : 0;
if (!(andBit >>= 1)) { andBits++; andBit = 0x80; }
if (!andPixel && !xorPixel)
*pDstPixel++ = 0xFF000000; /* black */
else if (!andPixel && xorPixel)
*pDstPixel++ = 0xFFFFFFFF; /* white */
else if (andPixel && !xorPixel)
*pDstPixel++ = 0x00000000; /* transparent */
else if (andPixel && xorPixel)
*pDstPixel++ = 0xFF000000; /* inverted (set as black) */
}
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
else if (xorBpp == 32)
{
xorStep = nWidth * 4;
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
andBit = 0x80;
if (!vFlip)
{
andBits = &andMask[andStep * y];
xorBits = &xorMask[xorStep * y];
}
else
{
andBits = &andMask[andStep * (nHeight - y - 1)];
xorBits = &xorMask[xorStep * (nHeight - y - 1)];
}
for (x = 0; x < nWidth; x++)
{
xorPixel = *((UINT32*) xorBits);
xorBits += 4;
andPixel = (*andBits & andBit) ? 1 : 0;
if (!(andBit >>= 1)) { andBits++; andBit = 0x80; }
xorPixel |= 0xFF000000;
if (andPixel)
{
if ((~xorPixel) & 0xFFFFFF) /* black */
*pDstPixel++ = 0x00000000; /* transparent */
else if (xorPixel & 0xFFFFFF) /* white */
*pDstPixel++ = 0xFF000000; /* inverted (set as black) */
else
*pDstPixel++ = xorPixel;
}
else
{
*pDstPixel++ = xorPixel;
}
}
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
}
fprintf(stderr, "freerdp_image_copy_from_pointer_data: failed to convert from %d bpp to %d bpp\n",
xorBpp, dstBitsPerPixel);
return -1;
}
void freerdp_image_swap_color_order(BYTE* data, int width, int height)
{
int x, y;
@ -2411,7 +2719,7 @@ int freerdp_image24_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs
pDstPixel[2] = pSrcPixel[0];
pDstPixel[3] = 0xFF;
pSrcPixel += 4;
pSrcPixel += 3;
pDstPixel += 4;
}
@ -2433,7 +2741,7 @@ int freerdp_image24_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs
pDstPixel[2] = pSrcPixel[0];
pDstPixel[3] = 0xFF;
pSrcPixel += 4;
pSrcPixel += 3;
pDstPixel += 4;
}

View File

@ -3295,6 +3295,8 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa
UINT16 length;
BYTE *bm, *em;
BOOL foundMultifragmentUpdate = FALSE;
Stream_GetPointer(s, mark);
count = numberCapabilities;
@ -3441,6 +3443,7 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa
case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
if (!rdp_read_multifragment_update_capability_set(s, length, settings))
return FALSE;
foundMultifragmentUpdate = TRUE;
break;
case CAPSET_TYPE_LARGE_POINTER:
@ -3489,6 +3492,15 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa
count-numberCapabilities, count);
}
/**
* If we never received a multifragment update capability set,
* then the peer doesn't support fragmentation.
*/
if (!foundMultifragmentUpdate)
{
settings->MultifragMaxRequestSize = 0;
}
#ifdef WITH_DEBUG_CAPABILITIES
Stream_GetPointer(s, em);
Stream_SetPointer(s, mark);

View File

@ -893,6 +893,34 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
maxLength -= 20;
}
totalLength = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
/**
* TEMPORARY FIX
*
* FreeRDP always sends updates using fast-path without regard to the client settings
* for 1) FASTPATH_OUTPUT_SUPPORTED in the extraFlags field of the general capability
* set or 2) the MaxRequestSize field in the Multifragment Update capability set.
*
* As a temporary workaround to clients that do not support fragmentation, this code
* determines if fragmentation is needed and/or exceeds the size advertised maximum
* request size from the client. In this case, slow-path is utilized.
*
*/
if ((totalLength > maxLength) && (totalLength > settings->MultifragMaxRequestSize))
{
wStream* sps;
/* Use slow-path to send the PDU */
sps = transport_send_stream_init(rdp->transport, totalLength + 50);
rdp_init_stream_data_pdu(rdp, sps);
Stream_Copy(sps, s, totalLength);
return rdp_send_data_pdu(rdp, sps, DATA_PDU_TYPE_UPDATE, MCS_GLOBAL_CHANNEL_ID);
}
if (rdp->do_crypt)
{
rdp->sec_flags |= SEC_ENCRYPT;
@ -901,9 +929,6 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
}
totalLength = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
for (fragment = 0; (totalLength > 0) || (fragment == 0); fragment++)
{
BYTE* pSrcData;

View File

@ -291,9 +291,9 @@ void gcc_write_conference_create_response(wStream* s, wStream* userData)
per_write_choice(s, 0);
per_write_object_identifier(s, t124_02_98_oid);
/* ConnectPDULength */
/* ConnectData::connectPDU (OCTET_STRING) */
/* This length MUST be ignored by the client according to [MS-RDPBCGR] */
per_write_length(s, 0);
per_write_length(s, 0x2A);
/* ConnectGCCPDU */
per_write_choice(s, 0x14);

View File

@ -192,6 +192,7 @@ int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s);
BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id);
wStream* rdp_data_pdu_init(rdpRdp* rdp);
int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s);
BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id);
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s);

View File

@ -11,6 +11,8 @@ create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
include_directories(${OPENSSL_INCLUDE_DIR})
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
target_link_libraries(${MODULE_NAME} freerdp)

View File

@ -59,7 +59,7 @@ HGDI_DC gdi_GetDC()
* @return new device context
*/
HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp)
HGDI_DC gdi_CreateDC(UINT32 flags, int bpp)
{
HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC));
@ -71,9 +71,9 @@ HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp)
hDC->bitsPerPixel = bpp;
hDC->bytesPerPixel = bpp / 8;
hDC->alpha = clrconv->alpha;
hDC->invert = clrconv->invert;
hDC->rgb555 = clrconv->rgb555;
hDC->alpha = (flags & CLRCONV_ALPHA) ? TRUE : FALSE;
hDC->invert = (flags & CLRCONV_INVERT) ? TRUE : FALSE;
hDC->rgb555 = (flags & CLRCONV_RGB555) ? TRUE : FALSE;
hDC->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND));
hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0);

View File

@ -550,8 +550,6 @@ static void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
UINT32* palette32;
rdpGdi* gdi = context->gdi;
CopyMemory(gdi->clrconv->palette, palette, sizeof(rdpPalette));
palette32 = (UINT32*) gdi->palette;
for (index = 0; index < palette->number; index++)
@ -615,10 +613,15 @@ static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
}
else if (brush->style == GDI_BS_HATCHED)
{
BYTE* hatched;
HGDI_BITMAP hBmp;
data = freerdp_mono_image_convert(GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch, 8, 8, 1,
gdi->dstBpp, backColor, foreColor, gdi->clrconv);
data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch);
freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8,
hatched, backColor, foreColor, gdi->palette);
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
@ -634,15 +637,23 @@ static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
else if (brush->style == GDI_BS_PATTERN)
{
HGDI_BITMAP hBmp;
UINT32 brushFormat;
if (brush->bpp > 1)
{
data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv);
brushFormat = gdi_get_pixel_format(brush->bpp, FALSE);
data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
freerdp_image_copy(data, gdi->format, -1, 0, 0,
8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette);
}
else
{
data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp,
backColor, foreColor, gdi->clrconv);
data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8,
brush->data, backColor, foreColor, gdi->palette);
}
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
@ -810,15 +821,23 @@ static void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
else if (brush->style == GDI_BS_PATTERN)
{
HGDI_BITMAP hBmp;
UINT32 brushFormat;
if (brush->bpp > 1)
{
data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv);
brushFormat = gdi_get_pixel_format(brush->bpp, FALSE);
data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
freerdp_image_copy(data, gdi->format, -1, 0, 0,
8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette);
}
else
{
data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp,
backColor, foreColor, gdi->clrconv);
data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8,
brush->data, backColor, foreColor, gdi->palette);
}
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
@ -1180,22 +1199,9 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer)
gdi->hdc->bitsPerPixel = gdi->dstBpp;
gdi->hdc->bytesPerPixel = gdi->bytesPerPixel;
gdi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV));
if (!gdi->clrconv)
return -1;
gdi->clrconv->alpha = (flags & CLRCONV_ALPHA) ? TRUE : FALSE;
gdi->clrconv->invert = (flags & CLRCONV_INVERT) ? TRUE : FALSE;
gdi->clrconv->rgb555 = (flags & CLRCONV_RGB555) ? TRUE : FALSE;
gdi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette));
if (!gdi->clrconv->palette)
return -1;
gdi->hdc->alpha = gdi->clrconv->alpha;
gdi->hdc->invert = gdi->clrconv->invert;
gdi->hdc->rgb555 = gdi->clrconv->rgb555;
gdi->hdc->alpha = (flags & CLRCONV_ALPHA) ? TRUE : FALSE;
gdi->hdc->invert = (flags & CLRCONV_INVERT) ? TRUE : FALSE;
gdi->hdc->rgb555 = (flags & CLRCONV_RGB555) ? TRUE : FALSE;
gdi_init_primary(gdi);
@ -1234,8 +1240,6 @@ void gdi_free(freerdp* instance)
gdi_bitmap_free_ex(gdi->image);
gdi_DeleteDC(gdi->hdc);
_aligned_free(gdi->bitmap_buffer);
free(gdi->clrconv->palette);
free(gdi->clrconv);
free(gdi);
}

View File

@ -66,6 +66,10 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
add_subdirectory(include)
add_subdirectory(librdtk)
if(WITH_X11)
add_subdirectory(sample)
endif()
# Exporting
if(${CMAKE_VERSION} VERSION_GREATER "2.8.10")

2
rdtk/sample/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
rdtk-sample

View File

@ -0,0 +1,35 @@
# RdTk: Remote Desktop Toolkit
# rdtk cmake build script
#
# Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MODULE_NAME "rdtk-sample")
set(MODULE_PREFIX "RDTK_SAMPLE")
include_directories(${X11_INCLUDE_DIRS})
set(${MODULE_PREFIX}_SRCS
rdtk_x11.c)
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
set(${MODULE_PREFIX}_LIBS rdtk)
list(APPEND ${MODULE_PREFIX}_LIBS ${X11_LIBRARIES})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "RdTk")

147
rdtk/sample/rdtk_x11.c Normal file
View File

@ -0,0 +1,147 @@
/**
* RdTk: Remote Desktop Toolkit
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rdtk/rdtk.h>
#include <X11/Xlib.h>
int main(int argc, char** argv)
{
GC gc;
int index;
int depth;
int x, y;
int width;
int height;
BYTE* buffer;
int scanline;
int pf_count;
XEvent event;
XImage* image;
Pixmap pixmap;
Screen* screen;
Visual* visual;
int scanline_pad;
int screen_number;
Display* display;
Window window;
Window root_window;
rdtkEngine* engine;
rdtkSurface* surface;
unsigned long border;
unsigned long background;
XPixmapFormatValues* pf;
XPixmapFormatValues* pfs;
display = XOpenDisplay(NULL);
if (!display)
{
fprintf(stderr, "Cannot open display\n");
exit(1);
}
x = 10;
y = 10;
width = 640;
height = 480;
screen_number = DefaultScreen(display);
screen = ScreenOfDisplay(display, screen_number);
visual = DefaultVisual(display, screen_number);
gc = DefaultGC(display, screen_number);
depth = DefaultDepthOfScreen(screen);
root_window = RootWindow(display, screen_number);
border = BlackPixel(display, screen_number);
background = WhitePixel(display, screen_number);
scanline_pad = 0;
pfs = XListPixmapFormats(display, &pf_count);
for (index = 0; index < pf_count; index++)
{
pf = &pfs[index];
if (pf->depth == depth)
{
scanline_pad = pf->scanline_pad;
break;
}
}
XFree(pfs);
engine = rdtk_engine_new();
scanline = width * 4;
buffer = (BYTE*) malloc(scanline * height);
surface = rdtk_surface_new(engine, buffer, width, height, scanline);
rdtk_surface_fill(surface, 0, 0, width, height, 0x3BB9FF);
rdtk_label_draw(surface, 16, 16, 128, 32, NULL, "label", 0, 0);
rdtk_button_draw(surface, 16, 64, 128, 32, NULL, "button");
rdtk_text_field_draw(surface, 16, 128, 128, 32, NULL, "text field");
window = XCreateSimpleWindow(display, root_window,
x, y, width, height, 1, border, background);
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
XSetFunction(display, gc, GXcopy);
XSetFillStyle(display, gc, FillSolid);
pixmap = XCreatePixmap(display, window, width, height, depth);
image = XCreateImage(display, visual, depth, ZPixmap, 0,
(char*) buffer, width, height, scanline_pad, 0);
while (1)
{
XNextEvent(display, &event);
if (event.type == Expose)
{
XPutImage(display, pixmap, gc, image, 0, 0, 0, 0, width, height);
XCopyArea(display, pixmap, window, gc, 0, 0, width, height, 0, 0);
}
if (event.type == KeyPress)
break;
if (event.type == ClientMessage)
break;
}
XFlush(display);
XCloseDisplay(display);
rdtk_surface_free(surface);
free(buffer);
rdtk_engine_free(engine);
return 0;
}

View File

@ -0,0 +1,64 @@
/**
* WinPR: Windows Portable Runtime
* Clipboard Functions
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_CLIPBOARD_H
#define WINPR_CLIPBOARD_H
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
typedef struct _wClipboard wClipboard;
typedef void* (*CLIPBOARD_SYNTHESIZE_FN)(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize);
#ifdef __cplusplus
extern "C" {
#endif
WINPR_API void ClipboardLock(wClipboard* clipboard);
WINPR_API void ClipboardUnlock(wClipboard* clipboard);
WINPR_API BOOL ClipboardEmpty(wClipboard* clipboard);
WINPR_API UINT32 ClipboardCountFormats(wClipboard* clipboard);
WINPR_API UINT32 ClipboardGetFormatIds(wClipboard* clipboard, UINT32** ppFormatIds);
WINPR_API UINT32 ClipboardCountRegisteredFormats(wClipboard* clipboard);
WINPR_API UINT32 ClipboardGetRegisteredFormatIds(wClipboard* clipboard, UINT32** ppFormatIds);
WINPR_API UINT32 ClipboardRegisterFormat(wClipboard* clipboard, const char* name);
WINPR_API BOOL ClipboardRegisterSynthesizer(wClipboard* clipboard, UINT32 formatId,
UINT32 syntheticId, CLIPBOARD_SYNTHESIZE_FN pfnSynthesize);
WINPR_API UINT32 ClipboardGetFormatId(wClipboard* clipboard, const char* name);
WINPR_API const char* ClipboardGetFormatName(wClipboard* clipboard, UINT32 formatId);
WINPR_API void* ClipboardGetData(wClipboard* clipboard, UINT32 formatId, UINT32* pSize);
WINPR_API BOOL ClipboardSetData(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32 size);
WINPR_API UINT64 ClipboardGetOwner(wClipboard* clipboard);
WINPR_API void ClipboardSetOwner(wClipboard* clipboard, UINT64 ownerId);
WINPR_API wClipboard* ClipboardCreate();
WINPR_API void ClipboardDestroy(wClipboard* clipboard);
#ifdef __cplusplus
}
#endif
#endif /* WINPR_CLIPBOARD_H */

View File

@ -58,14 +58,11 @@ static INLINE UINT64 _rotr64(UINT64 value, int shift) {
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
#define _byteswap_ushort(_val) __builtin_bswap16(_val)
#define _byteswap_ulong(_val) __builtin_bswap32(_val)
#define _byteswap_uint64(_val) __builtin_bswap64(_val)
#else
#define _byteswap_ushort(_val) (((_val) >> 8) | ((_val) << 8))
#define _byteswap_ulong(_val) (((_val) >> 24) | \
(((_val) & 0x00FF0000) >> 8) | \
(((_val) & 0x0000FF00) << 8) | \
@ -82,6 +79,16 @@ static INLINE UINT64 _rotr64(UINT64 value, int shift) {
#endif
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))
#define _byteswap_ushort(_val) __builtin_bswap16(_val)
#else
#define _byteswap_ushort(_val) (((_val) >> 8) | ((_val) << 8))
#endif
/**
* __lzcnt16, __lzcnt, __lzcnt64:
* http://msdn.microsoft.com/en-us/library/bb384809/

View File

@ -23,6 +23,46 @@
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#pragma pack(push, 1)
struct _WINPR_BITMAP_FILE_HEADER
{
BYTE bfType[2];
UINT32 bfSize;
UINT16 bfReserved1;
UINT16 bfReserved2;
UINT32 bfOffBits;
};
typedef struct _WINPR_BITMAP_FILE_HEADER WINPR_BITMAP_FILE_HEADER;
struct _WINPR_BITMAP_INFO_HEADER
{
UINT32 biSize;
INT32 biWidth;
INT32 biHeight;
UINT16 biPlanes;
UINT16 biBitCount;
UINT32 biCompression;
UINT32 biSizeImage;
INT32 biXPelsPerMeter;
INT32 biYPelsPerMeter;
UINT32 biClrUsed;
UINT32 biClrImportant;
};
typedef struct _WINPR_BITMAP_INFO_HEADER WINPR_BITMAP_INFO_HEADER;
struct _WINPR_BITMAP_CORE_HEADER
{
UINT32 bcSize;
UINT16 bcWidth;
UINT16 bcHeight;
UINT16 bcPlanes;
UINT16 bcBitCount;
};
typedef struct _WINPR_BITMAP_CORE_HEADER WINPR_BITMAP_CORE_HEADER;
#pragma pack(pop)
#define WINPR_IMAGE_BITMAP 0
#define WINPR_IMAGE_PNG 1

101
winpr/include/winpr/pack.h Normal file
View File

@ -0,0 +1,101 @@
/**
* WinPR: Windows Portable Runtime
* Pragma Pack
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This header is meant to be repeatedly included
* after defining the operation to be done:
*
* #define WINPR_PACK_PUSH
* #include <winpr/pack.h> // enables packing
*
* #define WINPR_PACK_POP
* #include <winpr/pack.h> // disables packing
*
* On each include, WINPR_PACK_* macros are undefined.
*/
#if !defined(__APPLE__)
#ifndef WINPR_PRAGMA_PACK_EXT
#define WINPR_PRAGMA_PACK_EXT
#endif
#endif
#ifdef PRAGMA_PACK_PUSH
#ifndef PRAGMA_PACK_PUSH1
#define PRAGMA_PACK_PUSH1
#endif
#undef PRAGMA_PACK_PUSH
#endif
#ifdef PRAGMA_PACK_PUSH1
#ifdef WINPR_PRAGMA_PACK_EXT
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif
#undef PRAGMA_PACK_PUSH1
#endif
#ifdef PRAGMA_PACK_PUSH2
#ifdef WINPR_PRAGMA_PACK_EXT
#pragma pack(push, 2)
#else
#pragma pack(2)
#endif
#undef PRAGMA_PACK_PUSH2
#endif
#ifdef PRAGMA_PACK_PUSH4
#ifdef WINPR_PRAGMA_PACK_EXT
#pragma pack(push, 4)
#else
#pragma pack(4)
#endif
#undef PRAGMA_PACK_PUSH4
#endif
#ifdef PRAGMA_PACK_PUSH8
#ifdef WINPR_PRAGMA_PACK_EXT
#pragma pack(push, 8)
#else
#pragma pack(8)
#endif
#undef PRAGMA_PACK_PUSH8
#endif
#ifdef PRAGMA_PACK_PUSH16
#ifdef WINPR_PRAGMA_PACK_EXT
#pragma pack(push, 16)
#else
#pragma pack(16)
#endif
#undef PRAGMA_PACK_PUSH16
#endif
#ifdef PRAGMA_PACK_POP
#ifdef WINPR_PRAGMA_PACK_EXT
#pragma pack(pop)
#else
#pragma pack()
#endif
#undef PRAGMA_PACK_POP
#endif
#undef WINPR_PRAGMA_PACK_EXT

View File

@ -227,11 +227,7 @@
#define SCARD_NEGOTIABLE 5
#define SCARD_SPECIFIC 6
#if defined(__APPLE__) | defined(sun)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
typedef struct _SCARD_IO_REQUEST
{
@ -557,11 +553,7 @@ typedef struct
SCARDHANDLE hCardHandle;
} OPENCARDNAMEW, *POPENCARDNAMEW, *LPOPENCARDNAMEW;
#if defined(__APPLE__) | defined(sun)
#pragma pack()
#else
#pragma pack(pop)
#endif
#ifdef UNICODE
#define LPOCNCONNPROC LPOCNCONNPROCW

View File

@ -181,6 +181,11 @@ WINPR_API int ConvertToUnicode(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteS
WINPR_API int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
LPSTR* lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
WINPR_API void ByteSwapUnicode(WCHAR* wstr, int length);
WINPR_API int ConvertLineEndingToLF(char* str, int size);
WINPR_API char* ConvertLineEndingToCRLF(const char* str, int* size);
#ifdef __cplusplus
}
#endif

259
winpr/include/winpr/user.h Normal file
View File

@ -0,0 +1,259 @@
/**
* WinPR: Windows Portable Runtime
* User Environment
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_USER_H
#define WINPR_USER_H
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
/**
* Standard Clipboard Formats
*/
#ifndef _WIN32
#define CF_TEXT 1
#define CF_BITMAP 2
#define CF_METAFILEPICT 3
#define CF_SYLK 4
#define CF_DIF 5
#define CF_TIFF 6
#define CF_OEMTEXT 7
#define CF_DIB 8
#define CF_PALETTE 9
#define CF_PENDATA 10
#define CF_RIFF 11
#define CF_WAVE 12
#define CF_UNICODETEXT 13
#define CF_ENHMETAFILE 14
#define CF_HDROP 15
#define CF_LOCALE 16
#define CF_DIBV5 17
#define CF_MAX 18
#define CF_OWNERDISPLAY 0x0080
#define CF_DSPTEXT 0x0081
#define CF_DSPBITMAP 0x0082
#define CF_DSPMETAFILEPICT 0x0083
#define CF_DSPENHMETAFILE 0x008E
#define CF_PRIVATEFIRST 0x0200
#define CF_PRIVATELAST 0x02FF
#define CF_GDIOBJFIRST 0x0300
#define CF_GDIOBJLAST 0x03FF
/* Windows Metafile Picture Format */
#define MM_TEXT 1
#define MM_LOMETRIC 2
#define MM_HIMETRIC 3
#define MM_LOENGLISH 4
#define MM_HIENGLISH 5
#define MM_TWIPS 6
#define MM_ISOTROPIC 7
#define MM_ANISOTROPIC 8
#define MM_MIN MM_TEXT
#define MM_MAX MM_ANISOTROPIC
#define MM_MAX_FIXEDSCALE MM_TWIPS
#endif
/**
* Bitmap Definitions
*/
#ifndef _WIN32
#pragma pack(push, 1)
typedef LONG FXPT16DOT16, FAR *LPFXPT16DOT16;
typedef LONG FXPT2DOT30, FAR *LPFXPT2DOT30;
typedef struct tagCIEXYZ
{
FXPT2DOT30 ciexyzX;
FXPT2DOT30 ciexyzY;
FXPT2DOT30 ciexyzZ;
} CIEXYZ;
typedef CIEXYZ FAR *LPCIEXYZ;
typedef struct tagICEXYZTRIPLE
{
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
} CIEXYZTRIPLE;
typedef CIEXYZTRIPLE FAR *LPCIEXYZTRIPLE;
typedef struct tagBITMAP
{
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP;
typedef struct tagRGBTRIPLE
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} RGBTRIPLE, *PRGBTRIPLE, NEAR *NPRGBTRIPLE, FAR *LPRGBTRIPLE;
typedef struct tagRGBQUAD
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
typedef RGBQUAD FAR* LPRGBQUAD;
#define BI_RGB 0
#define BI_RLE8 1
#define BI_RLE4 2
#define BI_BITFIELDS 3
#define BI_JPEG 4
#define BI_PNG 5
#define PROFILE_LINKED 'LINK'
#define PROFILE_EMBEDDED 'MBED'
typedef struct tagBITMAPCOREHEADER
{
DWORD bcSize;
WORD bcWidth;
WORD bcHeight;
WORD bcPlanes;
WORD bcBitCount;
} BITMAPCOREHEADER, FAR *LPBITMAPCOREHEADER, *PBITMAPCOREHEADER;
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct
{
DWORD bV4Size;
LONG bV4Width;
LONG bV4Height;
WORD bV4Planes;
WORD bV4BitCount;
DWORD bV4V4Compression;
DWORD bV4SizeImage;
LONG bV4XPelsPerMeter;
LONG bV4YPelsPerMeter;
DWORD bV4ClrUsed;
DWORD bV4ClrImportant;
DWORD bV4RedMask;
DWORD bV4GreenMask;
DWORD bV4BlueMask;
DWORD bV4AlphaMask;
DWORD bV4CSType;
CIEXYZTRIPLE bV4Endpoints;
DWORD bV4GammaRed;
DWORD bV4GammaGreen;
DWORD bV4GammaBlue;
} BITMAPV4HEADER, FAR *LPBITMAPV4HEADER, *PBITMAPV4HEADER;
typedef struct
{
DWORD bV5Size;
LONG bV5Width;
LONG bV5Height;
WORD bV5Planes;
WORD bV5BitCount;
DWORD bV5Compression;
DWORD bV5SizeImage;
LONG bV5XPelsPerMeter;
LONG bV5YPelsPerMeter;
DWORD bV5ClrUsed;
DWORD bV5ClrImportant;
DWORD bV5RedMask;
DWORD bV5GreenMask;
DWORD bV5BlueMask;
DWORD bV5AlphaMask;
DWORD bV5CSType;
CIEXYZTRIPLE bV5Endpoints;
DWORD bV5GammaRed;
DWORD bV5GammaGreen;
DWORD bV5GammaBlue;
DWORD bV5Intent;
DWORD bV5ProfileData;
DWORD bV5ProfileSize;
DWORD bV5Reserved;
} BITMAPV5HEADER, FAR *LPBITMAPV5HEADER, *PBITMAPV5HEADER;
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;
typedef struct tagBITMAPCOREINFO
{
BITMAPCOREHEADER bmciHeader;
RGBTRIPLE bmciColors[1];
} BITMAPCOREINFO, FAR *LPBITMAPCOREINFO, *PBITMAPCOREINFO;
typedef struct tagBITMAPFILEHEADER
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
#pragma pack(pop)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* WINPR_USER_H */

View File

@ -379,4 +379,6 @@ typedef WORD LANGID;
#endif
#include <winpr/user.h>
#endif /* WINPR_WTYPES_H */

View File

@ -83,7 +83,7 @@ foreach(DIR ${WINPR_CORE})
endforeach()
set(WINPR_LEVEL2 winsock sspi winhttp asn1 sspicli crt bcrypt rpc credui
wtsapi dsparse wnd smartcard nt)
wtsapi dsparse wnd smartcard nt clipboard)
foreach(DIR ${WINPR_LEVEL2})
add_subdirectory(${DIR})

View File

@ -0,0 +1,25 @@
# WinPR: Windows Portable Runtime
# libwinpr-clipboard cmake build script
#
# Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
winpr_module_add(
synthetic.c
clipboard.c
clipboard.h)
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@ -0,0 +1,9 @@
set(MINWIN_LAYER "0")
set(MINWIN_GROUP "none")
set(MINWIN_MAJOR_VERSION "0")
set(MINWIN_MINOR_VERSION "0")
set(MINWIN_SHORT_NAME "clipboard")
set(MINWIN_LONG_NAME "Clipboard Functions")
set(MODULE_LIBRARY_NAME "clipboard")

View File

@ -0,0 +1,498 @@
/**
* WinPR: Windows Portable Runtime
* Clipboard Functions
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/collections.h>
#include <winpr/clipboard.h>
#include "clipboard.h"
/**
* Clipboard (Windows):
* msdn.microsoft.com/en-us/library/windows/desktop/ms648709/
*
* W3C Clipboard API and events:
* http://www.w3.org/TR/clipboard-apis/
*/
const char* CF_STANDARD_STRINGS[CF_MAX] =
{
"CF_RAW", /* 0 */
"CF_TEXT", /* 1 */
"CF_BITMAP", /* 2 */
"CF_METAFILEPICT", /* 3 */
"CF_SYLK", /* 4 */
"CF_DIF", /* 5 */
"CF_TIFF", /* 6 */
"CF_OEMTEXT", /* 7 */
"CF_DIB", /* 8 */
"CF_PALETTE", /* 9 */
"CF_PENDATA", /* 10 */
"CF_RIFF", /* 11 */
"CF_WAVE", /* 12 */
"CF_UNICODETEXT", /* 13 */
"CF_ENHMETAFILE", /* 14 */
"CF_HDROP", /* 15 */
"CF_LOCALE", /* 16 */
"CF_DIBV5" /* 17 */
};
wClipboardFormat* ClipboardFindFormat(wClipboard* clipboard, UINT32 formatId, const char* name)
{
UINT32 index;
wClipboardFormat* format = NULL;
if (formatId)
{
for (index = 0; index < clipboard->numFormats; index++)
{
if (formatId == clipboard->formats[index].formatId)
{
format = &clipboard->formats[index];
break;
}
}
}
else if (name)
{
for (index = 0; index < clipboard->numFormats; index++)
{
if (strcmp(name, clipboard->formats[index].formatName) == 0)
{
format = &clipboard->formats[index];
break;
}
}
}
else
{
/* special "CF_RAW" case */
if (clipboard->numFormats > 0)
{
format = &clipboard->formats[0];
if (format->formatId)
return NULL;
if (!format->formatName || (strcmp(format->formatName, CF_STANDARD_STRINGS[0]) == 0))
return format;
}
}
return format;
}
wClipboardSynthesizer* ClipboardFindSynthesizer(wClipboardFormat* format, UINT32 formatId)
{
UINT32 index;
wClipboardSynthesizer* synthesizer;
if (!format)
return NULL;
if (format->numSynthesizers < 1)
return NULL;
for (index = 0; index < format->numSynthesizers; index++)
{
synthesizer = &(format->synthesizers[index]);
if (formatId == synthesizer->syntheticId)
return synthesizer;
}
return NULL;
}
void ClipboardLock(wClipboard* clipboard)
{
EnterCriticalSection(&(clipboard->lock));
}
void ClipboardUnlock(wClipboard* clipboard)
{
LeaveCriticalSection(&(clipboard->lock));
}
BOOL ClipboardEmpty(wClipboard* clipboard)
{
if (clipboard->data)
{
free((void*) clipboard->data);
clipboard->data = NULL;
}
clipboard->size = 0;
clipboard->sequenceNumber++;
return TRUE;
}
UINT32 ClipboardCountRegisteredFormats(wClipboard* clipboard)
{
return clipboard->numFormats;
}
UINT32 ClipboardGetRegisteredFormatIds(wClipboard* clipboard, UINT32** ppFormatIds)
{
UINT32 index;
UINT32* pFormatIds;
wClipboardFormat* format;
if (!ppFormatIds)
return 0;
pFormatIds = *ppFormatIds;
if (!pFormatIds)
{
pFormatIds = malloc(clipboard->numFormats * sizeof(UINT32));
if (!pFormatIds)
return 0;
*ppFormatIds = pFormatIds;
}
for (index = 0; index < clipboard->numFormats; index++)
{
format = &(clipboard->formats[index]);
pFormatIds[index] = format->formatId;
}
return clipboard->numFormats;
}
UINT32 ClipboardRegisterFormat(wClipboard* clipboard, const char* name)
{
wClipboardFormat* format;
format = ClipboardFindFormat(clipboard, 0, name);
if (format)
return format->formatId;
if ((clipboard->numFormats + 1) >= clipboard->maxFormats)
{
clipboard->maxFormats *= 2;
clipboard->formats = (wClipboardFormat*) realloc(clipboard->formats,
clipboard->maxFormats * sizeof(wClipboardFormat));
if (!clipboard->formats)
return 0;
}
format = &(clipboard->formats[clipboard->numFormats]);
ZeroMemory(format, sizeof(wClipboardFormat));
if (name)
{
format->formatName = _strdup(name);
if (!format->formatName)
return 0;
}
format->formatId = clipboard->nextFormatId++;
clipboard->numFormats++;
return format->formatId;
}
BOOL ClipboardRegisterSynthesizer(wClipboard* clipboard, UINT32 formatId,
UINT32 syntheticId, CLIPBOARD_SYNTHESIZE_FN pfnSynthesize)
{
UINT32 index;
wClipboardFormat* format;
wClipboardSynthesizer* synthesizer;
format = ClipboardFindFormat(clipboard, formatId, NULL);
if (!format)
return FALSE;
if (format->formatId == syntheticId)
return FALSE;
synthesizer = ClipboardFindSynthesizer(format, formatId);
if (!synthesizer)
{
index = format->numSynthesizers++;
format->synthesizers = (wClipboardSynthesizer*) realloc(format->synthesizers,
format->numSynthesizers * sizeof(wClipboardSynthesizer));
if (!format->synthesizers)
return FALSE;
synthesizer = &(format->synthesizers[index]);
}
ZeroMemory(synthesizer, sizeof(wClipboardSynthesizer));
synthesizer->syntheticId = syntheticId;
synthesizer->pfnSynthesize = pfnSynthesize;
return TRUE;
}
UINT32 ClipboardCountFormats(wClipboard* clipboard)
{
UINT32 count;
wClipboardFormat* format;
format = ClipboardFindFormat(clipboard, clipboard->formatId, NULL);
if (!format)
return 0;
count = 1 + format->numSynthesizers;
return count;
}
UINT32 ClipboardGetFormatIds(wClipboard* clipboard, UINT32** ppFormatIds)
{
UINT32 index;
UINT32 count;
UINT32* pFormatIds;
wClipboardFormat* format;
wClipboardSynthesizer* synthesizer;
format = ClipboardFindFormat(clipboard, clipboard->formatId, NULL);
if (!format)
return 0;
count = 1 + format->numSynthesizers;
if (!ppFormatIds)
return 0;
pFormatIds = *ppFormatIds;
if (!pFormatIds)
{
pFormatIds = malloc(count * sizeof(UINT32));
if (!pFormatIds)
return 0;
*ppFormatIds = pFormatIds;
}
pFormatIds[0] = format->formatId;
for (index = 1; index < count; index++)
{
synthesizer = &(format->synthesizers[index - 1]);
pFormatIds[index] = synthesizer->syntheticId;
}
return count;
}
BOOL ClipboardInitFormats(wClipboard* clipboard)
{
UINT32 formatId = 0;
wClipboardFormat* format;
for (formatId = 0; formatId < CF_MAX; formatId++)
{
format = &(clipboard->formats[clipboard->numFormats++]);
ZeroMemory(format, sizeof(wClipboardFormat));
format->formatId = formatId;
format->formatName = _strdup(CF_STANDARD_STRINGS[formatId]);
if (!format->formatName)
return FALSE;
}
ClipboardInitSynthesizers(clipboard);
return TRUE;
}
UINT32 ClipboardGetFormatId(wClipboard* clipboard, const char* name)
{
wClipboardFormat* format;
format = ClipboardFindFormat(clipboard, 0, name);
if (!format)
return 0;
return format->formatId;
}
const char* ClipboardGetFormatName(wClipboard* clipboard, UINT32 formatId)
{
wClipboardFormat* format;
format = ClipboardFindFormat(clipboard, formatId, NULL);
if (!format)
return NULL;
return format->formatName;
}
void* ClipboardGetData(wClipboard* clipboard, UINT32 formatId, UINT32* pSize)
{
UINT32 SrcSize = 0;
UINT32 DstSize = 0;
void* pSrcData = NULL;
void* pDstData = NULL;
wClipboardFormat* format;
wClipboardSynthesizer* synthesizer;
if (!pSize)
return NULL;
format = ClipboardFindFormat(clipboard, clipboard->formatId, NULL);
if (!format)
return NULL;
SrcSize = clipboard->size;
pSrcData = (void*) clipboard->data;
if (formatId == format->formatId)
{
DstSize = SrcSize;
pDstData = malloc(DstSize);
if (!pDstData)
return NULL;
CopyMemory(pDstData, pSrcData, SrcSize);
*pSize = DstSize;
}
else
{
synthesizer = ClipboardFindSynthesizer(format, formatId);
if (!synthesizer || !synthesizer->pfnSynthesize)
return NULL;
DstSize = SrcSize;
pDstData = synthesizer->pfnSynthesize(clipboard, format->formatId, pSrcData, &DstSize);
*pSize = DstSize;
}
return pDstData;
}
BOOL ClipboardSetData(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32 size)
{
wClipboardFormat* format;
format = ClipboardFindFormat(clipboard, formatId, NULL);
if (!format)
return FALSE;
free((void*) clipboard->data);
clipboard->data = data;
clipboard->size = size;
clipboard->formatId = formatId;
clipboard->sequenceNumber++;
return TRUE;
}
UINT64 ClipboardGetOwner(wClipboard* clipboard)
{
return clipboard->ownerId;
}
void ClipboardSetOwner(wClipboard* clipboard, UINT64 ownerId)
{
clipboard->ownerId = ownerId;
}
wClipboard* ClipboardCreate()
{
wClipboard* clipboard;
clipboard = (wClipboard*) calloc(1, sizeof(wClipboard));
if (clipboard)
{
clipboard->nextFormatId = 0xC000;
clipboard->sequenceNumber = 0;
InitializeCriticalSectionAndSpinCount(&(clipboard->lock), 4000);
clipboard->numFormats = 0;
clipboard->maxFormats = 64;
clipboard->formats = (wClipboardFormat*) malloc(clipboard->maxFormats * sizeof(wClipboardFormat));
if (!clipboard->formats)
{
free(clipboard);
return NULL;
}
ClipboardInitFormats(clipboard);
}
return clipboard;
}
void ClipboardDestroy(wClipboard* clipboard)
{
UINT32 index;
wClipboardFormat* format;
if (!clipboard)
return;
for (index = 0; index < clipboard->numFormats; index++)
{
format = &(clipboard->formats[index]);
free((void*) format->formatName);
if (format->synthesizers)
{
free(format->synthesizers);
format->synthesizers = NULL;
format->numSynthesizers = 0;
}
}
clipboard->numFormats = 0;
free(clipboard->formats);
DeleteCriticalSection(&(clipboard->lock));
free(clipboard);
}

View File

@ -0,0 +1,68 @@
/**
* WinPR: Windows Portable Runtime
* Clipboard Functions
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_CLIPBOARD_PRIVATE_H
#define WINPR_CLIPBOARD_PRIVATE_H
#include <winpr/clipboard.h>
#include <winpr/collections.h>
typedef struct _wClipboardFormat wClipboardFormat;
typedef struct _wClipboardSynthesizer wClipboardSynthesizer;
struct _wClipboardFormat
{
UINT32 formatId;
const char* formatName;
UINT32 numSynthesizers;
wClipboardSynthesizer* synthesizers;
};
struct _wClipboardSynthesizer
{
UINT32 syntheticId;
CLIPBOARD_SYNTHESIZE_FN pfnSynthesize;
};
struct _wClipboard
{
UINT64 ownerId;
/* clipboard formats */
UINT32 numFormats;
UINT32 maxFormats;
UINT32 nextFormatId;
wClipboardFormat* formats;
/* clipboard data */
UINT32 size;
const void* data;
UINT32 formatId;
UINT32 sequenceNumber;
CRITICAL_SECTION lock;
};
BOOL ClipboardInitSynthesizers(wClipboard* clipboard);
#endif /* WINPR_CLIPBOARD_PRIVATE_H */

View File

@ -0,0 +1,672 @@
/**
* WinPR: Windows Portable Runtime
* Clipboard Functions
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include "clipboard.h"
/**
* Standard Clipboard Formats:
* http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168/
*/
/**
* "CF_TEXT":
*
* Null-terminated ANSI text with CR/LF line endings.
*/
static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
int size;
char* pDstData = NULL;
if (formatId == CF_UNICODETEXT)
{
char* str = NULL;
size = (int) *pSize;
size = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data,
size / 2, (CHAR**) &str, 0, NULL, NULL);
if (!str)
return NULL;
pDstData = ConvertLineEndingToCRLF((const char*) str, &size);
free(str);
*pSize = size;
return pDstData;
}
else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
(formatId == ClipboardGetFormatId(clipboard, "UTF8_STRING")) ||
(formatId == ClipboardGetFormatId(clipboard, "text/plain")) ||
(formatId == ClipboardGetFormatId(clipboard, "TEXT")) ||
(formatId == ClipboardGetFormatId(clipboard, "STRING")))
{
size = (int) *pSize;
pDstData = ConvertLineEndingToCRLF((const char*) data, &size);
if (!pDstData)
return NULL;
*pSize = size;
return pDstData;
}
return NULL;
}
/**
* "CF_OEMTEXT":
*
* Null-terminated OEM text with CR/LF line endings.
*/
static void* clipboard_synthesize_cf_oemtext(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
return clipboard_synthesize_cf_text(clipboard, formatId, data, pSize);
}
/**
* "CF_LOCALE":
*
* System locale identifier associated with CF_TEXT
*/
static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
UINT32* pDstData = NULL;
pDstData = (UINT32*) malloc(sizeof(UINT32));
*pDstData = 0x0409; /* English - United States */
return (void*) pDstData;
}
/**
* "CF_UNICODETEXT":
*
* Null-terminated UTF-16 text with CR/LF line endings.
*/
static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
int size;
int status;
char* crlfStr = NULL;
WCHAR* pDstData = NULL;
if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
(formatId == ClipboardGetFormatId(clipboard, "UTF8_STRING")) ||
(formatId == ClipboardGetFormatId(clipboard, "text/plain")) ||
(formatId == ClipboardGetFormatId(clipboard, "TEXT")) ||
(formatId == ClipboardGetFormatId(clipboard, "STRING")))
{
size = (int) *pSize;
crlfStr = ConvertLineEndingToCRLF((char*) data, &size);
if (!crlfStr)
return NULL;
status = ConvertToUnicode(CP_UTF8, 0, crlfStr, size, &pDstData, 0);
free(crlfStr);
if (status <= 0)
return NULL;
*pSize = ((status + 1) * 2);
}
return (void*) pDstData;
}
/**
* "UTF8_STRING":
*
* Null-terminated UTF-8 string with LF line endings.
*/
static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
int size;
char* pDstData = NULL;
if (formatId == CF_UNICODETEXT)
{
size = (int) *pSize;
size = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data,
size / 2, (CHAR**) &pDstData, 0, NULL, NULL);
if (!pDstData)
return NULL;
size = ConvertLineEndingToLF(pDstData, size);
*pSize = size;
return pDstData;
}
else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
(formatId == ClipboardGetFormatId(clipboard, "text/plain")) ||
(formatId == ClipboardGetFormatId(clipboard, "TEXT")) ||
(formatId == ClipboardGetFormatId(clipboard, "STRING")))
{
size = (int) *pSize;
pDstData = (char*) malloc(size);
if (!pDstData)
return NULL;
CopyMemory(pDstData, data, size);
size = ConvertLineEndingToLF((char*) pDstData, size);
*pSize = size;
return pDstData;
}
return NULL;
}
/**
* "CF_DIB":
*
* BITMAPINFO structure followed by the bitmap bits.
*/
static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
UINT32 SrcSize;
UINT32 DstSize;
BYTE* pDstData;
SrcSize = *pSize;
if (formatId == CF_DIBV5)
{
}
else if (formatId == ClipboardGetFormatId(clipboard, "image/bmp"))
{
BITMAPFILEHEADER* pFileHeader;
if (SrcSize < (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)))
return NULL;
pFileHeader = (BITMAPFILEHEADER*) data;
if (pFileHeader->bfType != 0x4D42)
return NULL;
DstSize = SrcSize - sizeof(BITMAPFILEHEADER);
pDstData = (BYTE*) malloc(DstSize);
if (!pDstData)
return NULL;
data = (void*) &((BYTE*) data)[sizeof(BITMAPFILEHEADER)];
CopyMemory(pDstData, data, DstSize);
*pSize = DstSize;
return pDstData;
}
return NULL;
}
/**
* "CF_DIBV5":
*
* BITMAPV5HEADER structure followed by the bitmap color space information and the bitmap bits.
*/
static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
if (formatId == CF_DIB)
{
}
else if (formatId == ClipboardGetFormatId(clipboard, "image/bmp"))
{
}
return NULL;
}
/**
* "image/bmp":
*
* Bitmap file format.
*/
static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
UINT32 SrcSize;
UINT32 DstSize;
BYTE* pDstData;
SrcSize = *pSize;
if (formatId == CF_DIB)
{
BYTE* pDst;
BITMAPINFOHEADER* pInfoHeader;
BITMAPFILEHEADER* pFileHeader;
if (SrcSize < sizeof(BITMAPINFOHEADER))
return NULL;
pInfoHeader = (BITMAPINFOHEADER*) data;
if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32))
return NULL;
DstSize = sizeof(BITMAPFILEHEADER) + SrcSize;
pDstData = (BYTE*) malloc(DstSize);
if (!pDstData)
return NULL;
pFileHeader = (BITMAPFILEHEADER*) pDstData;
pFileHeader->bfType = 0x4D42;
pFileHeader->bfSize = DstSize;
pFileHeader->bfReserved1 = 0;
pFileHeader->bfReserved2 = 0;
pFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pDst = &pDstData[sizeof(BITMAPFILEHEADER)];
CopyMemory(pDst, data, SrcSize);
*pSize = DstSize;
return pDstData;
}
else if (formatId == CF_DIBV5)
{
}
return NULL;
}
/**
* "HTML Format":
*
* HTML clipboard format: msdn.microsoft.com/en-us/library/windows/desktop/ms649015/
*/
static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
char* pSrcData = NULL;
char* pDstData = NULL;
int SrcSize = (int) *pSize;
if (formatId == ClipboardGetFormatId(clipboard, "text/html"))
{
char* body;
BYTE bom[2];
char num[11];
WCHAR* wstr;
if (SrcSize > 2)
{
CopyMemory(bom, data, 2);
if ((bom[0] == 0xFE) && (bom[1] == 0xFF))
{
ByteSwapUnicode((WCHAR*) data, SrcSize / 2);
}
if ((bom[0] == 0xFF) && (bom[1] == 0xFE))
{
wstr = (WCHAR*) &((BYTE*) data)[2];
ConvertFromUnicode(CP_UTF8, 0, wstr,
(SrcSize - 2) / 2, &pSrcData, 0, NULL, NULL);
}
}
if (!pSrcData)
{
pSrcData = (char*) calloc(1, SrcSize + 1);
CopyMemory(pSrcData, data, SrcSize);
}
pDstData = (char*) calloc(1, SrcSize + 200);
strcpy(pDstData,
"Version:0.9\r\n"
"StartHTML:0000000000\r\n"
"EndHTML:0000000000\r\n"
"StartFragment:0000000000\r\n"
"EndFragment:0000000000\r\n");
body = strstr(pSrcData, "<body");
if (!body)
body = strstr(pSrcData, "<BODY");
/* StartHTML */
sprintf_s(num, sizeof(num), "%010lu", strlen(pDstData));
CopyMemory(&pDstData[23], num, 10);
if (!body)
strcat(pDstData, "<HTML><BODY>");
strcat(pDstData, "<!--StartFragment-->");
/* StartFragment */
sprintf_s(num, sizeof(num), "%010lu", strlen(pDstData));
CopyMemory(&pDstData[69], num, 10);
strcat(pDstData, pSrcData);
/* EndFragment */
sprintf_s(num, sizeof(num), "%010lu", strlen(pDstData));
CopyMemory(&pDstData[93], num, 10);
strcat(pDstData, "<!--EndFragment-->");
if (!body)
strcat(pDstData, "</BODY></HTML>");
/* EndHTML */
sprintf_s(num, sizeof(num), "%010lu", strlen(pDstData));
CopyMemory(&pDstData[43], num, 10);
*pSize = (UINT32) strlen(pDstData) + 1;
free(pSrcData);
}
return pDstData;
}
/**
* "text/html":
*
* HTML text format.
*/
static void* clipboard_synthesize_text_html(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize)
{
int beg;
int end;
char* str;
char* begStr;
char* endStr;
int SrcSize;
int DstSize = -1;
BYTE* pDstData = NULL;
if (formatId == ClipboardGetFormatId(clipboard, "HTML Format"))
{
str = (char*) data;
SrcSize = (int) *pSize;
begStr = strstr(str, "StartHTML:");
endStr = strstr(str, "EndHTML:");
if (!begStr || !endStr)
return NULL;
beg = atoi(&begStr[10]);
end = atoi(&endStr[8]);
if ((beg > SrcSize) || (end > SrcSize) || (beg >= end))
return NULL;
DstSize = end - beg;
pDstData = (BYTE*) malloc(SrcSize - beg + 1);
if (!pDstData)
return NULL;
CopyMemory(pDstData, &str[beg], DstSize);
DstSize = ConvertLineEndingToLF((char*) pDstData, DstSize);
*pSize = (UINT32) DstSize;
}
return (void*) pDstData;
}
BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
{
UINT32 formatId;
UINT32 altFormatId;
/**
* CF_TEXT
*/
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_LOCALE,
clipboard_synthesize_cf_locale);
altFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING");
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, altFormatId,
clipboard_synthesize_utf8_string);
/**
* CF_OEMTEXT
*/
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_TEXT,
clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_LOCALE,
clipboard_synthesize_cf_locale);
altFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING");
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, altFormatId,
clipboard_synthesize_utf8_string);
/**
* CF_UNICODETEXT
*/
ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_TEXT,
clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_LOCALE,
clipboard_synthesize_cf_locale);
altFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING");
ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, altFormatId,
clipboard_synthesize_utf8_string);
/**
* UTF8_STRING
*/
formatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING");
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
clipboard_synthesize_cf_locale);
}
/**
* text/plain
*/
formatId = ClipboardRegisterFormat(clipboard, "text/plain");
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
clipboard_synthesize_cf_locale);
}
/**
* TEXT
*/
formatId = ClipboardRegisterFormat(clipboard, "TEXT");
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
clipboard_synthesize_cf_locale);
}
/**
* STRING
*/
formatId = ClipboardRegisterFormat(clipboard, "STRING");
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
clipboard_synthesize_cf_locale);
}
/**
* CF_DIB
*/
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, CF_DIB, CF_DIBV5,
clipboard_synthesize_cf_dibv5);
altFormatId = ClipboardRegisterFormat(clipboard, "image/bmp");
ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
clipboard_synthesize_image_bmp);
}
/**
* CF_DIBV5
*/
if (formatId && 0)
{
ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, CF_DIB,
clipboard_synthesize_cf_dib);
altFormatId = ClipboardRegisterFormat(clipboard, "image/bmp");
ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
clipboard_synthesize_image_bmp);
}
/**
* image/bmp
*/
formatId = ClipboardRegisterFormat(clipboard, "image/bmp");
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_DIB,
clipboard_synthesize_cf_dib);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_DIBV5,
clipboard_synthesize_cf_dibv5);
}
/**
* HTML Format
*/
formatId = ClipboardRegisterFormat(clipboard, "HTML Format");
if (formatId)
{
altFormatId = ClipboardRegisterFormat(clipboard, "text/html");
ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId,
clipboard_synthesize_text_html);
}
/**
* text/html
*/
formatId = ClipboardRegisterFormat(clipboard, "text/html");
if (formatId)
{
altFormatId = ClipboardRegisterFormat(clipboard, "HTML Format");
ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId,
clipboard_synthesize_html_format);
}
return TRUE;
}

View File

@ -0,0 +1,3 @@
TestClipboard
TestClipboard.c

View File

@ -0,0 +1,25 @@
set(MODULE_NAME "TestClipboard")
set(MODULE_PREFIX "TEST_CLIPBOARD")
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestClipboardFormats.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
target_link_libraries(${MODULE_NAME} winpr)
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
foreach(test ${${MODULE_PREFIX}_TESTS})
get_filename_component(TestName ${test} NAME_WE)
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")

View File

@ -0,0 +1,94 @@
#include <winpr/crt.h>
#include <winpr/print.h>
#include <winpr/clipboard.h>
int TestClipboardFormats(int argc, char* argv[])
{
UINT32 index;
UINT32 count;
UINT32 formatId;
UINT32* pFormatIds;
const char* formatName;
wClipboard* clipboard;
UINT32 utf8StringFormatId;
clipboard = ClipboardCreate();
formatId = ClipboardRegisterFormat(clipboard, "text/html");
formatId = ClipboardRegisterFormat(clipboard, "image/bmp");
formatId = ClipboardRegisterFormat(clipboard, "image/png");
utf8StringFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING");
pFormatIds = NULL;
count = ClipboardGetRegisteredFormatIds(clipboard, &pFormatIds);
for (index = 0; index < count; index++)
{
formatId = pFormatIds[index];
formatName = ClipboardGetFormatName(clipboard, formatId);
fprintf(stderr, "Format: 0x%04X %s\n", formatId, formatName);
}
free(pFormatIds);
if (1)
{
BOOL bSuccess;
UINT32 SrcSize;
UINT32 DstSize;
char* pSrcData;
char* pDstData;
pSrcData = _strdup("this is a test string");
SrcSize = (UINT32) (strlen(pSrcData) + 1);
bSuccess = ClipboardSetData(clipboard, utf8StringFormatId, (void*) pSrcData, SrcSize);
fprintf(stderr, "ClipboardSetData: %d\n", bSuccess);
DstSize = 0;
pDstData = (char*) ClipboardGetData(clipboard, utf8StringFormatId, &DstSize);
fprintf(stderr, "ClipboardGetData: %s\n", pDstData);
free(pDstData);
}
if (1)
{
UINT32 DstSize;
char* pSrcData;
WCHAR* pDstData;
DstSize = 0;
pDstData = (WCHAR*) ClipboardGetData(clipboard, CF_UNICODETEXT, &DstSize);
pSrcData = NULL;
ConvertFromUnicode(CP_UTF8, 0, pDstData, -1, &pSrcData, 0, NULL, NULL);
fprintf(stderr, "ClipboardGetData (synthetic): %s\n", pSrcData);
free(pDstData);
free(pSrcData);
}
pFormatIds = NULL;
count = ClipboardGetFormatIds(clipboard, &pFormatIds);
for (index = 0; index < count; index++)
{
formatId = pFormatIds[index];
formatName = ClipboardGetFormatName(clipboard, formatId);
fprintf(stderr, "Format: 0x%04X %s\n", formatId, formatName);
}
free(pFormatIds);
ClipboardDestroy(clipboard);
return 0;
}

View File

@ -387,3 +387,81 @@ int lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
}
#endif
int ConvertLineEndingToLF(char* str, int size)
{
int status;
char* end;
char* pInput;
char* pOutput;
end = &str[size];
pInput = pOutput = str;
while (pInput < end)
{
if ((pInput[0] == '\r') && (pInput[1] == '\n'))
{
*pOutput++ = '\n';
pInput += 2;
}
else
{
*pOutput++ = *pInput++;
}
}
status = pOutput - str;
return status;
}
char* ConvertLineEndingToCRLF(const char* str, int* size)
{
int count;
char* newStr;
char* pOutput;
const char* end;
const char* pInput;
end = &str[*size];
count = 0;
pInput = str;
while (pInput < end)
{
if (*pInput == '\n')
count++;
pInput++;
}
newStr = (char*) malloc(*size + (count * 2) + 1);
if (!newStr)
return NULL;
pInput = str;
pOutput = newStr;
while (pInput < end)
{
if ((*pInput == '\n') && ((pInput > str) && (pInput[-1] != '\r')))
{
*pOutput++ = '\r';
*pOutput++ = '\n';
}
else
{
*pOutput++ = *pInput;
}
pInput++;
}
*size = pOutput - newStr;
return newStr;
}

View File

@ -376,3 +376,18 @@ int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int
return status;
}
/**
* Swap Unicode byte order (UTF16LE <-> UTF16BE)
*/
void ByteSwapUnicode(WCHAR* wstr, int length)
{
WCHAR* end = &wstr[length];
while (wstr < end)
{
*wstr = _byteswap_ushort(*wstr);
wstr++;
}
}

View File

@ -278,7 +278,7 @@ BOOL CloseHandle(HANDLE hObject)
BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
{
*((ULONG_PTR*) lpTargetHandle) = hSourceHandle;
*((ULONG_PTR*) lpTargetHandle) = (ULONG_PTR) hSourceHandle;
return TRUE;
}

View File

@ -78,9 +78,7 @@ typedef long PCSC_LONG;
#define PCSC_SCARD_CTL_CODE(code) (0x42000000 + (code))
#define PCSC_CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
#ifdef __APPLE__
#pragma pack(1)
#endif
#pragma pack(push, 1)
typedef struct
{
@ -99,16 +97,6 @@ typedef struct
PCSC_DWORD cbPciLength;
} PCSC_SCARD_IO_REQUEST;
#ifdef __APPLE__
#pragma pack()
#endif
#if defined(__APPLE__) | defined(sun)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
typedef struct
{
BYTE tag;
@ -116,11 +104,7 @@ typedef struct
UINT32 value;
} PCSC_TLV_STRUCTURE;
#if defined(__APPLE__) | defined(sun)
#pragma pack()
#else
#pragma pack(pop)
#endif
struct _PCSCFunctionTable
{

View File

@ -34,54 +34,6 @@
* Refer to "Compressed Image File Formats: JPEG, PNG, GIF, XBM, BMP" book
*/
#if defined(__APPLE__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct _WINPR_BITMAP_FILE_HEADER
{
BYTE bfType[2];
UINT32 bfSize;
UINT16 bfReserved1;
UINT16 bfReserved2;
UINT32 bfOffBits;
};
typedef struct _WINPR_BITMAP_FILE_HEADER WINPR_BITMAP_FILE_HEADER;
struct _WINPR_BITMAP_INFO_HEADER
{
UINT32 biSize;
INT32 biWidth;
INT32 biHeight;
UINT16 biPlanes;
UINT16 biBitCount;
UINT32 biCompression;
UINT32 biSizeImage;
INT32 biXPelsPerMeter;
INT32 biYPelsPerMeter;
UINT32 biClrUsed;
UINT32 biClrImportant;
};
typedef struct _WINPR_BITMAP_INFO_HEADER WINPR_BITMAP_INFO_HEADER;
struct _WINPR_BITMAP_CORE_HEADER
{
UINT32 bcSize;
UINT16 bcWidth;
UINT16 bcHeight;
UINT16 bcPlanes;
UINT16 bcBitCount;
};
typedef struct _WINPR_BITMAP_CORE_HEADER WINPR_BITMAP_CORE_HEADER;
#if defined(__APPLE__)
#pragma pack()
#else
#pragma pack(pop)
#endif
int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp)
{
FILE* fp;

View File

@ -197,10 +197,12 @@ int WtsApi32_InitializeWtsApi(void)
WTSAPI32_LOAD_PROC(IsChildSessionsEnabled, WTS_IS_CHILD_SESSIONS_ENABLED_FN);
WTSAPI32_LOAD_PROC(GetChildSessionId, WTS_GET_CHILD_SESSION_ID_FN);
WTSAPI32_LOAD_PROC(GetActiveConsoleSessionId, WTS_GET_ACTIVE_CONSOLE_SESSION_ID_FN);
g_WtsApi = &WtsApi32_WtsApiFunctionTable;
Win32_InitializeWinSta(g_WtsApi);
Win32_InitializeWinSta(&WtsApi32_WtsApiFunctionTable);
#endif
g_WtsApi = &WtsApi32_WtsApiFunctionTable;
return 1;
}