FreeRDP
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 
33 static 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 
291 BOOL 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 
360 BOOL mf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
361 {
362  return FALSE;
363 }
364 
365 BOOL 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 
488 BOOL mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
489 {
490  return FALSE;
491 }
492 
493 BOOL mf_input_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
494 {
495  return FALSE;
496 }
497 
498 BOOL mf_input_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
499 {
500  return FALSE;
501 }
502 
503 BOOL mf_input_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
504 {
505  return FALSE;
506 }
507 
508 BOOL mf_input_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
509 {
510  return FALSE;
511 }