Example #1
0
        private void PostProcessInput(object sender, ProcessInputEventArgs e)
        {
            InputReportEventArgs input = e.StagingItem.Input as InputReportEventArgs;

            if (input != null && input.RoutedEvent == InputManager.InputReportEvent)
            {
                RawGenericInputReport report = input.Report as RawGenericInputReport;

                if (report != null)
                {
                    if (!e.StagingItem.Input.Handled)
                    {
                        GenericEvent     ge   = (GenericEvent)report.InternalEvent;
                        GenericEventArgs args = new GenericEventArgs(
                            this,
                            report.InternalEvent);

                        args.RoutedEvent = GenericEvents.GenericStandardEvent;
                        if (report.Target != null)
                        {
                            args.Source = report.Target;
                        }

                        e.PushInput(args, e.StagingItem);
                    }
                }
            }
        }
Example #2
0
        private RawButtonInputReport ExtractRawButtonInputReport(NotifyInputEventArgs e, RoutedEvent Event)
        {
            RawButtonInputReport buttonInput = null;

            InputReportEventArgs input = e.StagingItem.Input as InputReportEventArgs;

            if (input != null)
            {
                if (input.Report is RawButtonInputReport && input.RoutedEvent == Event)
                {
                    buttonInput = (RawButtonInputReport)input.Report;
                }
            }

            return(buttonInput);
        }
        private void PostProcessInput(object sender, ProcessInputEventArgs e)
        {
            if (!e.StagingItem.Input.Handled)
            {
                RoutedEvent routedEvent = e.StagingItem.Input.RoutedEvent;
                if (routedEvent == InputManager.InputReportEvent)
                {
                    InputReportEventArgs input = e.StagingItem.Input as InputReportEventArgs;
                    if (input != null)
                    {
                        RawTouchInputReport report = input.Report as RawTouchInputReport;
                        if (report != null)
                        {
                            TouchEventArgs args = new TouchEventArgs(
                                this,
                                report.Timestamp,
                                report.Touches);

                            UIElement target = report.Target;
                            if (report.EventMessage == (byte)TouchMessages.Down)
                            {
                                args.RoutedEvent = TouchEvents.TouchDownEvent;
                            }
                            else if (report.EventMessage == (byte)TouchMessages.Up)
                            {
                                args.RoutedEvent = TouchEvents.TouchUpEvent;
                            }
                            else if (report.EventMessage == (byte)TouchMessages.Move)
                            {
                                args.RoutedEvent = TouchEvents.TouchMoveEvent;
                            }
                            else
                            {
                                throw new Exception("Unknown touch event.");
                            }

                            args.Source = (target == null ? _focus : target);
                            e.PushInput(args, e.StagingItem);
                        }
                    }
                }
            }
        }
        /// <summary>
        ///     Reports input to the input manager.
        /// </summary>
        /// <returns>
        ///     Whether or not any event generated as a consequence of this
        ///     event was handled.
        /// </returns>
        // do we really need this?  Make the "providers" call InputManager.ProcessInput themselves.
        // we currently need to map back to providers for other reasons.
        public bool ReportInput(InputDevice device, InputReport inputReport)
        {
            if (_isDisposed)
            {
                throw new InvalidOperationException();
            }

            bool handled = false;

            InputReportEventArgs input = new InputReportEventArgs(device, inputReport);

            input.RoutedEvent = InputManager.PreviewInputReportEvent;

            if (_inputManager != null)
            {
                handled = _inputManager.ProcessInput(input);
            }

            return(handled);
        }
        private object ProcessStagingArea(object frame)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.

            try
            {
                while (_stagingArea.Count > 0)
                {
                    _currentStagingStack = _stagingArea.Dequeue() as Stack;

                    do
                    {
                        StagingAreaInputItem item = (StagingAreaInputItem)_currentStagingStack.Pop();

                        // Pre-Process the input.  This could modify the staging
                        // area, and it could cancel the processing of this
                        // input event.
                        //

                        bool fCanceled = false;

                        int devType = (int)item.Input._inputDevice.DeviceType;

                        if (InputDeviceEvents[devType]._preProcessInput != null)
                        {
                            PreProcessInputEventArgs preProcessInputEventArgs;
                            InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                            fCanceled = preProcessInputEventArgs._canceled;
                        }

                        if (!fCanceled)
                        {
                            // Pre-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._preNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Raise the input event being processed.
                            InputEventArgs input = item.Input;

                            // Some input events are explicitly associated with
                            // an element.  Those that are not instead are associated with
                            // the target of the input device for this event.
                            UIElement eventSource = input._source as UIElement;

                            if (eventSource == null && input._inputDevice != null)
                            {
                                eventSource = input._inputDevice.Target;
                            }

                            if (eventSource != null)
                            {
                                eventSource.RaiseEvent(input);
                            }

                            // Post-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._postNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Post-Process the input.  This could modify the staging
                            // area.
                            if (InputDeviceEvents[devType]._postProcessInput != null)
                            {
                                InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));
                            }

                            // PreviewInputReport --> InputReport
                            if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                            {
                                if (!item.Input.Handled)
                                {
                                    InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                    InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                    inputReport.RoutedEvent = InputManager.InputReportEvent;

                                    _currentStagingStack.Push(new StagingAreaInputItem(inputReport, item));
                                }
                            }

                            if (input.Handled)
                            {
                                handled = true;
                            }
                        }
                    } while (_currentStagingStack.Count > 0);
                }
            }
            finally
            {
                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to. 
                if (_stagingArea.Count > 0)
                {
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, Dispatcher.CurrentFrame);
                }

                _frameStagingArea.Remove(frame);
            }

            return handled;
        }
Example #6
0
        private object ProcessStagingArea(object postContinue)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.
           
            while (_stagingArea.Count > 0)
            {
                StagingAreaInputItem item = (StagingAreaInputItem)_stagingArea.Pop();

                // If we found a marker, we have reached the end of a
                // "section" of the staging area.  We just return from
                // the synchronous processing of the staging area.
                // If a dispatcher frame has been pushed by someone, this
                // will not return to the original ProcessInput.  Instead
                // it will unwind to the dispatcher and since we have
                // already pushed a work item to continue processing the
                // input, it will simply call back into us to do more
                // processing.  At which point we will continue to drain
                // the staging area.  This could cause strage behavior,
                // but it is deemed more acceptable than stalling input
                // processing.
                // make sure we all agree on this.  We could also
                // just delay the rest of the staging area until
                // the dispatcher frame finishes.  Unfortunately,
                // this means you could receive an input event for
                // something that happened a long time ago.

                if (item.IsMarker)
                {
                    break;
                }

                // Pre-Process the input.  This could modify the staging
                // area, and it could cancel the processing of this
                // input event.
                //

                bool fCanceled = false;

                int devType = (int)item.Input._inputDevice.DeviceType;

                if (InputDeviceEvents[devType]._preProcessInput != null)
                {
                    PreProcessInputEventArgs preProcessInputEventArgs;
                    InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                    fCanceled = preProcessInputEventArgs._canceled;
                }

                if (!fCanceled)
                {
                    // Pre-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._preNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Raise the input event being processed.
                    InputEventArgs input = item.Input;

                    // Some input events are explicitly associated with
                    // an element.  Those that are not instead are associated with
                    // the target of the input device for this event.
                    UIElement eventSource = input._source as UIElement;

                    if (eventSource == null && input._inputDevice != null)
                    {
                        eventSource = input._inputDevice.Target;
                    }

                    if (eventSource != null)
                    {
                        eventSource.RaiseEvent(input);
                    }

                    // Post-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._postNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Post-Process the input.  This could modify the staging
                    // area.
                    if (InputDeviceEvents[devType]._postProcessInput != null)
                    {
                        InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));

                        // PreviewInputReport --> InputReport
                        if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                        {
                            if (!item.Input.Handled)
                            {
                                InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                inputReport.RoutedEvent = InputManager.InputReportEvent;

                                _stagingArea.Push(new StagingAreaInputItem(false, inputReport, item));
                            }
                        }
                    }

                    if (input.Handled)
                    {
                        handled = true;
                    }
                }
            }

            if ((bool)postContinue == true)
            {
                _continueProcessingStagingArea = false;

                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to.
                if (_stagingArea.Count > 0)
                {
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, true);
                    _continueProcessingStagingArea = true;

                    // Now fall through to synchronously drain the staging area.
                }
            }

            return handled;
        }
        /// <summary>
        ///     Reports input to the input manager.
        /// </summary>
        /// <returns>
        ///     Whether or not any event generated as a consequence of this
        ///     event was handled.
        /// </returns>
        // do we really need this?  Make the "providers" call InputManager.ProcessInput themselves.
        // we currently need to map back to providers for other reasons.
        public bool ReportInput(InputDevice device, InputReport inputReport)
        {
            if (_isDisposed)
            {
                throw new InvalidOperationException();
            }

            bool handled = false;

            InputReportEventArgs input = new InputReportEventArgs(device, inputReport);
            input.RoutedEvent = InputManager.PreviewInputReportEvent;

            if (_inputManager != null)
            {
                handled = _inputManager.ProcessInput(input);
            }

            return handled;
        }
        private object ProcessStagingArea(object postContinue)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.

            _continueProcessingStagingArea = true;

            try
            {
                while (_stagingArea.Count > 0)
                {
                    _currentStagingStack = _stagingArea.Dequeue() as Stack;

                    do
                    {
                        StagingAreaInputItem item = (StagingAreaInputItem)_currentStagingStack.Pop();

                        // Pre-Process the input.  This could modify the staging
                        // area, and it could cancel the processing of this
                        // input event.
                        //

                        bool fCanceled = false;

                        int devType = (int)item.Input._inputDevice.DeviceType;

                        if (InputDeviceEvents[devType]._preProcessInput != null)
                        {
                            PreProcessInputEventArgs preProcessInputEventArgs;
                            InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                            fCanceled = preProcessInputEventArgs._canceled;
                        }

                        if (!fCanceled)
                        {
                            // Pre-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._preNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Raise the input event being processed.
                            InputEventArgs input = item.Input;

                            // Some input events are explicitly associated with
                            // an element.  Those that are not instead are associated with
                            // the target of the input device for this event.
                            UIElement eventSource = input._source as UIElement;

                            if (eventSource == null && input._inputDevice != null)
                            {
                                eventSource = input._inputDevice.Target;
                            }

                            if (eventSource != null)
                            {
                                eventSource.RaiseEvent(input);
                            }

                            // Post-Notify the input.
                            //
                            if (InputDeviceEvents[devType]._postNotifyInput != null)
                            {
                                InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                            }

                            // Post-Process the input.  This could modify the staging
                            // area.
                            if (InputDeviceEvents[devType]._postProcessInput != null)
                            {
                                InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));
                            }

                            // PreviewInputReport --> InputReport
                            if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                            {
                                if (!item.Input.Handled)
                                {
                                    InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                    InputReportEventArgs inputReport        = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                    inputReport.RoutedEvent = InputManager.InputReportEvent;

                                    _currentStagingStack.Push(new StagingAreaInputItem(inputReport, item));
                                }
                            }

                            if (input.Handled)
                            {
                                handled = true;
                            }
                        }
                    }while(_currentStagingStack.Count > 0);
                }
            }
            finally
            {
                _continueProcessingStagingArea = false;

                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to.
                if (_stagingArea.Count > 0)
                {
                    _continueProcessingStagingArea = true;
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, true);
                }
            }

            return(handled);
        }
Example #9
0
        private object ProcessStagingArea(object postContinue)
        {
            bool handled = false;

            // NOTE -- avalon caches the XXXEventArgs.  In our system, the costs are different,
            // so it is probably cheaper for us to just create them, since everything gets created
            // on the heap anyways, and IL is expensive.  we should reconsider this if
            // its a performance impact.

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.

            while (_stagingArea.Count > 0)
            {
                StagingAreaInputItem item = (StagingAreaInputItem)_stagingArea.Pop();

                // If we found a marker, we have reached the end of a
                // "section" of the staging area.  We just return from
                // the synchronous processing of the staging area.
                // If a dispatcher frame has been pushed by someone, this
                // will not return to the original ProcessInput.  Instead
                // it will unwind to the dispatcher and since we have
                // already pushed a work item to continue processing the
                // input, it will simply call back into us to do more
                // processing.  At which point we will continue to drain
                // the staging area.  This could cause strage behavior,
                // but it is deemed more acceptable than stalling input
                // processing.
                // make sure we all agree on this.  We could also
                // just delay the rest of the staging area until
                // the dispatcher frame finishes.  Unfortunately,
                // this means you could receive an input event for
                // something that happened a long time ago.

                if (item.IsMarker)
                {
                    break;
                }

                // Pre-Process the input.  This could modify the staging
                // area, and it could cancel the processing of this
                // input event.
                //

                bool fCanceled = false;

                int devType = (int)item.Input._inputDevice.DeviceType;

                if (InputDeviceEvents[devType]._preProcessInput != null)
                {
                    PreProcessInputEventArgs preProcessInputEventArgs;
                    InputDeviceEvents[devType]._preProcessInput(this, preProcessInputEventArgs = new PreProcessInputEventArgs(item));

                    fCanceled = preProcessInputEventArgs._canceled;
                }

                if (!fCanceled)
                {
                    // Pre-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._preNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._preNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Raise the input event being processed.
                    InputEventArgs input = item.Input;

                    // Some input events are explicitly associated with
                    // an element.  Those that are not instead are associated with
                    // the target of the input device for this event.
                    UIElement eventSource = input._source as UIElement;

                    if (eventSource == null && input._inputDevice != null)
                    {
                        eventSource = input._inputDevice.Target;
                    }

                    if (eventSource != null)
                    {
                        eventSource.RaiseEvent(input);
                    }

                    // Post-Notify the input.
                    //
                    if (InputDeviceEvents[devType]._postNotifyInput != null)
                    {
                        InputDeviceEvents[devType]._postNotifyInput(this, new NotifyInputEventArgs(item));
                    }

                    // Post-Process the input.  This could modify the staging
                    // area.
                    if (InputDeviceEvents[devType]._postProcessInput != null)
                    {
                        InputDeviceEvents[devType]._postProcessInput(this, new ProcessInputEventArgs(item));

                        // PreviewInputReport --> InputReport
                        if (item.Input._routedEvent == InputManager.PreviewInputReportEvent)
                        {
                            if (!item.Input.Handled)
                            {
                                InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;
                                InputReportEventArgs inputReport        = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                inputReport.RoutedEvent = InputManager.InputReportEvent;

                                _stagingArea.Push(new StagingAreaInputItem(false, inputReport, item));
                            }
                        }
                    }

                    if (input.Handled)
                    {
                        handled = true;
                    }
                }
            }

            if ((bool)postContinue == true)
            {
                _continueProcessingStagingArea = false;

                // It is possible that we can be re-entered by a nested
                // dispatcher frame.  Continue processing the staging
                // area if we need to.
                if (_stagingArea.Count > 0)
                {
                    // Before we actually start to drain the staging area, we need
                    // to post a work item to process more input.  This enables us
                    // to process more input if we enter a nested pump.
                    Dispatcher.BeginInvoke(_continueProcessingStagingAreaCallback, true);
                    _continueProcessingStagingArea = true;

                    // Now fall through to synchronously drain the staging area.
                }
            }

            return(handled);
        }