Merge pull request #2169 from awakecoding/master
Clipboard, RemoteApp, Cursor + Color Conversion
This commit is contained in:
commit
8330b03a0e
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
struct cliprdr_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
|
||||
wLog* log;
|
||||
BOOL received_caps;
|
||||
BOOL use_long_format_names;
|
||||
BOOL stream_fileclip_enabled;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
@ -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__
|
@ -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);
|
||||
}
|
||||
}
|
@ -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__
|
@ -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);
|
||||
}
|
||||
}
|
@ -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__
|
@ -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__)
|
||||
|
@ -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
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
@ -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 */
|
||||
|
@ -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++)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include <freerdp/codec/mppc.h>
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct _XCRUSH_MATCH_INFO
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -287,7 +287,6 @@ struct rdp_gdi
|
||||
BOOL invert;
|
||||
HGDI_DC hdc;
|
||||
UINT32 format;
|
||||
HCLRCONV clrconv;
|
||||
gdiBitmap* primary;
|
||||
gdiBitmap* drawing;
|
||||
UINT32 bitmap_size;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
2
rdtk/sample/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
rdtk-sample
|
||||
|
35
rdtk/sample/CMakeLists.txt
Normal file
35
rdtk/sample/CMakeLists.txt
Normal 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
147
rdtk/sample/rdtk_x11.c
Normal 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;
|
||||
}
|
64
winpr/include/winpr/clipboard.h
Normal file
64
winpr/include/winpr/clipboard.h
Normal 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 */
|
||||
|
@ -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/
|
||||
|
@ -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
101
winpr/include/winpr/pack.h
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
259
winpr/include/winpr/user.h
Normal 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 */
|
||||
|
@ -379,4 +379,6 @@ typedef WORD LANGID;
|
||||
|
||||
#endif
|
||||
|
||||
#include <winpr/user.h>
|
||||
|
||||
#endif /* WINPR_WTYPES_H */
|
||||
|
@ -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})
|
||||
|
25
winpr/libwinpr/clipboard/CMakeLists.txt
Normal file
25
winpr/libwinpr/clipboard/CMakeLists.txt
Normal 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()
|
9
winpr/libwinpr/clipboard/ModuleOptions.cmake
Normal file
9
winpr/libwinpr/clipboard/ModuleOptions.cmake
Normal 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")
|
||||
|
498
winpr/libwinpr/clipboard/clipboard.c
Normal file
498
winpr/libwinpr/clipboard/clipboard.c
Normal 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);
|
||||
}
|
68
winpr/libwinpr/clipboard/clipboard.h
Normal file
68
winpr/libwinpr/clipboard/clipboard.h
Normal 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 */
|
672
winpr/libwinpr/clipboard/synthetic.c
Normal file
672
winpr/libwinpr/clipboard/synthetic.c
Normal 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;
|
||||
}
|
3
winpr/libwinpr/clipboard/test/.gitignore
vendored
Normal file
3
winpr/libwinpr/clipboard/test/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
TestClipboard
|
||||
TestClipboard.c
|
||||
|
25
winpr/libwinpr/clipboard/test/CMakeLists.txt
Normal file
25
winpr/libwinpr/clipboard/test/CMakeLists.txt
Normal 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")
|
94
winpr/libwinpr/clipboard/test/TestClipboardFormats.c
Normal file
94
winpr/libwinpr/clipboard/test/TestClipboardFormats.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user