--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * 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.
+ */
+
+#import "Clipboard.h"
+
+int mac_cliprdr_send_client_format_list(CliprdrClientContext* cliprdr)
+{
+ UINT32 index;
+ UINT32 formatId;
+ UINT32 numFormats;
+ UINT32* pFormatIds;
+ const char* formatName;
+ CLIPRDR_FORMAT* formats;
+ CLIPRDR_FORMAT_LIST formatList;
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+
+ ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
+
+ pFormatIds = NULL;
+ numFormats = ClipboardGetFormatIds(mfc->clipboard, &pFormatIds);
+
+ formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT));
+
+ if (!formats)
+ return -1;
+
+ for (index = 0; index < numFormats; index++)
+ {
+ formatId = pFormatIds[index];
+ formatName = ClipboardGetFormatName(mfc->clipboard, formatId);
+
+ formats[index].formatId = formatId;
+ formats[index].formatName = NULL;
+
+ if ((formatId > CF_MAX) && formatName)
+ formats[index].formatName = _strdup(formatName);
+ }
+
+ formatList.msgFlags = CB_RESPONSE_OK;
+ formatList.numFormats = numFormats;
+ formatList.formats = formats;
+
+ mfc->cliprdr->ClientFormatList(mfc->cliprdr, &formatList);
+
+ free(pFormatIds);
+ free(formats);
+
+ return 1;
+}
+
+int mac_cliprdr_send_client_format_data_request(CliprdrClientContext* cliprdr, UINT32 formatId)
+{
+ CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+
+ ZeroMemory(&formatDataRequest, sizeof(CLIPRDR_FORMAT_DATA_REQUEST));
+
+ formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
+ formatDataRequest.msgFlags = 0;
+
+ formatDataRequest.requestedFormatId = formatId;
+ mfc->requestedFormatId = formatId;
+ ResetEvent(mfc->clipboardRequestEvent);
+
+ cliprdr->ClientFormatDataRequest(cliprdr, &formatDataRequest);
+
+ return 1;
+}
+
+int mac_cliprdr_send_client_capabilities(CliprdrClientContext* cliprdr)
+{
+ CLIPRDR_CAPABILITIES capabilities;
+ CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
+
+ capabilities.cCapabilitiesSets = 1;
+ capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet);
+
+ generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
+ generalCapabilitySet.capabilitySetLength = 12;
+
+ generalCapabilitySet.version = CB_CAPS_VERSION_2;
+ generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
+
+ cliprdr->ClientCapabilities(cliprdr, &capabilities);
+
+ return 1;
+}
+
+int mac_cliprdr_monitor_ready(CliprdrClientContext* cliprdr, CLIPRDR_MONITOR_READY* monitorReady)
+{
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+
+ mfc->clipboardSync = TRUE;
+ mac_cliprdr_send_client_capabilities(cliprdr);
+ mac_cliprdr_send_client_format_list(cliprdr);
+
+ return 1;
+}
+
+int mac_cliprdr_server_capabilities(CliprdrClientContext* cliprdr, CLIPRDR_CAPABILITIES* capabilities)
+{
+ UINT32 index;
+ CLIPRDR_CAPABILITY_SET* capabilitySet;
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+
+ for (index = 0; index < capabilities->cCapabilitiesSets; index++)
+ {
+ capabilitySet = &(capabilities->capabilitySets[index]);
+
+ if ((capabilitySet->capabilitySetType == CB_CAPSTYPE_GENERAL) &&
+ (capabilitySet->capabilitySetLength >= CB_CAPSTYPE_GENERAL_LEN))
+ {
+ CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet
+ = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilitySet;
+
+ mfc->clipboardCapabilities = generalCapabilitySet->generalFlags;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+int mac_cliprdr_server_format_list(CliprdrClientContext* cliprdr, CLIPRDR_FORMAT_LIST* formatList)
+{
+ UINT32 index;
+ CLIPRDR_FORMAT* format;
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+
+ if (mfc->serverFormats)
+ {
+ for (index = 0; index < mfc->numServerFormats; index++)
+ {
+ free(mfc->serverFormats[index].formatName);
+ }
+
+ free(mfc->serverFormats);
+ mfc->serverFormats = NULL;
+ mfc->numServerFormats = 0;
+ }
+
+ if (formatList->numFormats < 1)
+ return 1;
+
+ mfc->numServerFormats = formatList->numFormats;
+ mfc->serverFormats = (CLIPRDR_FORMAT*) calloc(mfc->numServerFormats, sizeof(CLIPRDR_FORMAT));
+
+ if (!mfc->serverFormats)
+ return -1;
+
+ for (index = 0; index < mfc->numServerFormats; index++)
+ {
+ mfc->serverFormats[index].formatId = formatList->formats[index].formatId;
+ mfc->serverFormats[index].formatName = NULL;
+
+ if (formatList->formats[index].formatName)
+ mfc->serverFormats[index].formatName = _strdup(formatList->formats[index].formatName);
+ }
+
+ for (index = 0; index < mfc->numServerFormats; index++)
+ {
+ format = &(mfc->serverFormats[index]);
+
+ if (format->formatId == CF_UNICODETEXT)
+ {
+ mac_cliprdr_send_client_format_data_request(cliprdr, CF_UNICODETEXT);
+ break;
+ }
+ else if (format->formatId == CF_TEXT)
+ {
+ mac_cliprdr_send_client_format_data_request(cliprdr, CF_TEXT);
+ break;
+ }
+ }
+
+ return 1;
+}
+
+int mac_cliprdr_server_format_list_response(CliprdrClientContext* cliprdr, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse)
+{
+ return 1;
+}
+
+int mac_cliprdr_server_lock_clipboard_data(CliprdrClientContext* cliprdr, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
+{
+ return 1;
+}
+
+int mac_cliprdr_server_unlock_clipboard_data(CliprdrClientContext* cliprdr, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
+{
+ return 1;
+}
+
+int mac_cliprdr_server_format_data_request(CliprdrClientContext* cliprdr, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
+{
+ BYTE* data;
+ UINT32 size;
+ UINT32 formatId;
+ CLIPRDR_FORMAT_DATA_RESPONSE response;
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+
+ ZeroMemory(&response, sizeof(CLIPRDR_FORMAT_DATA_RESPONSE));
+
+ formatId = formatDataRequest->requestedFormatId;
+ data = (BYTE*) ClipboardGetData(mfc->clipboard, formatId, &size);
+
+ response.msgFlags = CB_RESPONSE_OK;
+ response.dataLen = size;
+ response.requestedFormatData = data;
+
+ if (!data)
+ {
+ response.msgFlags = CB_RESPONSE_FAIL;
+ response.dataLen = 0;
+ response.requestedFormatData = NULL;
+ }
+
+ cliprdr->ClientFormatDataResponse(cliprdr, &response);
+
+ free(data);
+
+ return 1;
+}
+
+int mac_cliprdr_server_format_data_response(CliprdrClientContext* cliprdr, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse)
+{
+ BYTE* data;
+ UINT32 size;
+ UINT32 index;
+ UINT32 formatId;
+ CLIPRDR_FORMAT* format = NULL;
+ mfContext* mfc = (mfContext*) cliprdr->custom;
+ MRDPView* view = (MRDPView*) mfc->view;
+
+ for (index = 0; index < mfc->numServerFormats; index++)
+ {
+ if (mfc->requestedFormatId == mfc->serverFormats[index].formatId)
+ format = &(mfc->serverFormats[index]);
+ }
+
+ if (!format)
+ {
+ SetEvent(mfc->clipboardRequestEvent);
+ return -1;
+ }
+
+ if (format->formatName)
+ formatId = ClipboardRegisterFormat(mfc->clipboard, format->formatName);
+ else
+ formatId = format->formatId;
+
+ size = formatDataResponse->dataLen;
+ data = (BYTE*) malloc(size);
+ CopyMemory(data, formatDataResponse->requestedFormatData, size);
+
+ ClipboardSetData(mfc->clipboard, formatId, data, size);
+
+ SetEvent(mfc->clipboardRequestEvent);
+
+ if ((formatId == CF_TEXT) || (formatId == CF_UNICODETEXT))
+ {
+ formatId = ClipboardRegisterFormat(mfc->clipboard, "UTF8_STRING");
+
+ data = (void*) ClipboardGetData(mfc->clipboard, formatId, &size);
+ NSString* str = [[NSString alloc] initWithBytes: (void*) data length:size encoding:NSUTF8StringEncoding];
+ free(data);
+
+ NSArray* types = [[NSArray alloc] initWithObjects:NSStringPboardType, nil];
+ [view->pasteboard_wr declareTypes:types owner:view];
+ [view->pasteboard_wr setString:str forType:NSStringPboardType];
+ }
+
+ return 1;
+}
+
+int mac_cliprdr_server_file_contents_request(CliprdrClientContext* cliprdr, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
+{
+ return 1;
+}
+
+int mac_cliprdr_server_file_contents_response(CliprdrClientContext* cliprdr, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
+{
+ return 1;
+}
+
+void mac_cliprdr_init(mfContext* mfc, CliprdrClientContext* cliprdr)
+{
+ cliprdr->custom = (void*) mfc;
+ mfc->cliprdr = cliprdr;
+
+ mfc->clipboard = ClipboardCreate();
+ mfc->clipboardRequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ cliprdr->MonitorReady = mac_cliprdr_monitor_ready;
+ cliprdr->ServerCapabilities = mac_cliprdr_server_capabilities;
+ cliprdr->ServerFormatList = mac_cliprdr_server_format_list;
+ cliprdr->ServerFormatListResponse = mac_cliprdr_server_format_list_response;
+ cliprdr->ServerLockClipboardData = mac_cliprdr_server_lock_clipboard_data;
+ cliprdr->ServerUnlockClipboardData = mac_cliprdr_server_unlock_clipboard_data;
+ cliprdr->ServerFormatDataRequest = mac_cliprdr_server_format_data_request;
+ cliprdr->ServerFormatDataResponse = mac_cliprdr_server_format_data_response;
+ cliprdr->ServerFileContentsRequest = mac_cliprdr_server_file_contents_request;
+ cliprdr->ServerFileContentsResponse = mac_cliprdr_server_file_contents_response;
+}
+
+void mac_cliprdr_uninit(mfContext* mfc, CliprdrClientContext* cliprdr)
+{
+ cliprdr->custom = NULL;
+ mfc->cliprdr = NULL;
+
+ ClipboardDestroy(mfc->clipboard);
+ CloseHandle(mfc->clipboardRequestEvent);
+}
#import "mfreerdp.h"
#import "MRDPView.h"
#import "MRDPCursor.h"
+#import "Clipboard.h"
#import "PasswordDialog.h"
#include <winpr/crt.h>
#import "freerdp/gdi/dc.h"
#import "freerdp/gdi/region.h"
#import "freerdp/graphics.h"
-#import "freerdp/utils/event.h"
-#import "freerdp/client/cliprdr.h"
#import "freerdp/client/file.h"
#import "freerdp/client/cmdline.h"
#import "freerdp/log.h"
static void update_activity_cb(freerdp* instance);
static void input_activity_cb(freerdp* instance);
-static void channel_activity_cb(freerdp* instance);
-
-int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data);
-int receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size);
-
-void process_cliprdr_event(freerdp* instance, wMessage* event);
-void cliprdr_process_cb_format_list_event(freerdp* instance, RDP_CB_FORMAT_LIST_EVENT* event);
-void cliprdr_send_data_request(freerdp* instance, UINT32 format);
-void cliprdr_process_cb_monitor_ready_event(freerdp* inst);
-void cliprdr_process_cb_data_response_event(freerdp* instance, RDP_CB_DATA_RESPONSE_EVENT* event);
-void cliprdr_process_text(freerdp* instance, BYTE* data, int len);
-void cliprdr_send_supported_format_list(freerdp* instance);
-int register_channel_fds(int* fds, int count, freerdp* instance);
DWORD mac_client_thread(void* param);
-struct cursor
-{
- rdpPointer* pointer;
- BYTE* cursor_data;
- void* bmiRep; /* NSBitmapImageRep */
- void* nsCursor; /* NSCursor */
- void* nsImage; /* NSImage */
-};
-
-struct rgba_data
-{
- char red;
- char green;
- char blue;
- char alpha;
-};
-
@implementation MRDPView
@synthesize is_connected;
return 0;
}
-DWORD mac_client_channels_thread(void* param)
-{
- int status;
- wMessage* event;
- HANDLE channelsEvent;
- rdpChannels* channels;
- rdpContext* context = (rdpContext*) param;
-
- channels = context->channels;
- channelsEvent = freerdp_channels_get_event_handle(context->instance);
-
- while (WaitForSingleObject(channelsEvent, INFINITE) == WAIT_OBJECT_0)
- {
- status = freerdp_channels_process_pending_messages(context->instance);
-
- if (!status)
- break;
-
- event = freerdp_channels_pop_event(context->channels);
-
- if (event)
- {
- switch (GetMessageClass(event->id))
- {
- case CliprdrChannel_Class:
- process_cliprdr_event(context->instance, event);
- break;
- }
-
- freerdp_event_free(event);
- }
- }
-
- ExitThread(0);
- return 0;
-}
-
DWORD mac_client_thread(void* param)
{
@autoreleasepool
HANDLE updateEvent;
HANDLE updateThread;
HANDLE channelsEvent;
- HANDLE channelsThread;
DWORD nCount;
rdpContext* context = (rdpContext*) param;
events[nCount++] = inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
- if (settings->AsyncChannels)
- {
- channelsThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_channels_thread, context, 0, NULL);
- }
- else
- {
- events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
- }
+ events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
while (1)
{
}
}
- if (!settings->AsyncChannels)
+ if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
{
- if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
- {
- channel_activity_cb(instance);
- }
+ freerdp_channels_process_pending_messages(instance);
}
}
CloseHandle(inputThread);
}
- if (settings->AsyncChannels)
- {
- WaitForSingleObject(channelsThread, INFINITE);
- CloseHandle(channelsThread);
- }
-
ExitThread(0);
return 0;
}
- (void) onPasteboardTimerFired :(NSTimer*) timer
{
- int i;
- NSArray* types;
+ BYTE* data;
+ UINT32 size;
+ UINT32 formatId;
+ BOOL formatMatch;
+ int changeCount;
+ NSData* formatData;
+ const char* formatType;
+ NSPasteboardItem* item;
+
+ changeCount = (int) [pasteboard_rd changeCount];
+
+ if (changeCount == pasteboard_changecount)
+ return;
+
+ pasteboard_changecount = changeCount;
+
+ NSArray* items = [pasteboard_rd pasteboardItems];
+
+ if ([items count] < 1)
+ return;
+
+ item = [items objectAtIndex:0];
+
+ /**
+ * System-Declared Uniform Type Identifiers:
+ * https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
+ */
- i = (int) [pasteboard_rd changeCount];
+ formatMatch = FALSE;
- if (i != pasteboard_changecount)
+ for (NSString* type in [item types])
{
- pasteboard_changecount = i;
- types = [NSArray arrayWithObject:NSStringPboardType];
- NSString *str = [pasteboard_rd availableTypeFromArray:types];
- if (str != nil)
+ formatType = [type UTF8String];
+
+ if (strcmp(formatType, "public.utf8-plain-text") == 0)
{
- cliprdr_send_supported_format_list(instance);
+ formatData = [item dataForType:type];
+ formatId = ClipboardRegisterFormat(mfc->clipboard, "UTF8_STRING");
+
+ size = (UINT32) [formatData length];
+
+ data = (BYTE*) malloc(size);
+ [formatData getBytes:data length:size];
+
+ ClipboardSetData(mfc->clipboard, formatId, (void*) data, size);
+ formatMatch = TRUE;
+
+ break;
}
}
+
+ if (!formatMatch)
+ ClipboardEmpty(mfc->clipboard);
+
+ if (mfc->clipboardSync)
+ mac_cliprdr_send_client_format_list(mfc->cliprdr);
+}
+
+- (void) pause
+{
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self->pasteboard_timer invalidate];
+ });
+
+ NSArray* trackingAreas = self.trackingAreas;
+
+ for (NSTrackingArea* ta in trackingAreas)
+ {
+ [self removeTrackingArea:ta];
+ }
+}
+
+- (void)resume
+{
+ dispatch_async(dispatch_get_main_queue(), ^{
+ self->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES];
+ });
+
+ NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
+ [self addTrackingArea:trackingArea];
+ [trackingArea release];
}
- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height
void mac_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
{
rdpSettings* settings = context->settings;
+ mfContext* mfc = (mfContext*) context;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
+ else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
+ {
+ mac_cliprdr_init(mfc, (CliprdrClientContext*) e->pInterface);
+ }
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
void mac_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
{
rdpSettings* settings = context->settings;
+ mfContext* mfc = (mfContext*) context;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
+ else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
+ {
+ mac_cliprdr_uninit(mfc, (CliprdrClientContext*) e->pInterface);
+ }
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
view->pasteboard_wr = [NSPasteboard generalPasteboard];
/* setup pasteboard for read operations */
- view->pasteboard_rd = [NSPasteboard generalPasteboard];
- view->pasteboard_changecount = (int) [view->pasteboard_rd changeCount];
- view->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:mfc->view selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ view->pasteboard_rd = [NSPasteboard generalPasteboard];
+ view->pasteboard_changecount = -1;
+ });
+
+ [view resume];
mfc->appleKeyboardType = mac_detect_keyboard_type();
}
}
-static void channel_activity_cb(freerdp* instance)
-{
- wMessage* event;
-
- freerdp_channels_process_pending_messages(instance);
- event = freerdp_channels_pop_event(instance->context->channels);
-
- if (event)
- {
- WLog_DBG(TAG, "channel_activity_cb: message %d", event->id);
-
- switch (GetMessageClass(event->id))
- {
- case CliprdrChannel_Class:
- process_cliprdr_event(instance, event);
- break;
- }
-
- freerdp_event_free(event);
- }
-}
-
-int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data)
-{
- rdpChannels* channels = (rdpChannels*) user_data;
-
- freerdp_channels_load_plugin(channels, settings, name, plugin_data);
-
- return 1;
-}
-
-/*
- * stuff related to clipboard redirection
- */
-
-void cliprdr_process_cb_data_request_event(freerdp* instance)
-{
- int len;
- NSArray* types;
- RDP_CB_DATA_RESPONSE_EVENT* event;
- mfContext* mfc = (mfContext*) instance->context;
- MRDPView* view = (MRDPView*) mfc->view;
-
- event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_DataResponse, NULL, NULL);
-
- types = [NSArray arrayWithObject:NSStringPboardType];
- NSString* str = [view->pasteboard_rd availableTypeFromArray:types];
-
- if (str == nil)
- {
- event->data = NULL;
- event->size = 0;
- }
- else
- {
- NSString* data = [view->pasteboard_rd stringForType:NSStringPboardType];
- len = (int) ([data length] * 2 + 2);
- event->data = malloc(len);
- [data getCString:(char *) event->data maxLength:len encoding:NSUnicodeStringEncoding];
- event->size = len;
- }
-
- freerdp_channels_send_event(instance->context->channels, (wMessage*) event);
-}
-
-void cliprdr_send_data_request(freerdp* instance, UINT32 format)
-{
- RDP_CB_DATA_REQUEST_EVENT* event;
-
- event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_DataRequest, NULL, NULL);
-
- event->format = format;
- freerdp_channels_send_event(instance->context->channels, (wMessage*) event);
-}
-
-/**
- * at the moment, only the following formats are supported
- * CF_TEXT
- * CF_UNICODETEXT
- */
-
-void cliprdr_process_cb_data_response_event(freerdp* instance, RDP_CB_DATA_RESPONSE_EVENT* event)
-{
- NSString* str;
- NSArray* types;
- mfContext* mfc = (mfContext*) instance->context;
- MRDPView* view = (MRDPView*) mfc->view;
-
- if (event->size == 0)
- return;
-
- 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];
- [view->pasteboard_wr declareTypes:types owner:mfc->view];
- [view->pasteboard_wr setString:str forType:NSStringPboardType];
- }
-}
-
-void cliprdr_process_cb_monitor_ready_event(freerdp* instance)
-{
- wMessage* event;
- RDP_CB_FORMAT_LIST_EVENT* format_list_event;
-
- event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL);
-
- format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event;
- format_list_event->num_formats = 0;
-
- freerdp_channels_send_event(instance->context->channels, event);
-}
-
-/**
- * list of supported clipboard formats; currently only the following are supported
- * CF_TEXT
- * CF_UNICODETEXT
- */
-
-void cliprdr_process_cb_format_list_event(freerdp* instance, RDP_CB_FORMAT_LIST_EVENT* event)
-{
- int i;
- mfContext* mfc = (mfContext*) instance->context;
- MRDPView* view = (MRDPView*) mfc->view;
-
- if (event->num_formats == 0)
- return;
-
- for (i = 0; i < event->num_formats; i++)
- {
- switch (event->formats[i])
- {
- case CF_TEXT:
- case CF_UNICODETEXT:
- view->pasteboard_format = CF_UNICODETEXT;
- cliprdr_send_data_request(instance, CF_UNICODETEXT);
- return;
- break;
- }
- }
-}
-
-void process_cliprdr_event(freerdp* instance, wMessage* event)
-{
- if (event)
- {
- switch (GetMessageType(event->id))
- {
- /*
- * Monitor Ready PDU is sent by server to indicate that it has been
- * initialized and is ready. This PDU is transmitted by the server after it has sent
- * Clipboard Capabilities PDU
- */
- case CliprdrChannel_MonitorReady:
- cliprdr_process_cb_monitor_ready_event(instance);
- break;
-
- /*
- * The Format List PDU is sent either by the client or the server when its
- * local system clipboard is updated with new clipboard data. This PDU
- * contains the Clipboard Format ID and name pairs of the new Clipboard
- * Formats on the clipboard
- */
- case CliprdrChannel_FormatList:
- cliprdr_process_cb_format_list_event(instance, (RDP_CB_FORMAT_LIST_EVENT*) event);
- break;
-
- /*
- * The Format Data Request PDU is sent by the receipient of the Format List PDU.
- * It is used to request the data for one of the formats that was listed in the
- * Format List PDU
- */
- case CliprdrChannel_DataRequest:
- cliprdr_process_cb_data_request_event(instance);
- break;
-
- /*
- * The Format Data Response PDU is sent as a reply to the Format Data Request PDU.
- * It is used to indicate whether processing of the Format Data Request PDU
- * was successful. If the processing was successful, the Format Data Response PDU
- * includes the contents of the requested clipboard data
- */
- case CliprdrChannel_DataResponse:
- cliprdr_process_cb_data_response_event(instance, (RDP_CB_DATA_RESPONSE_EVENT*) event);
- break;
-
- default:
- WLog_ERR(TAG, "process_cliprdr_event: unknown event type %d", GetMessageType(event->id));
- break;
- }
- }
-}
-
-void cliprdr_send_supported_format_list(freerdp* instance)
-{
- RDP_CB_FORMAT_LIST_EVENT* event;
-
- event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL);
-
- event->formats = (UINT32*) malloc(sizeof(UINT32) * 1);
- event->num_formats = 1;
- event->formats[0] = CF_UNICODETEXT;
-
- freerdp_channels_send_event(instance->context->channels, (wMessage*) event);
-}
-
/**
* given a rect with 0,0 at the top left (windows cords)
* convert it to a rect with 0,0 at the bottom left (apple cords)