FreeRDP
Loading...
Searching...
No Matches
mf_input.c
1
20#include <freerdp/config.h>
21
22#include <ApplicationServices/ApplicationServices.h>
23#include <Carbon/Carbon.h>
24
25#include <winpr/windows.h>
26
27#include "mf_input.h"
28#include "mf_info.h"
29
30#include <freerdp/log.h>
31#define TAG SERVER_TAG("mac")
32
33static const CGKeyCode keymap[256] = {
34 0xFF, // 0x0
35 kVK_Escape, // 0x1
36 kVK_ANSI_1, // 0x2
37 kVK_ANSI_2, // 0x3
38 kVK_ANSI_3, // 0x4
39 kVK_ANSI_4, // 0x5
40 kVK_ANSI_5, // 0x6
41 kVK_ANSI_6, // 0x7
42 kVK_ANSI_7, // 0x8
43 kVK_ANSI_8, // 0x9
44 kVK_ANSI_9, // 0xa
45 kVK_ANSI_0, // 0xb
46 kVK_ANSI_Minus, // 0xc
47 kVK_ANSI_Equal, // 0xd
48 kVK_Delete, // 0xe
49 kVK_Tab, // 0xf
50 kVK_ANSI_Q, // 0x10
51 kVK_ANSI_W, // 0x11
52 kVK_ANSI_E, // 0x12
53 kVK_ANSI_R, // 0x13
54 kVK_ANSI_T, // 0x14
55 kVK_ANSI_Y, // 0x15
56 kVK_ANSI_U, // 0x16
57 kVK_ANSI_I, // 0x17
58 kVK_ANSI_O, // 0x18
59 kVK_ANSI_P, // 0x19
60 kVK_ANSI_LeftBracket, // 0x1a
61 kVK_ANSI_RightBracket, // 0x1b
62 kVK_Return, // 0x1c
63 kVK_Control, // 0x1d
64 kVK_ANSI_A, // 0x1e
65 kVK_ANSI_S, // 0x1f
66 kVK_ANSI_D, // 0x20
67 kVK_ANSI_F, // 0x21
68 kVK_ANSI_G, // 0x22
69 kVK_ANSI_H, // 0x23
70 kVK_ANSI_J, // 0x24
71 kVK_ANSI_K, // 0x25
72 kVK_ANSI_L, // 0x26
73 kVK_ANSI_Semicolon, // 0x27
74 kVK_ANSI_Quote, // 0x28
75 kVK_ANSI_Grave, // 0x29
76 kVK_Shift, // 0x2a
77 kVK_ANSI_Backslash, // 0x2b
78 kVK_ANSI_Z, // 0x2c
79 kVK_ANSI_X, // 0x2d
80 kVK_ANSI_C, // 0x2e
81 kVK_ANSI_V, // 0x2f
82 kVK_ANSI_B, // 0x30
83 kVK_ANSI_N, // 0x31
84 kVK_ANSI_M, // 0x32
85 kVK_ANSI_Comma, // 0x33
86 kVK_ANSI_Period, // 0x34
87 kVK_ANSI_Slash, // 0x35
88 kVK_Shift, // 0x36
89 kVK_ANSI_KeypadMultiply, // 0x37
90 kVK_Option, // 0x38
91 kVK_Space, // 0x39
92 kVK_CapsLock, // 0x3a
93 kVK_F1, // 0x3b
94 kVK_F2, // 0x3c
95 kVK_F3, // 0x3d
96 kVK_F4, // 0x3e
97 kVK_F5, // 0x3f
98 kVK_F6, // 0x40
99 kVK_F7, // 0x41
100 kVK_F8, // 0x42
101 kVK_F9, // 0x43
102 kVK_F10, // 0x44
103 0xFF, // 0x45 -- numlock
104 0xFF, // 0x46 -- scroll lock
105 kVK_ANSI_Keypad7, // 0x47
106 kVK_ANSI_Keypad8, // 0x48
107 kVK_ANSI_Keypad9, // 0x49
108 kVK_ANSI_KeypadMinus, // 0x4a
109 kVK_ANSI_Keypad4, // 0x4b
110 kVK_ANSI_Keypad5, // 0x4c
111 kVK_ANSI_Keypad6, // 0x4d
112 kVK_ANSI_KeypadPlus, // 0x4e
113 kVK_ANSI_Keypad1, // 0x4f
114 kVK_ANSI_Keypad2, // 0x50
115 kVK_ANSI_Keypad3, // 0x51
116 kVK_ANSI_Keypad0, // 0x52
117 kVK_ANSI_KeypadDecimal, // 0x53
118 0xFF, // 0x54
119 0xFF, // 0x55
120 0xFF, // 0x56
121 kVK_F11, // 0x57
122 kVK_F12, // 0x58
123 0xFF, // 0x59 -- pause
124 0xFF, // 0x5a
125 kVK_Control, // 0x5b
126 kVK_Control, // 0x5c
127 0xFF, // 0x5d -- application
128 0xFF, // 0x5e -- power
129 0xFF, // 0x5f -- sleep
130 0xFF, // 0x60
131 0xFF, // 0x61
132 0xFF, // 0x62
133 0xFF, // 0x63 -- wake
134 0xFF, // 0x64
135 0xFF, // 0x65
136 0xFF, // 0x66
137 0xFF, // 0x67
138 0xFF, // 0x68
139 0xFF, // 0x69
140 0xFF, // 0x6a
141 0xFF, // 0x6b
142 0xFF, // 0x6c
143 0xFF, // 0x6d
144 0xFF, // 0x6e
145 0xFF, // 0x6f
146 0xFF, // 0x70
147 0xFF, // 0x71
148 0xFF, // 0x72
149 0xFF, // 0x73
150 0xFF, // 0x74
151 0xFF, // 0x75
152 0xFF, // 0x76
153 0xFF, // 0x77
154 0xFF, // 0x78
155 0xFF, // 0x79
156 0xFF, // 0x7a
157 0xFF, // 0x7b
158 0xFF, // 0x7c
159 0xFF, // 0x7d
160 0xFF, // 0x7e
161 0xFF, // 0x7f
162 0xFF, // 0x80
163 0xFF, // 0x81
164 0xFF, // 0x82
165 0xFF, // 0x83
166 0xFF, // 0x84
167 0xFF, // 0x85
168 0xFF, // 0x86
169 0xFF, // 0x87
170 0xFF, // 0x88
171 0xFF, // 0x89
172 0xFF, // 0x8a
173 0xFF, // 0x8b
174 0xFF, // 0x8c
175 0xFF, // 0x8d
176 0xFF, // 0x8e
177 0xFF, // 0x8f
178 0xFF, // 0x90
179 0xFF, // 0x91
180 0xFF, // 0x92
181 0xFF, // 0x93
182 0xFF, // 0x94
183 0xFF, // 0x95
184 0xFF, // 0x96
185 0xFF, // 0x97
186 0xFF, // 0x98
187 0xFF, // 0x99
188 0xFF, // 0x9a
189 0xFF, // 0x9b
190 0xFF, // 0x9c
191 0xFF, // 0x9d
192 0xFF, // 0x9e
193 0xFF, // 0x9f
194 0xFF, // 0xa0
195 0xFF, // 0xa1
196 0xFF, // 0xa2
197 0xFF, // 0xa3
198 0xFF, // 0xa4
199 0xFF, // 0xa5
200 0xFF, // 0xa6
201 0xFF, // 0xa7
202 0xFF, // 0xa8
203 0xFF, // 0xa9
204 0xFF, // 0xaa
205 0xFF, // 0xab
206 0xFF, // 0xac
207 0xFF, // 0xad
208 0xFF, // 0xae
209 0xFF, // 0xaf
210 0xFF, // 0xb0
211 0xFF, // 0xb1
212 0xFF, // 0xb2
213 0xFF, // 0xb3
214 0xFF, // 0xb4
215 0xFF, // 0xb5
216 0xFF, // 0xb6
217 0xFF, // 0xb7
218 0xFF, // 0xb8
219 0xFF, // 0xb9
220 0xFF, // 0xba
221 0xFF, // 0xbb
222 0xFF, // 0xbc
223 0xFF, // 0xbd
224 0xFF, // 0xbe
225 0xFF, // 0xbf
226 0xFF, // 0xc0
227 0xFF, // 0xc1
228 0xFF, // 0xc2
229 0xFF, // 0xc3
230 0xFF, // 0xc4
231 0xFF, // 0xc5
232 0xFF, // 0xc6
233 0xFF, // 0xc7
234 0xFF, // 0xc8
235 0xFF, // 0xc9
236 0xFF, // 0xca
237 0xFF, // 0xcb
238 0xFF, // 0xcc
239 0xFF, // 0xcd
240 0xFF, // 0xce
241 0xFF, // 0xcf
242 0xFF, // 0xd0
243 0xFF, // 0xd1
244 0xFF, // 0xd2
245 0xFF, // 0xd3
246 0xFF, // 0xd4
247 0xFF, // 0xd5
248 0xFF, // 0xd6
249 0xFF, // 0xd7
250 0xFF, // 0xd8
251 0xFF, // 0xd9
252 0xFF, // 0xda
253 0xFF, // 0xdb
254 0xFF, // 0xdc
255 0xFF, // 0xdd
256 0xFF, // 0xde
257 0xFF, // 0xdf
258 0xFF, // 0xe0
259 0xFF, // 0xe1
260 0xFF, // 0xe2
261 0xFF, // 0xe3
262 0xFF, // 0xe4
263 0xFF, // 0xe5
264 0xFF, // 0xe6
265 0xFF, // 0xe7
266 0xFF, // 0xe8
267 0xFF, // 0xe9
268 0xFF, // 0xea
269 0xFF, // 0xeb
270 0xFF, // 0xec
271 0xFF, // 0xed
272 0xFF, // 0xee
273 0xFF, // 0xef
274 0xFF, // 0xf0
275 0xFF, // 0xf1
276 0xFF, // 0xf2
277 0xFF, // 0xf3
278 0xFF, // 0xf4
279 0xFF, // 0xf5
280 0xFF, // 0xf6
281 0xFF, // 0xf7
282 0xFF, // 0xf8
283 0xFF, // 0xf9
284 0xFF, // 0xfa
285 0xFF, // 0xfb
286 0xFF, // 0xfc
287 0xFF, // 0xfd
288 0xFF, // 0xfe
289};
290
291BOOL mf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
292{
293 CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
294 BOOL keyDown = TRUE;
295 CGEventRef kbEvent;
296 CGKeyCode kCode = 0xFF;
297
298 if (flags & KBD_FLAGS_RELEASE)
299 {
300 keyDown = FALSE;
301 }
302
303 if (flags & KBD_FLAGS_EXTENDED)
304 {
305 switch (code)
306 {
307 // case 0x52: //insert
308 case 0x53:
309 kCode = kVK_ForwardDelete;
310 break;
311
312 case 0x4B:
313 kCode = kVK_LeftArrow;
314 break;
315
316 case 0x47:
317 kCode = kVK_Home;
318 break;
319
320 case 0x4F:
321 kCode = kVK_End;
322 break;
323
324 case 0x48:
325 kCode = kVK_UpArrow;
326 break;
327
328 case 0x50:
329 kCode = kVK_DownArrow;
330 break;
331
332 case 0x49:
333 kCode = kVK_PageUp;
334 break;
335
336 case 0x51:
337 kCode = kVK_PageDown;
338 break;
339
340 case 0x4D:
341 kCode = kVK_RightArrow;
342 break;
343
344 default:
345 break;
346 }
347 }
348 else
349 {
350 kCode = keymap[code];
351 }
352
353 kbEvent = CGEventCreateKeyboardEvent(source, kCode, keyDown);
354 CGEventPost(kCGHIDEventTap, kbEvent);
355 CFRelease(kbEvent);
356 CFRelease(source);
357 return TRUE;
358}
359
360BOOL mf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
361{
362 return FALSE;
363}
364
365BOOL mf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
366{
367 float width, height;
368 CGWheelCount wheelCount = 2;
369 INT32 scroll_x = 0;
370 INT32 scroll_y = 0;
371
372 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
373 {
374 INT32 scroll = flags & WheelRotationMask;
375
376 if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
377 scroll = -(flags & WheelRotationMask) / 392;
378 else
379 scroll = (flags & WheelRotationMask) / 120;
380
381 if (flags & PTR_FLAGS_WHEEL)
382 scroll_y = scroll;
383 else
384 scroll_x = scroll;
385
386 CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
387 CGEventRef scrollEvent = CGEventCreateScrollWheelEvent(source, kCGScrollEventUnitLine,
388 wheelCount, scroll_y, scroll_x);
389 CGEventPost(kCGHIDEventTap, scrollEvent);
390 CFRelease(scrollEvent);
391 CFRelease(source);
392 }
393 else
394 {
395 mfInfo* mfi;
396 CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
397 CGEventType mouseType = kCGEventNull;
398 CGMouseButton mouseButton = kCGMouseButtonLeft;
399 mfi = mf_info_get_instance();
400 // width and height of primary screen (even in multimon setups
401 width = (float)mfi->servscreen_width;
402 height = (float)mfi->servscreen_height;
403 x += mfi->servscreen_xoffset;
404 y += mfi->servscreen_yoffset;
405
406 if (flags & PTR_FLAGS_MOVE)
407 {
408 if (mfi->mouse_down_left == TRUE)
409 {
410 mouseType = kCGEventLeftMouseDragged;
411 }
412 else if (mfi->mouse_down_right == TRUE)
413 {
414 mouseType = kCGEventRightMouseDragged;
415 }
416 else if (mfi->mouse_down_other == TRUE)
417 {
418 mouseType = kCGEventOtherMouseDragged;
419 }
420 else
421 {
422 mouseType = kCGEventMouseMoved;
423 }
424
425 CGEventRef move = CGEventCreateMouseEvent(source, mouseType, CGPointMake(x, y),
426 mouseButton // ignored for just movement
427 );
428 CGEventPost(kCGHIDEventTap, move);
429 CFRelease(move);
430 }
431
432 if (flags & PTR_FLAGS_BUTTON1)
433 {
434 mouseButton = kCGMouseButtonLeft;
435
436 if (flags & PTR_FLAGS_DOWN)
437 {
438 mouseType = kCGEventLeftMouseDown;
439 mfi->mouse_down_left = TRUE;
440 }
441 else
442 {
443 mouseType = kCGEventLeftMouseUp;
444 mfi->mouse_down_right = FALSE;
445 }
446 }
447 else if (flags & PTR_FLAGS_BUTTON2)
448 {
449 mouseButton = kCGMouseButtonRight;
450
451 if (flags & PTR_FLAGS_DOWN)
452 {
453 mouseType = kCGEventRightMouseDown;
454 mfi->mouse_down_right = TRUE;
455 }
456 else
457 {
458 mouseType = kCGEventRightMouseUp;
459 mfi->mouse_down_right = FALSE;
460 }
461 }
462 else if (flags & PTR_FLAGS_BUTTON3)
463 {
464 mouseButton = kCGMouseButtonCenter;
465
466 if (flags & PTR_FLAGS_DOWN)
467 {
468 mouseType = kCGEventOtherMouseDown;
469 mfi->mouse_down_other = TRUE;
470 }
471 else
472 {
473 mouseType = kCGEventOtherMouseUp;
474 mfi->mouse_down_other = FALSE;
475 }
476 }
477
478 CGEventRef mouseEvent =
479 CGEventCreateMouseEvent(source, mouseType, CGPointMake(x, y), mouseButton);
480 CGEventPost(kCGHIDEventTap, mouseEvent);
481 CFRelease(mouseEvent);
482 CFRelease(source);
483 }
484
485 return TRUE;
486}
487
488BOOL mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
489{
490 return FALSE;
491}
492
493BOOL mf_input_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
494{
495 return FALSE;
496}
497
498BOOL mf_input_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
499{
500 return FALSE;
501}
502
503BOOL mf_input_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
504{
505 return FALSE;
506}
507
508BOOL mf_input_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
509{
510 return FALSE;
511}