1 // Copyright 2015 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 #ifndef REMOTING_HOST_TOUCH_INJECTOR_WIN_H_ 6 #define REMOTING_HOST_TOUCH_INJECTOR_WIN_H_ 7 8 #include <windows.h> 9 #include <stdint.h> 10 #include <map> 11 #include <memory> 12 #include <vector> 13 14 #include "base/macros.h" 15 #include "base/scoped_native_library.h" 16 17 namespace remoting { 18 19 namespace protocol { 20 21 class TouchEvent; 22 23 } // namespace protocol 24 25 // This class calls InitializeTouchInjection() and InjectTouchInput() functions. 26 // The methods are virtual for mocking. 27 class TouchInjectorWinDelegate { 28 public: 29 virtual ~TouchInjectorWinDelegate(); 30 31 // Determines whether Windows touch injection functions can be used. 32 // Returns a non-null TouchInjectorWinDelegate on success. 33 static std::unique_ptr<TouchInjectorWinDelegate> Create(); 34 35 // These match the functions in MSDN. 36 virtual BOOL InitializeTouchInjection(UINT32 max_count, DWORD dw_mode); 37 virtual DWORD InjectTouchInput(UINT32 count, 38 const POINTER_TOUCH_INFO* contacts); 39 40 protected: 41 // Ctor in protected scope for mocking. 42 // This object takes ownership of the |library|. 43 TouchInjectorWinDelegate( 44 base::NativeLibrary library, 45 BOOL(NTAPI* initialize_touch_injection_func)(UINT32, DWORD), 46 BOOL(NTAPI* inject_touch_input_func)(UINT32, const POINTER_TOUCH_INFO*)); 47 48 private: 49 base::ScopedNativeLibrary library_module_; 50 51 // Pointers to Windows touch injection functions. 52 BOOL(NTAPI* initialize_touch_injection_func_)(UINT32, DWORD); 53 BOOL(NTAPI* inject_touch_input_func_)(UINT32, const POINTER_TOUCH_INFO*); 54 55 DISALLOW_COPY_AND_ASSIGN(TouchInjectorWinDelegate); 56 }; 57 58 // This class converts TouchEvent objects to POINTER_TOUCH_INFO so that it can 59 // be injected using the Windows touch injection API, and calls the injection 60 // functions. 61 // This class expects good inputs and does not sanity check the inputs. 62 // This class just converts the object and hands it off to the Windows API. 63 class TouchInjectorWin { 64 public: 65 TouchInjectorWin(); 66 ~TouchInjectorWin(); 67 68 // Returns false if initialization of touch injection APIs fails. 69 bool Init(); 70 71 // Deinitializes the object so that it can be reinitialized. 72 void Deinitialize(); 73 74 // Inject touch events. 75 void InjectTouchEvent(const protocol::TouchEvent& event); 76 77 void SetInjectorDelegateForTest( 78 std::unique_ptr<TouchInjectorWinDelegate> functions); 79 80 private: 81 // Helper methods called from InjectTouchEvent(). 82 // These helpers adapt Chromoting touch events, which convey changes to touch 83 // points, to Windows touch descriptions, which must include descriptions for 84 // all currently-active touch points, not just the changed ones. 85 void AddNewTouchPoints(const protocol::TouchEvent& event); 86 void MoveTouchPoints(const protocol::TouchEvent& event); 87 void EndTouchPoints(const protocol::TouchEvent& event); 88 void CancelTouchPoints(const protocol::TouchEvent& event); 89 90 // Set to null if touch injection is not available from the OS. 91 std::unique_ptr<TouchInjectorWinDelegate> delegate_; 92 93 // TODO(rkuroiwa): crbug.com/470203 94 // This is a naive implementation. Check if we can achieve 95 // better performance by reducing the number of copies. 96 // To reduce the number of copies, we can have a vector of 97 // POINTER_TOUCH_INFO and a map from touch ID to index in the vector. 98 // When removing points from the vector, just swap it with the last element 99 // and resize the vector. 100 // All the POINTER_TOUCH_INFOs are stored as "move" points. 101 std::map<uint32_t, POINTER_TOUCH_INFO> touches_in_contact_; 102 103 DISALLOW_COPY_AND_ASSIGN(TouchInjectorWin); 104 }; 105 106 } // namespace remoting 107 108 #endif // REMOTING_HOST_TOUCH_INJECTOR_WIN_H_ 109