// Sifaka START: Support Virtual Mouse Input
        private void UpdateActiveMouse()
        {
            var hardwareMouseMoved = (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f;
            var virtualMouseMoved  = (m_VirtualMousePosition - m_LastVirtualMousePosition).sqrMagnitude > 0.0f;

            if (CachedVirtualMouse == null || (hardwareMouseMoved && !virtualMouseMoved) || (!virtualMouseMoved && m_ActiveMouseType == EMouseCursorType.Hardware))
            {
                if (m_ActiveMouseType != EMouseCursorType.Hardware && CachedVirtualMouse != null)
                {
                    if (CachedVirtualMouse.IsMouseVisible())
                    {
                        CachedVirtualMouse.SetMouseVisibile(false);
                    }
                }
                m_ActiveMouseType = EMouseCursorType.Hardware;
            }
            else if (CachedVirtualMouse != null && virtualMouseMoved)
            {
                // Update virtual mouse to match hardware mouse
                if (m_ActiveMouseType != EMouseCursorType.Virtual)
                {
                    CachedVirtualMouse.SetMouseVisibile(true);
                    CachedVirtualMouse.SetVirtualMousePosition(m_MousePosition);
                }
                m_ActiveMouseType = EMouseCursorType.Virtual;
            }
        }
        private void UpdateMousePosition()
        {
            m_LastMousePosition = m_MousePosition;
            m_MousePosition     = UnityEngine.Input.mousePosition;

            if (CachedVirtualMouse != null)
            {
                m_LastVirtualMousePosition = m_VirtualMousePosition;
                m_VirtualMousePosition     = CachedVirtualMouse.GetVirtualMousePosition();
            }
        }
        // Sifaka START: Support Virtual Mouse Input
        protected override MouseState GetMousePointerEventData(int id)
        {
            // Normal flow if no virtual mouse
            if (m_ActiveMouseType == EMouseCursorType.Hardware)
            {
                return(base.GetMousePointerEventData(id));
            }

            // Our shiny flow for virtual mouse
            PointerEventData leftData;
            var created = GetPointerData(kMouseLeftId, out leftData, true);

            leftData.Reset();

            if (created)
            {
                leftData.position = m_VirtualMousePosition;
            }

            Vector2 pos = m_VirtualMousePosition;

            leftData.delta       = pos - leftData.position;
            leftData.position    = pos;
            leftData.scrollDelta = new Vector2();
            leftData.button      = PointerEventData.InputButton.Left;
            eventSystem.RaycastAll(leftData, m_RaycastResultCache);
            var raycast = FindFirstRaycast(m_RaycastResultCache);

            leftData.pointerCurrentRaycast = raycast;
            m_RaycastResultCache.Clear();

            // copy the apropriate data into right and middle slots
            PointerEventData rightData;

            GetPointerData(kMouseRightId, out rightData, true);
            CopyFromTo(leftData, rightData);
            rightData.button = PointerEventData.InputButton.Right;

            PointerEventData middleData;

            GetPointerData(kMouseMiddleId, out middleData, true);
            CopyFromTo(leftData, middleData);
            middleData.button = PointerEventData.InputButton.Middle;

            var data = CachedVirtualMouse.GetVirtualMouseData();

            m_VirtualMouseState.SetButtonState(PointerEventData.InputButton.Left, data.ButtonEntries[PointerEventData.InputButton.Left].StateForMouseButton(), leftData);
            m_VirtualMouseState.SetButtonState(PointerEventData.InputButton.Right, data.ButtonEntries[PointerEventData.InputButton.Right].StateForMouseButton(), rightData);
            m_VirtualMouseState.SetButtonState(PointerEventData.InputButton.Middle, data.ButtonEntries[PointerEventData.InputButton.Middle].StateForMouseButton(), middleData);
            // data.Reset();
            return(m_VirtualMouseState);
        }
        private void InitialiseMousePosition()
        {
            m_MousePosition     = UnityEngine.Input.mousePosition;
            m_LastMousePosition = UnityEngine.Input.mousePosition;

            if (CachedVirtualMouse != null)
            {
                m_VirtualMousePosition     = CachedVirtualMouse.GetVirtualMousePosition();
                m_LastVirtualMousePosition = CachedVirtualMouse.GetVirtualMousePosition();
            }

            m_ActiveMouseType = EMouseCursorType.Hardware;

            _initialised = true;
        }