// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef REMOTING_HOST_TOUCH_INJECTOR_WIN_H_ #define REMOTING_HOST_TOUCH_INJECTOR_WIN_H_ #include #include #include #include "base/memory/scoped_ptr.h" #include "base/scoped_native_library.h" namespace remoting { namespace protocol { class TouchEvent; } // namespace protocol // This class calls InitializeTouchInjection() and InjectTouchInput() functions. // The methods are virtual for mocking. class TouchInjectorWinDelegate { public: virtual ~TouchInjectorWinDelegate(); // Determines whether Windows touch injection functions can be used. // Returns a non-null TouchInjectorWinDelegate on success. static scoped_ptr Create(); // These match the functions in MSDN. virtual BOOL InitializeTouchInjection(UINT32 max_count, DWORD dw_mode); virtual DWORD InjectTouchInput(UINT32 count, const POINTER_TOUCH_INFO* contacts); protected: // Ctor in protected scope for mocking. // This object takes ownership of the |library|. TouchInjectorWinDelegate( base::NativeLibrary library, BOOL(NTAPI* initialize_touch_injection_func)(UINT32, DWORD), BOOL(NTAPI* inject_touch_input_func)(UINT32, const POINTER_TOUCH_INFO*)); private: base::ScopedNativeLibrary library_module_; // Pointers to Windows touch injection functions. BOOL(NTAPI* initialize_touch_injection_func_)(UINT32, DWORD); BOOL(NTAPI* inject_touch_input_func_)(UINT32, const POINTER_TOUCH_INFO*); DISALLOW_COPY_AND_ASSIGN(TouchInjectorWinDelegate); }; // This class converts TouchEvent objects to POINTER_TOUCH_INFO so that it can // be injected using the Windows touch injection API, and calls the injection // functions. // This class expects good inputs and does not sanity check the inputs. // This class just converts the object and hands it off to the Windows API. class TouchInjectorWin { public: TouchInjectorWin(); ~TouchInjectorWin(); // Returns false if initialization of touch injection APIs fails. bool Init(); // Deinitializes the object so that it can be reinitialized. void Deinitialize(); // Inject touch events. void InjectTouchEvent(const protocol::TouchEvent& event); void SetInjectorDelegateForTest( scoped_ptr functions); private: // Helper methods called from InjectTouchEvent(). // These helpers adapt Chromoting touch events, which convey changes to touch // points, to Windows touch descriptions, which must include descriptions for // all currently-active touch points, not just the changed ones. void AddNewTouchPoints(const protocol::TouchEvent& event); void MoveTouchPoints(const protocol::TouchEvent& event); void EndTouchPoints(const protocol::TouchEvent& event); void CancelTouchPoints(const protocol::TouchEvent& event); // Set to null if touch injection is not available from the OS. scoped_ptr delegate_; // TODO(rkuroiwa): crbug.com/470203 // This is a naive implementation. Check if we can achieve // better performance by reducing the number of copies. // To reduce the number of copies, we can have a vector of // POINTER_TOUCH_INFO and a map from touch ID to index in the vector. // When removing points from the vector, just swap it with the last element // and resize the vector. // All the POINTER_TOUCH_INFOs are stored as "move" points. std::map touches_in_contact_; DISALLOW_COPY_AND_ASSIGN(TouchInjectorWin); }; } // namespace remoting #endif // REMOTING_HOST_TOUCH_INJECTOR_WIN_H_