11#include <winpr/assert.h>
13#include "ios_freerdp_events.h"
14#include "ios_cliprdr.h"
17#pragma mark Sending compacted input events (from main thread)
21BOOL ios_events_send(mfInfo *mfi, NSDictionary *event_description)
24 NSData *encoded_description = [NSKeyedArchiver archivedDataWithRootObject:event_description
25 requiringSecureCoding:YES
28 if (!encoded_description)
30 NSLog(
@"%s: Failed to archive event (type: %@): %@", __func__,
31 [event_description objectForKey:
@"type"], error);
37 if ([encoded_description length] > 32000 || (mfi->event_pipe_producer == -1))
40 uint32_t archived_data_len = (uint32_t)[encoded_description length];
44 if (write(mfi->event_pipe_producer, &archived_data_len, 4) == -1)
46 NSLog(
@"%s: Failed to write length descriptor to pipe.", __func__);
50 if (write(mfi->event_pipe_producer, [encoded_description bytes], archived_data_len) == -1)
52 NSLog(
@"%s: Failed to write %d bytes into the event queue (event type: %@).", __func__,
53 (
int)[encoded_description length], [event_description objectForKey:
@"type"]);
61#pragma mark Processing compacted input events (from connection thread runloop)
63static BOOL ios_events_handle_event(mfInfo *mfi, NSDictionary *event_description)
65 NSString *event_type = [event_description objectForKey:@"type"];
66 BOOL should_continue = TRUE;
71 freerdp *instance = mfi->instance;
72 WINPR_ASSERT(instance);
73 WINPR_ASSERT(instance->context);
75 input = instance->context->input;
78 if ([event_type isEqualToString:
@"mouse"])
80 if (!input->MouseEvent(input,
81 [[event_description objectForKey:
@"flags"] unsignedShortValue],
82 [[event_description objectForKey:
@"coord_x"] unsignedShortValue],
83 [[event_description objectForKey:
@"coord_y"] unsignedShortValue]))
86 NSLog(
@"%s: MouseEvent failed.", __func__);
89 else if ([event_type isEqualToString:
@"keyboard"])
91 if ([[event_description objectForKey:
@"subtype"] isEqualToString:
@"scancode"])
92 freerdp_input_send_keyboard_event(
93 input, [[event_description objectForKey:
@"flags"] unsignedShortValue],
94 [[event_description objectForKey:
@"scancode"] unsignedShortValue]);
95 else if ([[event_description objectForKey:
@"subtype"] isEqualToString:
@"unicode"])
96 freerdp_input_send_unicode_keyboard_event(
97 input, [[event_description objectForKey:
@"flags"] unsignedShortValue],
98 [[event_description objectForKey:
@"unicode_char"] unsignedShortValue]);
100 NSLog(
@"%s: doesn't know how to send keyboard input with subtype %@", __func__,
101 [event_description objectForKey:
@"subtype"]);
103 else if ([event_type isEqualToString:
@"clipboard"])
106 afc->clipboardHasText = [[event_description objectForKey:@"has_text"] boolValue];
109 if (afc->cliprdr && afc->clipboardSync &&
110 (ios_cliprdr_send_client_format_list(afc->cliprdr) != CHANNEL_RC_OK))
111 NSLog(
@"%s: failed to send the clipboard format list.", __func__);
113 else if ([event_type isEqualToString:
@"disconnect"])
114 should_continue = FALSE;
116 NSLog(
@"%s: unrecognized event type: %@", __func__, event_type);
118 return should_continue;
121BOOL ios_events_check_handle(mfInfo *mfi)
125 if (WaitForSingleObject(mfi->handle, 0) != WAIT_OBJECT_0)
128 if (mfi->event_pipe_consumer == -1)
131 uint32_t archived_data_length = 0;
135 bytes_read = read(mfi->event_pipe_consumer, &archived_data_length, 4);
137 if (bytes_read == -1 || archived_data_length < 1 || archived_data_length > 32000)
139 NSLog(
@"%s: just read length descriptor. bytes_read=%ld, archived_data_length=%u", __func__,
140 bytes_read, archived_data_length);
146 NSMutableData *archived_object_data =
147 [[NSMutableData alloc] initWithLength:archived_data_length];
149 read(mfi->event_pipe_consumer, [archived_object_data mutableBytes], archived_data_length);
151 if (bytes_read != archived_data_length)
153 NSLog(
@"%s: attempted to read data; read %ld bytes but wanted %d bytes.", __func__,
154 bytes_read, archived_data_length);
155 [archived_object_data release];
159 NSError *error = nil;
160 NSDictionary *unarchived_object_data = [NSKeyedUnarchiver
161 unarchivedObjectOfClasses:[NSSet setWithObjects:[NSDictionary class], [NSString class],
162 [NSNumber class], nil]
163 fromData:archived_object_data
165 [archived_object_data release];
167 if (!unarchived_object_data)
170 NSLog(
@"%s: Failed to unarchive input event: %@", __func__, error);
174 return ios_events_handle_event(mfi, unarchived_object_data);
177HANDLE ios_events_get_handle(mfInfo *mfi)
184BOOL ios_events_create_pipe(mfInfo *mfi)
190 if (pipe(pipe_fds) == -1)
192 NSLog(
@"%s: pipe failed.", __func__);
196 mfi->event_pipe_consumer = pipe_fds[0];
197 mfi->event_pipe_producer = pipe_fds[1];
198 mfi->handle = CreateFileDescriptorEvent(
nullptr, FALSE, FALSE, mfi->event_pipe_consumer,
199 WINPR_FD_READ | WINPR_FD_WRITE);
203void ios_events_free_pipe(mfInfo *mfi)
206 int consumer_fd = mfi->event_pipe_consumer, producer_fd = mfi->event_pipe_producer;
208 mfi->event_pipe_consumer = mfi->event_pipe_producer = -1;
211 (void)CloseHandle(mfi->handle);