11#include <winpr/assert.h>
13#include "ios_freerdp_events.h"
16#pragma mark Sending compacted input events (from main thread)
20BOOL ios_events_send(mfInfo *mfi, NSDictionary *event_description)
23 NSData *encoded_description = [NSKeyedArchiver archivedDataWithRootObject:event_description
24 requiringSecureCoding:YES
27 if (!encoded_description)
29 NSLog(
@"%s: Failed to archive event (type: %@): %@", __func__,
30 [event_description objectForKey:
@"type"], error);
36 if ([encoded_description length] > 32000 || (mfi->event_pipe_producer == -1))
39 uint32_t archived_data_len = (uint32_t)[encoded_description length];
43 if (write(mfi->event_pipe_producer, &archived_data_len, 4) == -1)
45 NSLog(
@"%s: Failed to write length descriptor to pipe.", __func__);
49 if (write(mfi->event_pipe_producer, [encoded_description bytes], archived_data_len) == -1)
51 NSLog(
@"%s: Failed to write %d bytes into the event queue (event type: %@).", __func__,
52 (
int)[encoded_description length], [event_description objectForKey:
@"type"]);
60#pragma mark Processing compacted input events (from connection thread runloop)
62static BOOL ios_events_handle_event(mfInfo *mfi, NSDictionary *event_description)
64 NSString *event_type = [event_description objectForKey:@"type"];
65 BOOL should_continue = TRUE;
70 freerdp *instance = mfi->instance;
71 WINPR_ASSERT(instance);
72 WINPR_ASSERT(instance->context);
74 input = instance->context->input;
77 if ([event_type isEqualToString:
@"mouse"])
79 if (!input->MouseEvent(input,
80 [[event_description objectForKey:
@"flags"] unsignedShortValue],
81 [[event_description objectForKey:
@"coord_x"] unsignedShortValue],
82 [[event_description objectForKey:
@"coord_y"] unsignedShortValue]))
85 NSLog(
@"%s: MouseEvent failed.", __func__);
88 else if ([event_type isEqualToString:
@"keyboard"])
90 if ([[event_description objectForKey:
@"subtype"] isEqualToString:
@"scancode"])
91 freerdp_input_send_keyboard_event(
92 input, [[event_description objectForKey:
@"flags"] unsignedShortValue],
93 [[event_description objectForKey:
@"scancode"] unsignedShortValue]);
94 else if ([[event_description objectForKey:
@"subtype"] isEqualToString:
@"unicode"])
95 freerdp_input_send_unicode_keyboard_event(
96 input, [[event_description objectForKey:
@"flags"] unsignedShortValue],
97 [[event_description objectForKey:
@"unicode_char"] unsignedShortValue]);
99 NSLog(
@"%s: doesn't know how to send keyboard input with subtype %@", __func__,
100 [event_description objectForKey:
@"subtype"]);
102 else if ([event_type isEqualToString:
@"disconnect"])
103 should_continue = FALSE;
105 NSLog(
@"%s: unrecognized event type: %@", __func__, event_type);
107 return should_continue;
110BOOL ios_events_check_handle(mfInfo *mfi)
114 if (WaitForSingleObject(mfi->handle, 0) != WAIT_OBJECT_0)
117 if (mfi->event_pipe_consumer == -1)
120 uint32_t archived_data_length = 0;
124 bytes_read = read(mfi->event_pipe_consumer, &archived_data_length, 4);
126 if (bytes_read == -1 || archived_data_length < 1 || archived_data_length > 32000)
128 NSLog(
@"%s: just read length descriptor. bytes_read=%ld, archived_data_length=%u", __func__,
129 bytes_read, archived_data_length);
135 NSMutableData *archived_object_data =
136 [[NSMutableData alloc] initWithLength:archived_data_length];
138 read(mfi->event_pipe_consumer, [archived_object_data mutableBytes], archived_data_length);
140 if (bytes_read != archived_data_length)
142 NSLog(
@"%s: attempted to read data; read %ld bytes but wanted %d bytes.", __func__,
143 bytes_read, archived_data_length);
144 [archived_object_data release];
148 NSError *error = nil;
149 NSDictionary *unarchived_object_data = [NSKeyedUnarchiver
150 unarchivedObjectOfClasses:[NSSet setWithObjects:[NSDictionary class], [NSString class],
151 [NSNumber class], nil]
152 fromData:archived_object_data
154 [archived_object_data release];
156 if (!unarchived_object_data)
159 NSLog(
@"%s: Failed to unarchive input event: %@", __func__, error);
163 return ios_events_handle_event(mfi, unarchived_object_data);
166HANDLE ios_events_get_handle(mfInfo *mfi)
173BOOL ios_events_create_pipe(mfInfo *mfi)
179 if (pipe(pipe_fds) == -1)
181 NSLog(
@"%s: pipe failed.", __func__);
185 mfi->event_pipe_consumer = pipe_fds[0];
186 mfi->event_pipe_producer = pipe_fds[1];
187 mfi->handle = CreateFileDescriptorEvent(
nullptr, FALSE, FALSE, mfi->event_pipe_consumer,
188 WINPR_FD_READ | WINPR_FD_WRITE);
192void ios_events_free_pipe(mfInfo *mfi)
195 int consumer_fd = mfi->event_pipe_consumer, producer_fd = mfi->event_pipe_producer;
197 mfi->event_pipe_consumer = mfi->event_pipe_producer = -1;
200 (void)CloseHandle(mfi->handle);