OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
6 #error "This file requires ARC support." | |
7 #endif | |
8 | |
9 #import "remoting/ios/key_input.h" | |
10 #import "remoting/ios/key_map_us.h" | |
11 | |
12 @interface KeyInput (Private) | |
13 - (void)transmitAppropriateKeyCode:(NSString*)text; | |
14 - (void)transmitKeyCode:(NSInteger)keyCode needShift:(bool)needShift; | |
15 @end | |
16 | |
17 @implementation KeyInput | |
18 | |
19 @synthesize delegate = _delegate; | |
20 @synthesize keyboardVisible = _keyboardVisible; | |
21 @synthesize keyboardHeight = _keyboardHeight; | |
22 | |
23 // Override UIView | |
24 - (instancetype)initWithFrame:(CGRect)frame { | |
25 self = [super initWithFrame:frame]; | |
26 if (self) { | |
27 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | |
28 [center addObserver:self | |
29 selector:@selector(keyboardDidShow:) | |
30 name:UIKeyboardDidShowNotification | |
31 object:nil]; | |
32 [center addObserver:self | |
33 selector:@selector(keyboardWillHide:) | |
34 name:UIKeyboardWillHideNotification | |
35 object:nil]; | |
36 } | |
37 return self; | |
38 } | |
39 | |
40 // Override NSObject | |
41 - (void)dealloc { | |
42 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
43 } | |
44 | |
45 // Callback from NotificationCenter | |
46 - (void)keyboardDidShow:(NSNotification*)notification { | |
47 NSDictionary* userInfo = [notification userInfo]; | |
48 CGSize keyboardSize = | |
49 [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; | |
50 _keyboardHeight = keyboardSize.height; | |
51 _keyboardVisible = YES; | |
52 [_delegate keyboardShown]; | |
53 } | |
54 | |
55 // Callback from NotificationCenter | |
56 - (void)keyboardWillHide:(NSNotification*)notification { | |
57 _keyboardHeight = 0.0; | |
58 _keyboardVisible = NO; | |
59 [_delegate keyboardDismissed]; | |
60 } | |
61 | |
62 // Override UIKeyInput::UITextInputTraits property. | |
63 - (UIKeyboardType)keyboardType { | |
64 return UIKeyboardTypeAlphabet; | |
65 } | |
66 | |
67 // Override UIKeyInput::UITextInputTraits property. | |
68 // Remove text completion. | |
69 - (UITextAutocorrectionType)autocorrectionType { | |
70 return UITextAutocorrectionTypeNo; | |
71 } | |
72 | |
73 // Override UIView::UIResponder, when this interface is the first responder | |
74 // on-screen keyboard input will create events for Chromoting keyboard input. | |
75 - (BOOL)canBecomeFirstResponder { | |
76 return YES; | |
77 } | |
78 | |
79 // @protocol UIKeyInput, Send backspace. | |
80 - (void)deleteBackward { | |
81 [self transmitKeyCode:kKeyCodeMetaUS[kBackspaceIndex].code needShift:false]; | |
82 } | |
83 | |
84 // @protocol UIKeyInput, Assume this is a text input. | |
85 - (BOOL)hasText { | |
86 return YES; | |
87 } | |
88 | |
89 // @protocol UIKeyInput, Translate inserted text to key presses, one char at a | |
90 // time. | |
91 - (void)insertText:(NSString*)text { | |
92 [self transmitAppropriateKeyCode:text]; | |
93 } | |
94 | |
95 - (void)ctrlAltDel { | |
96 if (_delegate) { | |
97 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kCtrlIndex].code | |
98 isKeyDown:YES]; | |
99 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kAltIndex].code | |
100 isKeyDown:YES]; | |
101 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kDelIndex].code | |
102 isKeyDown:YES]; | |
103 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kDelIndex].code | |
104 isKeyDown:NO]; | |
105 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kAltIndex].code | |
106 isKeyDown:NO]; | |
107 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kCtrlIndex].code | |
108 isKeyDown:NO]; | |
109 } | |
110 } | |
111 | |
112 // When inserting multiple characters, process them one at a time. |text| is as | |
113 // it was output on the device. The shift key is not naturally presented in the | |
114 // input stream, and must be inserted by inspecting each char and considering | |
115 // that if the key was input on a traditional keyboard that the character would | |
116 // have required a shift. Assume caps lock does not exist. | |
117 - (void)transmitAppropriateKeyCode:(NSString*)text { | |
118 for (size_t i = 0; i < [text length]; ++i) { | |
119 NSInteger charToSend = [text characterAtIndex:i]; | |
120 | |
121 if (charToSend <= kKeyboardKeyMaxUS) { | |
122 [self transmitKeyCode:kKeyCodeMetaUS[charToSend].code | |
123 needShift:kKeyCodeMetaUS[charToSend].needsShift]; | |
124 } | |
125 } | |
126 } | |
127 | |
128 // |charToSend| is as it was output on the device. Some call this a | |
129 // 'key press'. For Chromoting this must be transferred as a key down (press | |
130 // down with a finger), followed by a key up (finger is removed from the | |
131 // keyboard). | |
132 // | |
133 // The delivery may be an upper case or special character. Chromoting is just | |
134 // interested in the button that was pushed, so to create an upper case | |
135 // character, first send a shift press, then the button, then release shift. | |
136 - (void)transmitKeyCode:(NSInteger)keyCode needShift:(bool)needShift { | |
137 if (keyCode > 0 && _delegate) { | |
138 if (needShift) { | |
139 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kShiftIndex].code | |
140 isKeyDown:YES]; | |
141 } | |
142 [_delegate keyboardActionKeyCode:keyCode isKeyDown:YES]; | |
143 [_delegate keyboardActionKeyCode:keyCode isKeyDown:NO]; | |
144 if (needShift) { | |
145 [_delegate keyboardActionKeyCode:kKeyCodeMetaUS[kShiftIndex].code | |
146 isKeyDown:NO]; | |
147 } | |
148 } | |
149 } | |
150 @end | |
OLD | NEW |