• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 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
21// Override UIKeyInput::UITextInputTraits property
22- (UIKeyboardType)keyboardType {
23  return UIKeyboardTypeAlphabet;
24}
25
26// Override UIView::UIResponder, when this interface is the first responder
27// on-screen keyboard input will create events for Chromoting keyboard input
28- (BOOL)canBecomeFirstResponder {
29  return YES;
30}
31
32// Override UIView::UIResponder
33// Keyboard was dismissed
34- (BOOL)resignFirstResponder {
35  BOOL wasFirstResponder = self.isFirstResponder;
36  BOOL didResignFirstReponder =
37      [super resignFirstResponder];  // I'm not sure that this returns YES when
38                                     // first responder was resigned, but for
39                                     // now I don't actually need to know what
40                                     // the return from super means.
41  if (wasFirstResponder) {
42    [_delegate keyboardDismissed];
43  }
44
45  return didResignFirstReponder;
46}
47
48// @protocol UIKeyInput, Send backspace
49- (void)deleteBackward {
50  [self transmitKeyCode:kKeyCodeUS[kBackspaceIndex] needShift:false];
51}
52
53// @protocol UIKeyInput, Assume this is a text input
54- (BOOL)hasText {
55  return YES;
56}
57
58// @protocol UIKeyInput, Translate inserted text to key presses, one char at a
59// time
60- (void)insertText:(NSString*)text {
61  [self transmitAppropriateKeyCode:text];
62}
63
64- (void)ctrlAltDel {
65  if (_delegate) {
66    [_delegate keyboardActionKeyCode:kKeyCodeUS[kCtrlIndex] isKeyDown:YES];
67    [_delegate keyboardActionKeyCode:kKeyCodeUS[kAltIndex] isKeyDown:YES];
68    [_delegate keyboardActionKeyCode:kKeyCodeUS[kDelIndex] isKeyDown:YES];
69    [_delegate keyboardActionKeyCode:kKeyCodeUS[kDelIndex] isKeyDown:NO];
70    [_delegate keyboardActionKeyCode:kKeyCodeUS[kAltIndex] isKeyDown:NO];
71    [_delegate keyboardActionKeyCode:kKeyCodeUS[kCtrlIndex] isKeyDown:NO];
72  }
73}
74
75// When inserting multiple characters, process them one at a time.  |text| is as
76// it was output on the device.  The shift key is not naturally presented in the
77// input stream, and must be inserted by inspecting each char and considering
78// that if the key was input on a traditional keyboard that the character would
79// have required a shift.  Assume caps lock does not exist.
80- (void)transmitAppropriateKeyCode:(NSString*)text {
81  for (int i = 0; i < [text length]; ++i) {
82    NSInteger charToSend = [text characterAtIndex:i];
83
84    if (charToSend <= kKeyboardKeyMaxUS) {
85      [self transmitKeyCode:kKeyCodeUS[charToSend]
86                  needShift:kIsShiftRequiredUS[charToSend]];
87    }
88  }
89}
90
91// |charToSend| is as it was output on the device.  Some call this a
92// 'key press'.  For Chromoting this must be transferred as a key down (press
93// down with a finger), followed by a key up (finger is removed from the
94// keyboard)
95//
96// The delivery may be an upper case or special character.  Chromoting is just
97// interested in the button that was pushed, so to create an upper case
98// character, first send a shift press, then the button, then release shift
99- (void)transmitKeyCode:(NSInteger)keyCode needShift:(bool)needShift {
100  if (keyCode > 0 && _delegate) {
101    if (needShift) {
102      [_delegate keyboardActionKeyCode:kKeyCodeUS[kShiftIndex] isKeyDown:YES];
103    }
104    [_delegate keyboardActionKeyCode:keyCode isKeyDown:YES];
105    [_delegate keyboardActionKeyCode:keyCode isKeyDown:NO];
106    if (needShift) {
107      [_delegate keyboardActionKeyCode:kKeyCodeUS[kShiftIndex] isKeyDown:NO];
108    }
109  }
110}
111@end
112