11#import "RDPKeyboard.h"
12#include <freerdp/locale/keyboard.h>
14@interface RDPKeyboard (Private)
15- (void)sendUnicodeKey:(NSInteger)character up:(BOOL)up;
16- (void)handleSpecialKey:(NSInteger)character;
17- (void)handleAlphaNumChar:(
int)character;
18- (void)notifyDelegateModifiersChanged;
23@synthesize delegate = _delegate, ctrlPressed = _ctrl_pressed, altPressed = _alt_pressed,
24 shiftPressed = _shift_pressed, winPressed = _win_pressed, altGrPressed = _altgr_pressed;
28 if ((
self = [super init]) != nil)
30 [
self initWithSession:nil delegate:nil];
32 memset(_virtual_key_map, 0,
sizeof(_virtual_key_map));
33 memset(_virtual_key_shift_map, 0,
sizeof(_virtual_key_shift_map));
36 _virtual_key_map['0'] = VK_KEY_0;
37 _virtual_key_map['1'] = VK_KEY_1;
38 _virtual_key_map['2'] = VK_KEY_2;
39 _virtual_key_map['3'] = VK_KEY_3;
40 _virtual_key_map['4'] = VK_KEY_4;
41 _virtual_key_map['5'] = VK_KEY_5;
42 _virtual_key_map['6'] = VK_KEY_6;
43 _virtual_key_map['7'] = VK_KEY_7;
44 _virtual_key_map['8'] = VK_KEY_8;
45 _virtual_key_map['9'] = VK_KEY_9;
47 _virtual_key_map['a'] = VK_KEY_A;
48 _virtual_key_map['b'] = VK_KEY_B;
49 _virtual_key_map['c'] = VK_KEY_C;
50 _virtual_key_map['d'] = VK_KEY_D;
51 _virtual_key_map['e'] = VK_KEY_E;
52 _virtual_key_map['f'] = VK_KEY_F;
53 _virtual_key_map['g'] = VK_KEY_G;
54 _virtual_key_map['h'] = VK_KEY_H;
55 _virtual_key_map['i'] = VK_KEY_I;
56 _virtual_key_map['j'] = VK_KEY_J;
57 _virtual_key_map['k'] = VK_KEY_K;
58 _virtual_key_map['l'] = VK_KEY_L;
59 _virtual_key_map['m'] = VK_KEY_M;
60 _virtual_key_map['n'] = VK_KEY_N;
61 _virtual_key_map['o'] = VK_KEY_O;
62 _virtual_key_map['p'] = VK_KEY_P;
63 _virtual_key_map['q'] = VK_KEY_Q;
64 _virtual_key_map['r'] = VK_KEY_R;
65 _virtual_key_map['s'] = VK_KEY_S;
66 _virtual_key_map['t'] = VK_KEY_T;
67 _virtual_key_map['u'] = VK_KEY_U;
68 _virtual_key_map['v'] = VK_KEY_V;
69 _virtual_key_map['w'] = VK_KEY_W;
70 _virtual_key_map['x'] = VK_KEY_X;
71 _virtual_key_map['y'] = VK_KEY_Y;
72 _virtual_key_map['z'] = VK_KEY_Z;
76 _virtual_key_map[' '] = VK_SPACE;
77 _virtual_key_map['`'] = _virtual_key_map['~'] = VK_OEM_3;
78 _virtual_key_map['-'] = _virtual_key_map['_'] = VK_OEM_MINUS;
79 _virtual_key_map['='] = _virtual_key_map['+'] = VK_OEM_PLUS;
80 _virtual_key_map['['] = _virtual_key_map['{'] = VK_OEM_4;
81 _virtual_key_map[']'] = _virtual_key_map['}'] = VK_OEM_6;
82 _virtual_key_map['\\'] = _virtual_key_map['|'] = VK_OEM_5;
83 _virtual_key_map[';'] = _virtual_key_map[':'] = VK_OEM_1;
84 _virtual_key_map['\''] = _virtual_key_map['\"'] = VK_OEM_7;
85 _virtual_key_map[','] = _virtual_key_map['<'] = VK_OEM_COMMA;
86 _virtual_key_map['.'] = _virtual_key_map['>'] = VK_OEM_PERIOD;
87 _virtual_key_map['/'] = _virtual_key_map['?'] = VK_OEM_2;
89 const char *shifted =
"~_+{}|:\"<>?!@#$%^&*()";
90 for (
const char *p = shifted; *p !=
'\0'; p++)
91 _virtual_key_shift_map[(
unsigned char)*p] = YES;
93 _virtual_key_map['!'] = VK_KEY_1;
94 _virtual_key_map['@'] = VK_KEY_2;
95 _virtual_key_map['#'] = VK_KEY_3;
96 _virtual_key_map['] = VK_KEY_4;
97 _virtual_key_map['%'] = VK_KEY_5;
98 _virtual_key_map['^'] = VK_KEY_6;
99 _virtual_key_map['&'] = VK_KEY_7;
100 _virtual_key_map['*'] = VK_KEY_8;
101 _virtual_key_map['('] = VK_KEY_9;
102 _virtual_key_map[')'] = VK_KEY_0;
113#pragma mark class methods
120 if (_shared_keyboard == nil)
124 if (_shared_keyboard == nil)
129 return _shared_keyboard;
133- (void)initWithSession:(
RDPSession *)session delegate:(NSObject<RDPKeyboardDelegate> *)delegate
142 _delegate = delegate;
149 [
self toggleShiftKey];
153 [
self toggleCtrlKey];
157 [
self toggleAltGrKey];
162- (void)sendUnicode:(NSInteger)character
164 if ((character >= 0) && (character < 256) && isalnum((
unsigned char)character))
165 [
self handleAlphaNumChar:(int)character];
167 [
self handleSpecialKey:character];
173- (void)sendVirtualKeyCode:(NSInteger)keyCode
175 [
self sendVirtualKey:keyCode up:NO];
176 [
self sendVirtualKey:keyCode up:YES];
183- (void)sendVirtualKey:(NSInteger)vKey up:(BOOL)up
185 const DWORD dvKey = WINPR_ASSERTING_INT_CAST(DWORD, vKey);
186 DWORD scancode = GetVirtualScanCodeFromVirtualKeyCode(dvKey, 4);
187 int flags = (up ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN);
188 flags |= ((scancode & KBDEXT) ? KBD_FLAGS_EXTENDED : 0);
190 sendInputEvent:[NSDictionary
191 dictionaryWithObjectsAndKeys:@"keyboard", @"type", @"scancode",
193 [NSNumber numberWithUnsignedShort:flags],
196 numberWithUnsignedShort:(scancode &
201#pragma mark modifier key handling
205 [
self sendVirtualKey:VK_LCONTROL up:_ctrl_pressed];
206 _ctrl_pressed = !_ctrl_pressed;
207 [
self notifyDelegateModifiersChanged];
213 [
self sendVirtualKey:VK_LMENU up:_alt_pressed];
214 _alt_pressed = !_alt_pressed;
215 [
self notifyDelegateModifiersChanged];
219- (void)toggleShiftKey
221 [
self sendVirtualKey:VK_LSHIFT up:_shift_pressed];
222 _shift_pressed = !_shift_pressed;
223 [
self notifyDelegateModifiersChanged];
229 [
self sendVirtualKey:(VK_LWIN | KBDEXT) up:_win_pressed];
230 _win_pressed = !_win_pressed;
231 [
self notifyDelegateModifiersChanged];
235- (void)toggleAltGrKey
237 [
self sendVirtualKey:(VK_RMENU | KBDEXT) up:_altgr_pressed];
238 _altgr_pressed = !_altgr_pressed;
239 [
self notifyDelegateModifiersChanged];
242#pragma mark Sending special key strokes
244- (void)sendEnterKeyStroke
246 [
self sendVirtualKeyCode:(VK_RETURN | KBDEXT)];
249- (void)sendEscapeKeyStroke
251 [
self sendVirtualKeyCode:VK_ESCAPE];
254- (void)sendBackspaceKeyStroke
256 [
self sendVirtualKeyCode:VK_BACK];
259- (void)sendDeleteKeyStroke
261 [
self sendVirtualKeyCode:(VK_DELETE | KBDEXT)];
264- (void)sendTabKeyStroke
266 [
self sendVirtualKeyCode:VK_TAB];
272@implementation RDPKeyboard (Private)
274- (void)handleAlphaNumChar:(
int)character
277 BOOL shift_was_sent = NO;
278 if (isupper(character) && _shift_pressed == NO)
280 character = tolower(character);
281 [
self sendVirtualKey:VK_LSHIFT up:NO];
282 shift_was_sent = YES;
286 int vk = _virtual_key_map[character];
290 [
self sendVirtualKey:vk up:NO];
291 [
self sendVirtualKey:vk up:YES];
296 [
self sendVirtualKey:VK_LSHIFT up:YES];
299- (void)handleSpecialKey:(NSInteger)character
301 if ((character >= 0) && (character < 256) && (_virtual_key_map[character] != 0))
303 BOOL shift_was_sent = NO;
304 if (_virtual_key_shift_map[character] && !_shift_pressed)
306 [
self sendVirtualKey:VK_LSHIFT up:NO];
307 shift_was_sent = YES;
310 [
self sendVirtualKey:_virtual_key_map[character] up:NO];
311 [
self sendVirtualKey:_virtual_key_map[character] up:YES];
314 [
self sendVirtualKey:VK_LSHIFT up:YES];
319 [
self sendUnicodeKey:character up:NO];
320 [
self sendUnicodeKey:character up:YES];
323- (void)sendUnicodeKey:(NSInteger)character up:(BOOL)up
325 const UINT16 ucharacter = WINPR_ASSERTING_INT_CAST(UINT16, character);
327 sendInputEvent:[NSDictionary
328 dictionaryWithObjectsAndKeys:
329 @"keyboard", @"type", @"unicode", @"subtype",
330 [NSNumber numberWithUnsignedShort:(up ? KBD_FLAGS_RELEASE : 0)],
331 @"flags", [NSNumber numberWithUnsignedShort:ucharacter],
332 @"unicode_char", nil]];
335- (void)notifyDelegateModifiersChanged
337 if ([[
self delegate] respondsToSelector:@selector(modifiersChangedForKeyboard:)])
338 [[self delegate] modifiersChangedForKeyboard:self];