Index: remoting/ios/key_input.mm |
diff --git a/remoting/ios/key_input.mm b/remoting/ios/key_input.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0e51efa7ac61ae166b76312a933a4a33b9c47ffc |
--- /dev/null |
+++ b/remoting/ios/key_input.mm |
@@ -0,0 +1,111 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#if !defined(__has_feature) || !__has_feature(objc_arc) |
+#error "This file requires ARC support." |
+#endif |
+ |
+#import "remoting/ios/key_input.h" |
+#import "remoting/ios/key_map_us.h" |
+ |
+@interface KeyInput (Private) |
+- (void)transmitAppropriateKeyCode:(NSString*)text; |
+- (void)transmitKeyCode:(NSInteger)keyCode needShift:(bool)needShift; |
+@end |
+ |
+@implementation KeyInput |
+ |
+@synthesize delegate = _delegate; |
+ |
+// Override UIKeyInput::UITextInputTraits property |
+- (UIKeyboardType)keyboardType { |
+ return UIKeyboardTypeAlphabet; |
+} |
+ |
+// Override UIView::UIResponder, when this interface is the first responder |
+// on-screen keyboard input will create events for Chromoting keyboard input |
+- (BOOL)canBecomeFirstResponder { |
+ return YES; |
+} |
+ |
+// Override UIView::UIResponder |
+// Keyboard was dismissed |
+- (BOOL)resignFirstResponder { |
+ BOOL wasFirstResponder = self.isFirstResponder; |
+ BOOL didResignFirstReponder = |
+ [super resignFirstResponder]; // I'm not sure that this returns YES when |
+ // first responder was resigned, but for |
+ // now I don't actually need to know what |
+ // the return from super means. |
+ if (wasFirstResponder) { |
+ [_delegate keyboardDismissed]; |
+ } |
+ |
+ return didResignFirstReponder; |
+} |
+ |
+// @protocol UIKeyInput, Send backspace |
+- (void)deleteBackward { |
+ [self transmitKeyCode:kKeyCodeUS[kBackspaceIndex] needShift:false]; |
+} |
+ |
+// @protocol UIKeyInput, Assume this is a text input |
+- (BOOL)hasText { |
+ return YES; |
+} |
+ |
+// @protocol UIKeyInput, Translate inserted text to key presses, one char at a |
+// time |
+- (void)insertText:(NSString*)text { |
+ [self transmitAppropriateKeyCode:text]; |
+} |
+ |
+- (void)ctrlAltDel { |
+ if (_delegate) { |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kCtrlIndex] isKeyDown:YES]; |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kAltIndex] isKeyDown:YES]; |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kDelIndex] isKeyDown:YES]; |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kDelIndex] isKeyDown:NO]; |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kAltIndex] isKeyDown:NO]; |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kCtrlIndex] isKeyDown:NO]; |
+ } |
+} |
+ |
+// When inserting multiple characters, process them one at a time. |text| is as |
+// it was output on the device. The shift key is not naturally presented in the |
+// input stream, and must be inserted by inspecting each char and considering |
+// that if the key was input on a traditional keyboard that the character would |
+// have required a shift. Assume caps lock does not exist. |
+- (void)transmitAppropriateKeyCode:(NSString*)text { |
+ for (int i = 0; i < [text length]; ++i) { |
+ NSInteger charToSend = [text characterAtIndex:i]; |
+ |
+ if (charToSend <= kKeyboardKeyMaxUS) { |
+ [self transmitKeyCode:kKeyCodeUS[charToSend] |
+ needShift:kIsShiftRequiredUS[charToSend]]; |
+ } |
+ } |
+} |
+ |
+// |charToSend| is as it was output on the device. Some call this a |
+// 'key press'. For Chromoting this must be transferred as a key down (press |
+// down with a finger), followed by a key up (finger is removed from the |
+// keyboard) |
+// |
+// The delivery may be an upper case or special character. Chromoting is just |
+// interested in the button that was pushed, so to create an upper case |
+// character, first send a shift press, then the button, then release shift |
+- (void)transmitKeyCode:(NSInteger)keyCode needShift:(bool)needShift { |
+ if (keyCode > 0 && _delegate) { |
+ if (needShift) { |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kShiftIndex] isKeyDown:YES]; |
+ } |
+ [_delegate keyboardActionKeyCode:keyCode isKeyDown:YES]; |
+ [_delegate keyboardActionKeyCode:keyCode isKeyDown:NO]; |
+ if (needShift) { |
+ [_delegate keyboardActionKeyCode:kKeyCodeUS[kShiftIndex] isKeyDown:NO]; |
+ } |
+ } |
+} |
+@end |