private void onPenDataTimeCountSequence(wgssSTU.IPenDataTimeCountSequence penTimeData)
        {
            UInt16 penSequence;
            UInt16 penTimeStamp;
            UInt16 penPressure;
            UInt16 x;
            UInt16 y;

            penPressure  = penTimeData.pressure;
            penTimeStamp = penTimeData.timeCount;
            penSequence  = penTimeData.sequence;
            x            = penTimeData.x;
            y            = penTimeData.y;

            Point pt  = tabletToScreen(penTimeData);
            int   btn = buttonClicked(pt); // Check if a button was clicked

            bool isDown = (penTimeData.sw != 0);

            //m_parent.print("Handling pen data timed");

            // This code uses a model of four states the pen can be in:
            // down or up, and whether this is the first sample of that state.

            if (isDown)
            {
                if (m_isDown == 0)
                {
                    // transition to down
                    if (btn > 0)
                    {
                        // We have put the pen down on a button.
                        // Track the pen without inking on the client.

                        m_isDown = btn;
                    }
                    else
                    {
                        // We have put the pen down somewhere else.
                        // Treat it as part of the signature.

                        m_isDown = -1;
                    }
                }
                else
                {
                    // already down, keep doing what we're doing!
                }

                // draw
                if (m_penTimeData.Count != 0 && m_isDown == -1)
                {
                    // Draw a line from the previous down point to this down point.
                    // This is the simplist thing you can do; a more sophisticated program
                    // can perform higher quality rendering than this!

                    Graphics gfx = setQualityGraphics(this);
                    wgssSTU.IPenDataTimeCountSequence prevPenData = m_penTimeData[m_penTimeData.Count - 1];
                    PointF prev = tabletToClient(prevPenData);

                    gfx.DrawLine(m_penInk, prev, tabletToClientTimed(penTimeData));
                    gfx.Dispose();
                }

                // The pen is down, store it for use later.
                if (m_isDown == -1)
                {
                    m_penTimeData.Add(penTimeData);
                }
            }
            else
            {
                if (m_isDown != 0)
                {
                    // transition to up
                    if (btn > 0)
                    {
                        // The pen is over a button

                        if (btn == m_isDown)
                        {
                            // The pen was pressed down over the same button as is was lifted now.
                            // Consider that as a click!
                            //m_parent.print("Performing button " + btn);
                            m_btns[btn - 1].PerformClick();
                        }
                    }
                    m_isDown = 0;
                }
                else
                {
                    // still up
                }

                // Add up data once we have collected some down data.
                if (m_penTimeData != null)
                {
                    if (m_penTimeData.Count != 0)
                    {
                        m_penTimeData.Add(penTimeData);
                    }
                }
            }
        }
 private PointF tabletToClientTimed(wgssSTU.IPenDataTimeCountSequence penData)
 {
     // Client means the Windows Form coordinates.
     return(new PointF((float)penData.x * this.ClientSize.Width / m_capability.tabletMaxX, (float)penData.y * this.ClientSize.Height / m_capability.tabletMaxY));
 }