/// <summary>
        /// Dispatched thread of DataReceived callback
        /// </summary>
        /// <param name="context">Context ID (always 0 for this)</param>
        /// <param name="data">Data block pointer</param>
        private void DataCallbackSTA(int context, data_block *data)
        {
            try
            {
                // X/Y Coordinates
                if (data->type == 1)
                {
                    my_data_block.tick    = data->tick;
                    my_data_block.rawx    = data->rawx;
                    my_data_block.rawy    = data->rawy;
                    my_data_block.calx    = data->calx;
                    my_data_block.caly    = data->caly;
                    my_data_block.hDevice = data->hDevice;
                    my_data_block.hStylus = data->hStylus;
                    my_data_block.type    = data->type;

                    if (Math.Abs(my_data_block.rawx - _lastX) < 5 && Math.Abs(my_data_block.rawy - _lastY) < 5)
                    // todo: invert this
                    {
                    }
                    else
                    {
                        _lastX = my_data_block.rawx;
                        _lastY = my_data_block.rawy;

                        if (TouchBaseMove != null && ScalingHandle != -1)
                        {
                            int x = 0, y = 0;
                            // Use the hooked window's rectangle to scale the controller coordinates to the window
                            if (DLL_TBApiScaleCoordinates(ref ScalingHandle, ref my_data_block, ref x, ref y))
                            {
                                LastPoint = new Point(x, y);
                            }
                            else
                            {
                                LastPoint = new Point(my_data_block.calx, my_data_block.caly);
                            }

                            TouchBaseMove(this, LastPoint);
                        }
                    }
                }
                // Touch Up/Down state
                if (data->type == 2)
                {
                    event_block *p_event = (event_block *)data;
                    my_event_block.tick    = p_event->tick;
                    my_event_block.left    = p_event->left;
                    my_event_block.right   = p_event->right;
                    my_event_block.timed   = p_event->timed;
                    my_event_block.hDevice = p_event->hDevice;
                    my_event_block.hStylus = p_event->hStylus;
                    my_event_block.type    = p_event->type;

                    // Fire "Down" if either Left or Right is pressed
                    if (my_event_block.left == 1 || my_event_block.right == 1)
                    {
                        if (TouchBaseDown != null && ScalingHandle != -1)
                        {
                            TouchBaseDown(this, LastPoint);
                        }
                    }
                    // Fire "Up" if both Left and Light are not pressed
                    else if (my_event_block.left == 0 && my_event_block.right == 0)
                    {
                        if (TouchBaseUp != null && ScalingHandle != -1)
                        {
                            TouchBaseUp(this, LastPoint);
                        }
                    }
                }

                if ((DateTime.Now - _lastRead).TotalMilliseconds < 100)
                {
                    return;
                }
                _lastRead = DateTime.Now;
            }
            catch (Exception ex) { }
            finally
            {
                _callbackReset.Set();
            }
        }
 /// <summary>
 /// DataReceived callback from the API
 /// </summary>
 /// <param name="context">Context ID (always 0 for this)</param>
 /// <param name="data">Data block pointer</param>
 private void DataCallback(int context, data_block *data)
 {
     // In order to make this play nice, we have to invoke it on the dispatcher thread of the hooked window.
     HookedWnd.Dispatcher.Invoke(new ThreadStart(() => DataCallbackSTA(context, data)),
                                 DispatcherPriority.Render);
 }