mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
mfreerdp: rewrite and update clipboard code
This commit is contained in:
parent
c5c9423ccf
commit
92d08cf58f
@ -32,6 +32,7 @@ set(${MODULE_PREFIX}_OBJECTIVE_SOURCES
|
|||||||
MRDPCursor.m
|
MRDPCursor.m
|
||||||
MRDPView.m
|
MRDPView.m
|
||||||
Keyboard.m
|
Keyboard.m
|
||||||
|
Clipboard.m
|
||||||
PasswordDialog.m)
|
PasswordDialog.m)
|
||||||
|
|
||||||
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
|
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
|
||||||
@ -42,6 +43,7 @@ set(${MODULE_PREFIX}_HEADERS
|
|||||||
MRDPCursor.h
|
MRDPCursor.h
|
||||||
MRDPView.h
|
MRDPView.h
|
||||||
Keyboard.h
|
Keyboard.h
|
||||||
|
Clipboard.h
|
||||||
PasswordDialog.h)
|
PasswordDialog.h)
|
||||||
|
|
||||||
set(${MODULE_PREFIX}_RESOURCES "en.lproj/InfoPlist.strings")
|
set(${MODULE_PREFIX}_RESOURCES "en.lproj/InfoPlist.strings")
|
||||||
|
29
client/Mac/Clipboard.h
Normal file
29
client/Mac/Clipboard.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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 "mfreerdp.h"
|
||||||
|
#import "mf_client.h"
|
||||||
|
|
||||||
|
#import "freerdp/freerdp.h"
|
||||||
|
#import "freerdp/channels/channels.h"
|
||||||
|
#import "freerdp/client/cliprdr.h"
|
||||||
|
|
||||||
|
int mac_cliprdr_send_client_format_list(CliprdrClientContext* cliprdr);
|
||||||
|
|
||||||
|
void mac_cliprdr_init(mfContext* mfc, CliprdrClientContext* cliprdr);
|
||||||
|
void mac_cliprdr_uninit(mfContext* mfc, CliprdrClientContext* cliprdr);
|
328
client/Mac/Clipboard.m
Normal file
328
client/Mac/Clipboard.m
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
@ -51,8 +51,8 @@
|
|||||||
BOOL skipMoveWindowOnce;
|
BOOL skipMoveWindowOnce;
|
||||||
|
|
||||||
@public
|
@public
|
||||||
NSPasteboard* pasteboard_rd; /* for reading from clipboard */
|
NSPasteboard* pasteboard_rd;
|
||||||
NSPasteboard* pasteboard_wr; /* for writing to clipboard */
|
NSPasteboard* pasteboard_wr;
|
||||||
int pasteboard_changecount;
|
int pasteboard_changecount;
|
||||||
int pasteboard_format;
|
int pasteboard_format;
|
||||||
int is_connected;
|
int is_connected;
|
||||||
@ -63,6 +63,8 @@
|
|||||||
- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height;
|
- (void) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height;
|
||||||
|
|
||||||
- (void) onPasteboardTimerFired :(NSTimer *) timer;
|
- (void) onPasteboardTimerFired :(NSTimer *) timer;
|
||||||
|
- (void) pause;
|
||||||
|
- (void) resume;
|
||||||
- (void) releaseResources;
|
- (void) releaseResources;
|
||||||
|
|
||||||
@property (assign) int is_connected;
|
@property (assign) int is_connected;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#import "mfreerdp.h"
|
#import "mfreerdp.h"
|
||||||
#import "MRDPView.h"
|
#import "MRDPView.h"
|
||||||
#import "MRDPCursor.h"
|
#import "MRDPCursor.h"
|
||||||
|
#import "Clipboard.h"
|
||||||
#import "PasswordDialog.h"
|
#import "PasswordDialog.h"
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
@ -39,8 +40,6 @@
|
|||||||
#import "freerdp/gdi/dc.h"
|
#import "freerdp/gdi/dc.h"
|
||||||
#import "freerdp/gdi/region.h"
|
#import "freerdp/gdi/region.h"
|
||||||
#import "freerdp/graphics.h"
|
#import "freerdp/graphics.h"
|
||||||
#import "freerdp/utils/event.h"
|
|
||||||
#import "freerdp/client/cliprdr.h"
|
|
||||||
#import "freerdp/client/file.h"
|
#import "freerdp/client/file.h"
|
||||||
#import "freerdp/client/cmdline.h"
|
#import "freerdp/client/cmdline.h"
|
||||||
#import "freerdp/log.h"
|
#import "freerdp/log.h"
|
||||||
@ -59,39 +58,9 @@ void mac_desktop_resize(rdpContext* context);
|
|||||||
|
|
||||||
static void update_activity_cb(freerdp* instance);
|
static void update_activity_cb(freerdp* instance);
|
||||||
static void input_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);
|
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
|
@implementation MRDPView
|
||||||
|
|
||||||
@synthesize is_connected;
|
@synthesize is_connected;
|
||||||
@ -183,43 +152,6 @@ DWORD mac_client_input_thread(void* param)
|
|||||||
return 0;
|
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)
|
DWORD mac_client_thread(void* param)
|
||||||
{
|
{
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
@ -231,7 +163,6 @@ DWORD mac_client_thread(void* param)
|
|||||||
HANDLE updateEvent;
|
HANDLE updateEvent;
|
||||||
HANDLE updateThread;
|
HANDLE updateThread;
|
||||||
HANDLE channelsEvent;
|
HANDLE channelsEvent;
|
||||||
HANDLE channelsThread;
|
|
||||||
|
|
||||||
DWORD nCount;
|
DWORD nCount;
|
||||||
rdpContext* context = (rdpContext*) param;
|
rdpContext* context = (rdpContext*) param;
|
||||||
@ -272,14 +203,7 @@ DWORD mac_client_thread(void* param)
|
|||||||
events[nCount++] = inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
events[nCount++] = inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->AsyncChannels)
|
events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
|
||||||
{
|
|
||||||
channelsThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_channels_thread, context, 0, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -307,12 +231,9 @@ DWORD mac_client_thread(void* param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings->AsyncChannels)
|
if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
|
freerdp_channels_process_pending_messages(instance);
|
||||||
{
|
|
||||||
channel_activity_cb(instance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,12 +253,6 @@ DWORD mac_client_thread(void* param)
|
|||||||
CloseHandle(inputThread);
|
CloseHandle(inputThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->AsyncChannels)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(channelsThread, INFINITE);
|
|
||||||
CloseHandle(channelsThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitThread(0);
|
ExitThread(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -798,21 +713,87 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type)
|
|||||||
|
|
||||||
- (void) onPasteboardTimerFired :(NSTimer*) timer
|
- (void) onPasteboardTimerFired :(NSTimer*) timer
|
||||||
{
|
{
|
||||||
int i;
|
BYTE* data;
|
||||||
NSArray* types;
|
UINT32 size;
|
||||||
|
UINT32 formatId;
|
||||||
|
BOOL formatMatch;
|
||||||
|
int changeCount;
|
||||||
|
NSData* formatData;
|
||||||
|
const char* formatType;
|
||||||
|
NSPasteboardItem* item;
|
||||||
|
|
||||||
i = (int) [pasteboard_rd changeCount];
|
changeCount = (int) [pasteboard_rd changeCount];
|
||||||
|
|
||||||
if (i != pasteboard_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
|
||||||
|
*/
|
||||||
|
|
||||||
|
formatMatch = FALSE;
|
||||||
|
|
||||||
|
for (NSString* type in [item types])
|
||||||
{
|
{
|
||||||
pasteboard_changecount = i;
|
formatType = [type UTF8String];
|
||||||
types = [NSArray arrayWithObject:NSStringPboardType];
|
|
||||||
NSString *str = [pasteboard_rd availableTypeFromArray:types];
|
if (strcmp(formatType, "public.utf8-plain-text") == 0)
|
||||||
if (str != nil)
|
|
||||||
{
|
{
|
||||||
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) setScrollOffset:(int)xOffset y:(int)yOffset w:(int)width h:(int)height
|
||||||
@ -826,6 +807,7 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type)
|
|||||||
void mac_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
|
void mac_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
|
||||||
{
|
{
|
||||||
rdpSettings* settings = context->settings;
|
rdpSettings* settings = context->settings;
|
||||||
|
mfContext* mfc = (mfContext*) context;
|
||||||
|
|
||||||
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||||
{
|
{
|
||||||
@ -836,6 +818,10 @@ void mac_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEve
|
|||||||
if (settings->SoftwareGdi)
|
if (settings->SoftwareGdi)
|
||||||
gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface);
|
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)
|
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -845,6 +831,7 @@ void mac_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEve
|
|||||||
void mac_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
|
void mac_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
|
||||||
{
|
{
|
||||||
rdpSettings* settings = context->settings;
|
rdpSettings* settings = context->settings;
|
||||||
|
mfContext* mfc = (mfContext*) context;
|
||||||
|
|
||||||
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||||
{
|
{
|
||||||
@ -855,6 +842,10 @@ void mac_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnec
|
|||||||
if (settings->SoftwareGdi)
|
if (settings->SoftwareGdi)
|
||||||
gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface);
|
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)
|
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -963,9 +954,12 @@ BOOL mac_post_connect(freerdp* instance)
|
|||||||
view->pasteboard_wr = [NSPasteboard generalPasteboard];
|
view->pasteboard_wr = [NSPasteboard generalPasteboard];
|
||||||
|
|
||||||
/* setup pasteboard for read operations */
|
/* setup pasteboard for read operations */
|
||||||
view->pasteboard_rd = [NSPasteboard generalPasteboard];
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
view->pasteboard_changecount = (int) [view->pasteboard_rd changeCount];
|
view->pasteboard_rd = [NSPasteboard generalPasteboard];
|
||||||
view->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:mfc->view selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES];
|
view->pasteboard_changecount = -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
[view resume];
|
||||||
|
|
||||||
mfc->appleKeyboardType = mac_detect_keyboard_type();
|
mfc->appleKeyboardType = mac_detect_keyboard_type();
|
||||||
|
|
||||||
@ -1272,212 +1266,6 @@ static void input_activity_cb(freerdp* instance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
* 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)
|
* convert it to a rect with 0,0 at the bottom left (apple cords)
|
||||||
|
@ -99,10 +99,8 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
|
|
||||||
settings->AsyncTransport = TRUE;
|
settings->AsyncTransport = TRUE;
|
||||||
|
|
||||||
settings->AsyncUpdate = TRUE;
|
settings->AsyncUpdate = TRUE;
|
||||||
settings->AsyncInput = TRUE;
|
settings->AsyncInput = TRUE;
|
||||||
settings->AsyncChannels = TRUE;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,13 @@ typedef struct mf_context mfContext;
|
|||||||
#include <freerdp/client/channels.h>
|
#include <freerdp/client/channels.h>
|
||||||
#include <freerdp/client/rdpei.h>
|
#include <freerdp/client/rdpei.h>
|
||||||
#include <freerdp/client/rdpgfx.h>
|
#include <freerdp/client/rdpgfx.h>
|
||||||
|
#include <freerdp/client/cliprdr.h>
|
||||||
#include <freerdp/client/encomsp.h>
|
#include <freerdp/client/encomsp.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/synch.h>
|
#include <winpr/synch.h>
|
||||||
#include <winpr/thread.h>
|
#include <winpr/thread.h>
|
||||||
|
#include <winpr/clipboard.h>
|
||||||
|
|
||||||
#include "MRDPView.h"
|
#include "MRDPView.h"
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
@ -63,6 +65,15 @@ struct mf_context
|
|||||||
DWORD keyboardThreadId;
|
DWORD keyboardThreadId;
|
||||||
BOOL disconnect;
|
BOOL disconnect;
|
||||||
BOOL sw_gdi;
|
BOOL sw_gdi;
|
||||||
|
|
||||||
|
BOOL clipboardSync;
|
||||||
|
wClipboard* clipboard;
|
||||||
|
UINT32 numServerFormats;
|
||||||
|
UINT32 requestedFormatId;
|
||||||
|
HANDLE clipboardRequestEvent;
|
||||||
|
CLIPRDR_FORMAT* serverFormats;
|
||||||
|
CliprdrClientContext* cliprdr;
|
||||||
|
UINT32 clipboardCapabilities;
|
||||||
|
|
||||||
rdpFile* connectionRdpFile;
|
rdpFile* connectionRdpFile;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user