Home | History | Annotate | Download | only in ios
      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