11#import "RDPKeyboard.h"
12#include <freerdp/locale/keyboard.h>
14@interface RDPKeyboard (Private)
15- (void)sendUnicodeKey:(
int)character up:(BOOL)up;
16- (void)handleSpecialKey:(
int)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;
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
141 _delegate = delegate;
148 [
self toggleShiftKey];
152 [
self toggleCtrlKey];
159- (void)sendUnicode:(
int)character
161 if ((character >= 0) && (character < 256) && isalnum((
unsigned char)character))
162 [
self handleAlphaNumChar:character];
164 [
self handleSpecialKey:character];
170- (void)sendVirtualKeyCode:(
int)keyCode
172 [
self sendVirtualKey:keyCode up:NO];
173 [
self sendVirtualKey:keyCode up:YES];
177- (void)sendVirtualKey:(
int)vKey up:(BOOL)up
179 DWORD scancode = GetVirtualScanCodeFromVirtualKeyCode(vKey, 4);
180 int flags = (up ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN);
181 flags |= ((scancode & KBDEXT) ? KBD_FLAGS_EXTENDED : 0);
183 sendInputEvent:[NSDictionary
184 dictionaryWithObjectsAndKeys:@"keyboard", @"type", @"scancode",
186 [NSNumber numberWithUnsignedShort:flags],
189 numberWithUnsignedShort:(scancode &
194#pragma mark modifier key handling
198 [
self sendVirtualKey:VK_LCONTROL up:_ctrl_pressed];
199 _ctrl_pressed = !_ctrl_pressed;
200 [
self notifyDelegateModifiersChanged];
206 [
self sendVirtualKey:VK_LMENU up:_alt_pressed];
207 _alt_pressed = !_alt_pressed;
208 [
self notifyDelegateModifiersChanged];
212- (void)toggleShiftKey
214 [
self sendVirtualKey:VK_LSHIFT up:_shift_pressed];
215 _shift_pressed = !_shift_pressed;
216 [
self notifyDelegateModifiersChanged];
222 [
self sendVirtualKey:(VK_LWIN | KBDEXT) up:_win_pressed];
223 _win_pressed = !_win_pressed;
224 [
self notifyDelegateModifiersChanged];
227#pragma mark Sending special key strokes
229- (void)sendEnterKeyStroke
231 [
self sendVirtualKeyCode:(VK_RETURN | KBDEXT)];
234- (void)sendEscapeKeyStroke
236 [
self sendVirtualKeyCode:VK_ESCAPE];
239- (void)sendBackspaceKeyStroke
241 [
self sendVirtualKeyCode:VK_BACK];
247@implementation RDPKeyboard (Private)
249- (void)handleAlphaNumChar:(
int)character
252 BOOL shift_was_sent = NO;
253 if (isupper(character) && _shift_pressed == NO)
255 character = tolower(character);
256 [
self sendVirtualKey:VK_LSHIFT up:NO];
257 shift_was_sent = YES;
261 int vk = _virtual_key_map[character];
265 [
self sendVirtualKey:vk up:NO];
266 [
self sendVirtualKey:vk up:YES];
271 [
self sendVirtualKey:VK_LSHIFT up:YES];
274- (void)handleSpecialKey:(
int)character
276 if ((character >= 0) && (character < 256) && (_virtual_key_map[character] != 0))
278 BOOL shift_was_sent = NO;
279 if (_virtual_key_shift_map[character] && !_shift_pressed)
281 [
self sendVirtualKey:VK_LSHIFT up:NO];
282 shift_was_sent = YES;
285 [
self sendVirtualKey:_virtual_key_map[character] up:NO];
286 [
self sendVirtualKey:_virtual_key_map[character] up:YES];
289 [
self sendVirtualKey:VK_LSHIFT up:YES];
294 [
self sendUnicodeKey:character up:NO];
295 [
self sendUnicodeKey:character up:YES];
298- (void)sendUnicodeKey:(
int)character up:(BOOL)up
301 sendInputEvent:[NSDictionary
302 dictionaryWithObjectsAndKeys:
303 @"keyboard", @"type", @"unicode", @"subtype",
304 [NSNumber numberWithUnsignedShort:(up ? KBD_FLAGS_RELEASE : 0)],
305 @"flags", [NSNumber numberWithUnsignedShort:character],
306 @"unicode_char", nil]];
309- (void)notifyDelegateModifiersChanged
311 if ([[
self delegate] respondsToSelector:@selector(modifiersChangedForKeyboard:)])
312 [[self delegate] modifiersChangedForKeyboard:self];