AbstractInputHandler getInputHandlerByName(String name) {
   AbstractInputHandler result = null;
   for (int id : inputModeIds) {
     AbstractInputHandler handler = getInputHandlerById(id);
     if (handler.getName().equals(name)) {
       result = handler;
       break;
     }
   }
   if (result == null) {
     result = getInputHandlerById(R.id.itemInputTouchPanZoomMouse);
   }
   return result;
 }
 // Send touch events or mouse events like button clicks to be handled.
 @Override
 public boolean onTouchEvent(MotionEvent event) {
   try {
     return inputHandler.onTouchEvent(event);
   } catch (NullPointerException e) {
   }
   return super.onTouchEvent(event);
 }
 /*
  * (non-Javadoc)
  *
  * @see android.app.Activity#onTrackballEvent(android.view.MotionEvent)
  */
 @Override
 public boolean onTrackballEvent(MotionEvent event) {
   try {
     // If we are using the Dpad as arrow keys, don't send the event to the inputHandler.
     if (connection.getUseDpadAsArrows()) return false;
     return inputHandler.onTrackballEvent(event);
   } catch (NullPointerException e) {
   }
   return super.onTrackballEvent(event);
 }
 public void showPanningState(boolean showLonger) {
   if (showLonger) {
     final Toast t = Toast.makeText(this, inputHandler.getHandlerDescription(), Toast.LENGTH_LONG);
     TimerTask tt =
         new TimerTask() {
           @Override
           public void run() {
             t.show();
             try {
               Thread.sleep(2000);
             } catch (InterruptedException e) {
             }
             t.show();
           }
         };
     new Timer().schedule(tt, 2000);
     t.show();
   } else {
     Toast t = Toast.makeText(this, inputHandler.getHandlerDescription(), Toast.LENGTH_SHORT);
     t.show();
   }
 }
  @Override
  public boolean onKey(View v, int keyCode, KeyEvent evt) {

    boolean consumed = false;

    if (keyCode == KeyEvent.KEYCODE_MENU) {
      if (evt.getAction() == KeyEvent.ACTION_DOWN) return super.onKeyDown(keyCode, evt);
      else return super.onKeyUp(keyCode, evt);
    }

    try {
      if (evt.getAction() == KeyEvent.ACTION_DOWN || evt.getAction() == KeyEvent.ACTION_MULTIPLE) {
        consumed = inputHandler.onKeyDown(keyCode, evt);
      } else if (evt.getAction() == KeyEvent.ACTION_UP) {
        consumed = inputHandler.onKeyUp(keyCode, evt);
      }
      resetOnScreenKeys(keyCode);
    } catch (NullPointerException e) {
    }

    return consumed;
  }
 // Send e.g. mouse events like hover and scroll to be handled.
 @Override
 public boolean onGenericMotionEvent(MotionEvent event) {
   // Ignore TOOL_TYPE_FINGER events that come from the touchscreen with HOVER type action
   // which cause pointer jumping trouble in simulated touchpad for some devices.
   int a = event.getAction();
   if (!((a == MotionEvent.ACTION_HOVER_ENTER
           || a == MotionEvent.ACTION_HOVER_EXIT
           || a == MotionEvent.ACTION_HOVER_MOVE)
       && event.getSource() == InputDevice.SOURCE_TOUCHSCREEN
       && event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER)) {
     try {
       return inputHandler.onTouchEvent(event);
     } catch (NullPointerException e) {
     }
   }
   return super.onGenericMotionEvent(event);
 }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    canvas.getKeyboard().setAfterMenu(true);
    switch (item.getItemId()) {
      case R.id.itemInfo:
        canvas.showConnectionInfo();
        return true;
      case R.id.itemSpecialKeys:
        showDialog(R.layout.metakey);
        return true;
      case R.id.itemColorMode:
        selectColorModel();
        return true;
        // Following sets one of the scaling options
      case R.id.itemZoomable:
      case R.id.itemOneToOne:
      case R.id.itemFitToScreen:
        AbstractScaling.getById(item.getItemId()).setScaleTypeForActivity(this);
        item.setChecked(true);
        showPanningState(false);
        return true;
      case R.id.itemCenterMouse:
        canvas
            .getPointer()
            .warpMouse(
                canvas.absoluteXPosition + canvas.getVisibleWidth() / 2,
                canvas.absoluteYPosition + canvas.getVisibleHeight() / 2);
        return true;
      case R.id.itemDisconnect:
        canvas.closeConnection();
        finish();
        return true;
      case R.id.itemEnterText:
        showDialog(R.layout.entertext);
        return true;
      case R.id.itemCtrlAltDel:
        canvas.getKeyboard().sendMetaKey(MetaKeyBean.keyCtrlAltDel);
        return true;
        /*        case R.id.itemFollowMouse:
                    boolean newFollow = !connection.getFollowMouse();
                    item.setChecked(newFollow);
                    connection.setFollowMouse(newFollow);
                    if (newFollow) {
                        vncCanvas.panToMouse();
                    }
                    connection.save(database.getWritableDatabase());
                    database.close();
                    return true;
                case R.id.itemFollowPan:
                    boolean newFollowPan = !connection.getFollowPan();
                    item.setChecked(newFollowPan);
                    connection.setFollowPan(newFollowPan);
                    connection.save(database.getWritableDatabase());
                    database.close();
                    return true;

                case R.id.itemArrowLeft:
                    vncCanvas.sendMetaKey(MetaKeyBean.keyArrowLeft);
                    return true;
                case R.id.itemArrowUp:
                    vncCanvas.sendMetaKey(MetaKeyBean.keyArrowUp);
                    return true;
                case R.id.itemArrowRight:
                    vncCanvas.sendMetaKey(MetaKeyBean.keyArrowRight);
                    return true;
                case R.id.itemArrowDown:
                    vncCanvas.sendMetaKey(MetaKeyBean.keyArrowDown);
                    return true;
        */
      case R.id.itemSendKeyAgain:
        sendSpecialKeyAgain();
        return true;
        // Disabling Manual/Wiki Menu item as the original does not correspond to this project
        // anymore.
        // case R.id.itemOpenDoc:
        //    Utils.showDocumentation(this);
        //    return true;
      case R.id.itemExtraKeys:
        if (connection.getExtraKeysToggleType() == Constants.EXTRA_KEYS_ON) {
          connection.setExtraKeysToggleType(Constants.EXTRA_KEYS_OFF);
          item.setTitle(R.string.extra_keys_enable);
          setExtraKeysVisibility(View.GONE, false);
        } else {
          connection.setExtraKeysToggleType(Constants.EXTRA_KEYS_ON);
          item.setTitle(R.string.extra_keys_disable);
          setExtraKeysVisibility(View.VISIBLE, false);
          extraKeysHidden = false;
        }
        setKeyStowDrawableAndVisibility();
        connection.save(database.getWritableDatabase());
        database.close();
        return true;
      case R.id.itemHelpInputMode:
        showDialog(R.id.itemHelpInputMode);
        return true;
      default:
        AbstractInputHandler input = getInputHandlerById(item.getItemId());
        if (input != null) {
          inputHandler = input;
          connection.setInputMode(input.getName());
          if (input.getName().equals(SimulatedTouchpadInputHandler.TOUCHPAD_MODE)) {
            connection.setFollowMouse(true);
            connection.setFollowPan(true);
          } else {
            connection.setFollowMouse(false);
            connection.setFollowPan(false);
          }

          item.setChecked(true);
          showPanningState(true);
          connection.save(database.getWritableDatabase());
          database.close();
          return true;
        }
    }
    return super.onOptionsItemSelected(item);
  }