32 KeyboardMapper.KeyProcessingListener, KeyboardView.OnKeyboardActionListener
34 private static final String TAG =
"FreeRDP.SessionInputManager";
36 private static final int SCROLLING_TIMEOUT = 50;
37 private static final int SCROLLING_DISTANCE = 20;
38 private static final int MAX_DISCARDED_MOVE_EVENTS = 3;
39 private static final int SEND_MOVE_EVENT_TIMEOUT = 150;
41 private static final int MSG_SEND_MOVE_EVENT = 1;
42 private static final int MSG_SCROLLING_REQUESTED = 2;
44 private final Context context;
45 private final KeyboardMapper keyboardMapper;
49 private final KeyboardView keyboardView;
50 private final KeyboardView modifiersKeyboardView;
51 private final PinchZoomListener pinchZoomListener =
new PinchZoomListener();
53 private Keyboard modifiersKeyboard;
54 private Keyboard specialkeysKeyboard;
55 private Keyboard numpadKeyboard;
56 private Keyboard cursorKeyboard;
59 private long instance = 0;
60 private Bitmap bitmap;
61 private int screenWidth;
62 private int screenHeight;
63 private int discardedMoveEvents = 0;
66 private boolean sysKeyboardVisible =
false;
67 private boolean extKeyboardVisible =
false;
69 private final Handler handler;
73 KeyboardView modifiersKeyboardView)
75 this.context = context;
76 this.scrollView = scrollView;
77 this.sessionView = sessionView;
78 this.touchPointerView = touchPointerView;
79 this.keyboardView = keyboardView;
80 this.modifiersKeyboardView = modifiersKeyboardView;
81 this.handler =
new InputHandler();
83 this.keyboardMapper =
new KeyboardMapper();
84 this.keyboardMapper.init(context);
87 keyboardView.setKeyboard(specialkeysKeyboard);
88 modifiersKeyboardView.setKeyboard(modifiersKeyboard);
90 keyboardView.setOnKeyboardActionListener(
this);
91 modifiersKeyboardView.setOnKeyboardActionListener(
this);
94 private void loadKeyboards()
96 Context app = context.getApplicationContext();
97 modifiersKeyboard =
new Keyboard(app, R.xml.modifiers_keyboard);
98 specialkeysKeyboard =
new Keyboard(app, R.xml.specialkeys_keyboard);
99 numpadKeyboard =
new Keyboard(app, R.xml.numpad_keyboard);
100 cursorKeyboard =
new Keyboard(app, R.xml.cursor_keyboard);
104 public void attachSession(
long instance, Bitmap surface)
106 this.instance = instance;
107 this.bitmap = surface;
108 keyboardMapper.reset(
this);
112 public void setBitmap(Bitmap bitmap)
114 this.bitmap = bitmap;
118 public ScaleGestureDetector.OnScaleGestureListener getPinchZoomListener()
120 return pinchZoomListener;
124 public void setScreenSize(
int width,
int height)
126 this.screenWidth = width;
127 this.screenHeight = height;
132 public void reloadKeyboards()
135 keyboardView.setKeyboard(specialkeysKeyboard);
136 modifiersKeyboardView.setKeyboard(modifiersKeyboard);
140 public void toggleSystemKeyboard()
142 showKeyboard(!sysKeyboardVisible,
false);
146 public void toggleExtendedKeyboard()
148 showKeyboard(
false, !extKeyboardVisible);
152 public void hideKeyboards()
154 showKeyboard(
false,
false);
158 public boolean isAnyKeyboardVisible()
160 return sysKeyboardVisible || extKeyboardVisible;
164 private void showKeyboard(
boolean showSystemKeyboard,
boolean showExtendedKeyboard)
166 if (showSystemKeyboard)
169 keyboardView.setVisibility(View.GONE);
171 setSoftInputState(
true);
174 modifiersKeyboardView.setVisibility(View.VISIBLE);
176 else if (showExtendedKeyboard)
179 setSoftInputState(
false);
182 keyboardView.setKeyboard(specialkeysKeyboard);
183 keyboardView.setVisibility(View.VISIBLE);
184 modifiersKeyboardView.setVisibility(View.VISIBLE);
189 setSoftInputState(
false);
190 keyboardView.setVisibility(View.GONE);
191 modifiersKeyboardView.setVisibility(View.GONE);
194 keyboardMapper.clearlAllModifiers();
197 sysKeyboardVisible = showSystemKeyboard;
198 extKeyboardVisible = showExtendedKeyboard;
201 private void setSoftInputState(
boolean state)
203 InputMethodManager mgr =
204 (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
208 sessionView.requestFocus();
209 mgr.showSoftInput(sessionView, InputMethodManager.SHOW_IMPLICIT);
213 mgr.hideSoftInputFromWindow(sessionView.getWindowToken(), 0);
218 public void cancelPendingEvents()
220 handler.removeMessages(MSG_SEND_MOVE_EVENT);
224 public boolean onGenericMotionEvent(MotionEvent e)
228 if (e.getAction() != MotionEvent.ACTION_SCROLL)
231 final float vScroll = e.getAxisValue(MotionEvent.AXIS_VSCROLL);
233 LibFreeRDP.sendCursorEvent(instance, 0, 0, Mouse.getScrollEvent(context,
false));
234 else if (vScroll > 0)
235 LibFreeRDP.sendCursorEvent(instance, 0, 0, Mouse.getScrollEvent(context,
true));
240 public boolean onAndroidKeyEvent(KeyEvent event)
244 return keyboardMapper.processAndroidKeyEvent(event);
249 public boolean onAndroidKeyLongPress(
int keyCode)
253 if (keyCode == KeyEvent.KEYCODE_BACK)
255 LibFreeRDP.disconnect(instance);
262 public boolean handleBackAsAltF4()
268 keyboardMapper.sendAltF4();
273 public void toggleTouchPointer()
275 if (touchPointerView.getVisibility() == View.VISIBLE)
277 touchPointerView.setVisibility(View.INVISIBLE);
278 sessionView.setTouchPointerPadding(0, 0);
282 touchPointerView.setVisibility(View.VISIBLE);
283 sessionView.setTouchPointerPadding(touchPointerView.getPointerWidth(),
284 touchPointerView.getPointerHeight());
291 private void sendDelayedMoveEvent(
int x,
int y)
293 if (handler.hasMessages(MSG_SEND_MOVE_EVENT))
295 handler.removeMessages(MSG_SEND_MOVE_EVENT);
296 discardedMoveEvents++;
299 discardedMoveEvents = 0;
301 if (discardedMoveEvents > MAX_DISCARDED_MOVE_EVENTS)
302 LibFreeRDP.sendCursorEvent(instance, x, y, Mouse.getMoveEvent());
304 handler.sendMessageDelayed(Message.obtain(
null, MSG_SEND_MOVE_EVENT, x, y),
305 SEND_MOVE_EVENT_TIMEOUT);
308 private void cancelDelayedMoveEvent()
310 handler.removeMessages(MSG_SEND_MOVE_EVENT);
313 private Point mapScreenCoordToSessionCoord(
int x,
int y)
315 int mappedX = (int)((
float)(x + scrollView.getScrollX()) / sessionView.getZoom());
316 int mappedY = (int)((
float)(y + scrollView.getScrollY()) / sessionView.getZoom());
319 if (mappedX > bitmap.getWidth())
320 mappedX = bitmap.getWidth();
321 if (mappedY > bitmap.getHeight())
322 mappedY = bitmap.getHeight();
324 return new Point(mappedX, mappedY);
327 private void updateModifierKeyStates()
329 List<Keyboard.Key> keys = modifiersKeyboard.getKeys();
330 for (Keyboard.Key curKey : keys)
334 switch (keyboardMapper.getModifierState(curKey.codes[0]))
336 case KeyboardMapper.KEYSTATE_ON:
338 curKey.pressed =
false;
341 case KeyboardMapper.KEYSTATE_OFF:
343 curKey.pressed =
false;
346 case KeyboardMapper.KEYSTATE_LOCKED:
348 curKey.pressed =
true;
353 modifiersKeyboardView.invalidateAllKeys();
359 @Override
public void onSessionViewBeginTouch()
364 @Override
public void onSessionViewEndTouch()
369 @Override
public void onSessionViewLeftTouch(
int x,
int y,
boolean down)
374 cancelDelayedMoveEvent();
375 LibFreeRDP.sendCursorEvent(instance, x, y, Mouse.getLeftButtonEvent(context, down));
378 @Override
public void onSessionViewMiddleTouch(
int x,
int y,
boolean down)
382 LibFreeRDP.sendCursorEvent(instance, x, y, Mouse.getMiddleButtonEvent(down));
385 @Override
public void onSessionViewRightTouch(
int x,
int y,
boolean down)
389 LibFreeRDP.sendCursorEvent(instance, x, y, Mouse.getRightButtonEvent(context, down));
392 @Override
public void onSessionViewMove(
int x,
int y)
396 sendDelayedMoveEvent(x, y);
399 @Override
public void onSessionViewMouseMove(
int x,
int y)
403 LibFreeRDP.sendCursorEvent(instance, x, y, Mouse.getMoveEvent());
406 @Override
public void onSessionViewScroll(
boolean down)
410 LibFreeRDP.sendCursorEvent(instance, 0, 0, Mouse.getScrollEvent(context, down));
413 @Override
public void onSessionViewHScroll(
boolean right)
417 LibFreeRDP.sendCursorEvent(instance, 0, 0, Mouse.getHScrollEvent(context, right));
423 @Override
public void onTouchPointerClose()
425 touchPointerView.setVisibility(View.INVISIBLE);
426 sessionView.setTouchPointerPadding(0, 0);
429 @Override
public void onTouchPointerLeftClick(
int x,
int y,
boolean down)
433 Point p = mapScreenCoordToSessionCoord(x, y);
434 LibFreeRDP.sendCursorEvent(instance, p.x, p.y, Mouse.getLeftButtonEvent(context, down));
437 @Override
public void onTouchPointerRightClick(
int x,
int y,
boolean down)
441 Point p = mapScreenCoordToSessionCoord(x, y);
442 LibFreeRDP.sendCursorEvent(instance, p.x, p.y, Mouse.getRightButtonEvent(context, down));
445 @Override
public void onTouchPointerMove(
int x,
int y)
449 Point p = mapScreenCoordToSessionCoord(x, y);
450 LibFreeRDP.sendCursorEvent(instance, p.x, p.y, Mouse.getMoveEvent());
453 !handler.hasMessages(MSG_SCROLLING_REQUESTED))
455 Log.v(TAG,
"Starting auto-scroll");
456 handler.sendEmptyMessageDelayed(MSG_SCROLLING_REQUESTED, SCROLLING_TIMEOUT);
460 @Override
public void onTouchPointerScroll(
boolean down)
464 LibFreeRDP.sendCursorEvent(instance, 0, 0, Mouse.getScrollEvent(context, down));
467 @Override
public void onTouchPointerToggleKeyboard()
469 toggleSystemKeyboard();
472 @Override
public void onTouchPointerToggleExtKeyboard()
474 toggleExtendedKeyboard();
477 @Override
public void onTouchPointerResetScrollZoom()
479 sessionView.setZoom(1.0f);
486 @Override
public void processVirtualKey(
int virtualKeyCode,
boolean down)
490 LibFreeRDP.sendKeyEvent(instance, virtualKeyCode, down);
493 @Override
public void processUnicodeKey(
int unicodeKey)
497 LibFreeRDP.sendUnicodeKeyEvent(instance, unicodeKey,
true);
498 LibFreeRDP.sendUnicodeKeyEvent(instance, unicodeKey,
false);
501 @Override
public void switchKeyboard(
int keyboardType)
503 switch (keyboardType)
505 case KeyboardMapper.KEYBOARD_TYPE_FUNCTIONKEYS:
506 keyboardView.setKeyboard(specialkeysKeyboard);
509 case KeyboardMapper.KEYBOARD_TYPE_NUMPAD:
510 keyboardView.setKeyboard(numpadKeyboard);
513 case KeyboardMapper.KEYBOARD_TYPE_CURSOR:
514 keyboardView.setKeyboard(cursorKeyboard);
522 @Override
public void modifiersChanged()
524 updateModifierKeyStates();
530 @Override
public void onKey(
int primaryCode,
int[] keyCodes)
532 keyboardMapper.processCustomKeyEvent(primaryCode);
535 @Override
public void onText(CharSequence text)
539 @Override
public void swipeRight()
543 @Override
public void swipeLeft()
547 @Override
public void swipeDown()
551 @Override
public void swipeUp()
555 @Override
public void onPress(
int primaryCode)
559 @Override
public void onRelease(
int primaryCode)
566 private class InputHandler
extends Handler
570 super(Looper.getMainLooper());
573 @Override
public void handleMessage(Message msg)
577 case MSG_SEND_MOVE_EVENT:
580 LibFreeRDP.sendCursorEvent(instance, msg.arg1, msg.arg2, Mouse.getMoveEvent());
583 case MSG_SCROLLING_REQUESTED:
587 float[] pointerPos = touchPointerView.getPointerPosition();
589 if (pointerPos[0] > (screenWidth - touchPointerView.getPointerWidth()))
590 scrollX = SCROLLING_DISTANCE;
591 else if (pointerPos[0] < 0)
592 scrollX = -SCROLLING_DISTANCE;
594 if (pointerPos[1] > (screenHeight - touchPointerView.getPointerHeight()))
595 scrollY = SCROLLING_DISTANCE;
596 else if (pointerPos[1] < 0)
597 scrollY = -SCROLLING_DISTANCE;
599 scrollView.scrollBy(scrollX, scrollY);
601 if (scrollView.getScrollX() == 0 ||
602 scrollView.getScrollX() == (sessionView.getWidth() - scrollView.getWidth()))
604 if (scrollView.getScrollY() == 0 ||
605 scrollView.getScrollY() ==
606 (sessionView.getHeight() - scrollView.getHeight()))
609 if (scrollX != 0 || scrollY != 0)
610 handler.sendEmptyMessageDelayed(MSG_SCROLLING_REQUESTED, SCROLLING_TIMEOUT);
612 Log.v(TAG,
"Stopping auto-scroll");
622 private class PinchZoomListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener
624 private float scaleFactor = 1.0f;
626 @Override
public boolean onScaleBegin(ScaleGestureDetector detector)
632 @Override
public boolean onScale(ScaleGestureDetector detector)
635 scaleFactor *= detector.getScaleFactor();
636 scaleFactor = Math.max(
SessionView.MIN_SCALE_FACTOR,
637 Math.min(scaleFactor,
SessionView.MAX_SCALE_FACTOR));
638 sessionView.setZoom(scaleFactor);
640 if (!sessionView.isAtMinZoom() && !sessionView.isAtMaxZoom())
643 float transOriginX = scrollView.getScrollX() * detector.getScaleFactor();
644 float transOriginY = scrollView.getScrollY() * detector.getScaleFactor();
648 (scrollView.getScrollX() + detector.getFocusX()) * detector.getScaleFactor();
650 (scrollView.getScrollY() + detector.getFocusY()) * detector.getScaleFactor();
655 scrollView.scrollBy((
int)((transCenterX - transOriginX) - detector.getFocusX()),
656 (
int)((transCenterY - transOriginY) - detector.getFocusY()));
662 @Override
public void onScaleEnd(ScaleGestureDetector de)