public static BioSignPoint toBioSignPoint(wgssSTU.IPenData penData)
 {
     BioSignPoint result = new BioSignPoint();
     result.Pressure = penData.pressure;
     result.Rdy = penData.rdy;
     result.Sw = penData.sw;
     result.X = penData.x;
     result.Y = penData.y;
     result.Time = System.DateTime.Now;
     return result;
 }
        // Process incoming pen data
        private void onPenData(wgssSTU.IPenData penData)
        {
            Point pt = tabletToScreen(WacomPadUtils.toBioSignPoint(penData));

            int btn = 0; // will be +ve if the pen is over a button.
            {
                for (int i = 0; i < m_btns.Length; ++i)
                {
                    if (m_btns[i].Bounds.Contains(pt))
                    {
                        btn = i + 1;
                        break;
                    }
                }
            }

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

            // 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 (this.sign.Points.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 = this.CreateGraphics();
                    gfx.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                    gfx.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                    gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                    BioSignPoint prevPenData = this.sign.Points[this.sign.Points.Count - 1];

                    PointF prev = tabletToClient(prevPenData);

                    gfx.DrawLine(m_penInk, prev, tabletToClient(WacomPadUtils.toBioSignPoint(penData)));
                    gfx.Dispose();
                }

                // The pen is down, store it for use later.
                if (m_isDown == -1)
                    this.sign.addPoint(WacomPadUtils.toBioSignPoint(penData));
            }
            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_btns[btn - 1].PerformClick();
                        }
                    }
                    m_isDown = 0;
                }
                else
                {
                    // still up
                }

                // Add up data once we have collected some down data.
                if ((this.sign!= null)&&(this.sign.Points.Count != 0))
                    this.sign.addPoint(WacomPadUtils.toBioSignPoint(penData));
            }
        }
 private void onGetReportException(wgssSTU.ITabletEventsException tabletEventsException)
 {
     try
     {
         tabletEventsException.getException();
     }
     catch (Exception e)
     {
         //TODO Log4NET
         m_tablet.disconnect();
         m_tablet = null;
         this.sign = null;
         this.Close();
     }
 }
        public WacomPadForm(wgssSTU.IUsbDevice usbDevice, int points)
        {
            semaphore = true;
            this.minPoints = points;
            if (presingString != null)
            {
                presignText.Text = presingString;
            }
            this.sign = new GraphSign();
            // This is a DPI aware application, so ensure you understand how .NET client coordinates work.
            // Testing using a Windows installation set to a high DPI is recommended to understand how
            // values get scaled or not.
            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;

            InitializeComponent();

            m_tablet = new wgssSTU.Tablet();
            wgssSTU.ProtocolHelper protocolHelper = new wgssSTU.ProtocolHelper();

            // A more sophisticated applications should cycle for a few times as the connection may only be
            // temporarily unavailable for a second or so.
            // For example, if a background process such as Wacom STU Display
            // is running, this periodically updates a slideshow of images to the device.

            wgssSTU.IErrorCode ec = m_tablet.usbConnect(usbDevice, true);
            if (ec.value == 0)
            {
                m_capability = m_tablet.getCapability();
                m_information = m_tablet.getInformation();
            }
            else
            {
                throw new Exception(ec.message);
            }

            this.SuspendLayout();
            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;

            // Set the size of the client window to be actual size,
            // based on the reported DPI of the monitor.

            Size clientSize = new Size((int)(m_capability.tabletMaxX / 2540F * 96F), (int)(m_capability.tabletMaxY / 2540F * 96F));
            this.ClientSize = clientSize;
            this.ResumeLayout();

            m_btns = new Button[3];
            if (usbDevice.idProduct != 0x00a2)
            {
                // Place the buttons across the bottom of the screen.

                int w2 = m_capability.screenWidth / 3;
                int w3 = m_capability.screenWidth / 3;
                int w1 = m_capability.screenWidth - w2 - w3;
                int y = m_capability.screenHeight * 6 / 7;
                int h = m_capability.screenHeight - y;

                presignText.Bounds = new Rectangle(0, 0, m_capability.screenWidth, h);
                m_btns[0].Bounds = new Rectangle(0, y, w1, h);
                m_btns[1].Bounds = new Rectangle(w1, y, w2, h);
                m_btns[2].Bounds = new Rectangle(w1 + w2, y, w3, h);
            }
            else
            {
                // The STU-300 is very shallow, so it is better to utilise
                // the buttons to the side of the display instead.

                int x = m_capability.screenWidth * 3 / 4;
                int w = m_capability.screenWidth - x;

                int h2 = m_capability.screenHeight / 3;
                int h3 = m_capability.screenHeight / 3;
                int h1 = m_capability.screenHeight - h2 - h3;

                m_btns[0].Bounds = new Rectangle(x, 0, w, h1);
                m_btns[1].Bounds = new Rectangle(x, h1, w, h2);
                m_btns[2].Bounds = new Rectangle(x, h1 + h2, w, h3);
            }
            m_btns[0].Text = "Aceptar";
            m_btns[1].Text = "Borrar";
            m_btns[2].Text = "Cancelar";
            m_btns[0].Click = new EventHandler(btnOk_Click);
            m_btns[1].Click = new EventHandler(btnClear_Click);
            m_btns[2].Click = new EventHandler(btnCancel_Click);

            // Disable color if the STU-520 bulk driver isn't installed.
            // This isn't necessary, but uploading colour images with out the driver
            // is very slow.

            // Calculate the encodingMode that will be used to update the image
            ushort idP = m_tablet.getProductId();
            wgssSTU.encodingFlag encodingFlag = (wgssSTU.encodingFlag)protocolHelper.simulateEncodingFlag(idP, 0);
            bool useColor = false;
            if ((encodingFlag & (wgssSTU.encodingFlag.EncodingFlag_16bit | wgssSTU.encodingFlag.EncodingFlag_24bit)) != 0)
            {
                if (m_tablet.supportsWrite())
                    useColor = true;
            }
            if ((encodingFlag & wgssSTU.encodingFlag.EncodingFlag_24bit) != 0)
            {
                m_encodingMode = m_tablet.supportsWrite() ? wgssSTU.encodingMode.EncodingMode_24bit_Bulk : wgssSTU.encodingMode.EncodingMode_24bit;
            }
            else if ((encodingFlag & wgssSTU.encodingFlag.EncodingFlag_16bit) != 0)
            {
                m_encodingMode = m_tablet.supportsWrite() ? wgssSTU.encodingMode.EncodingMode_16bit_Bulk : wgssSTU.encodingMode.EncodingMode_16bit;
            }
            else
            {
                // assumes 1bit is available
                m_encodingMode = wgssSTU.encodingMode.EncodingMode_1bit;
            }

            // Size the bitmap to the size of the LCD screen.
            // This application uses the same bitmap for both the screen and client (window).
            // However, at high DPI, this bitmap will be stretch and it would be better to
            // create individual bitmaps for screen and client at native resolutions.
            m_bitmap = new Bitmap(m_capability.screenWidth, m_capability.screenHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            {
                Graphics gfx = Graphics.FromImage(m_bitmap);
                gfx.Clear(Color.White);

                // Uses pixels for units as DPI won't be accurate for tablet LCD.
                Font font = new Font(FontFamily.GenericSansSerif, m_btns[0].Bounds.Height / 2F, GraphicsUnit.Pixel);
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;

                if (useColor)
                {
                    gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                }
                else
                {
                    // Anti-aliasing should be turned off for monochrome devices.
                    gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
                }

                gfx.DrawRectangle(Pens.Black, presignText.Bounds);
                gfx.DrawString(presignText.Text, font, Brushes.Black, presignText.Bounds, sf);

                // Draw the buttons
                for (int i = 0; i < m_btns.Length; ++i)
                {
                    if (useColor)
                    {
                        gfx.FillRectangle(Brushes.LightGray, m_btns[i].Bounds);
                    }
                    gfx.DrawRectangle(Pens.Black, m_btns[i].Bounds);
                    gfx.DrawString(m_btns[i].Text, font, Brushes.Black, m_btns[i].Bounds, sf);
                }

                gfx.Dispose();
                font.Dispose();

                // Finally, use this bitmap for the window background.
                this.BackgroundImage = m_bitmap;
                this.BackgroundImageLayout = ImageLayout.Stretch;
            }

            // Now the bitmap has been created, it needs to be converted to device-native
            // format.
            {

                // Unfortunately it is not possible for the native COM component to
                // understand .NET bitmaps. We have therefore convert the .NET bitmap
                // into a memory blob that will be understood by COM.

                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                m_bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                m_bitmapData = (byte[])protocolHelper.resizeAndFlatten(stream.ToArray(), 0, 0, (uint)m_bitmap.Width, (uint)m_bitmap.Height, m_capability.screenWidth, m_capability.screenHeight, (byte)m_encodingMode, wgssSTU.Scale.Scale_Fit, 0, 0);
                protocolHelper = null;
                stream.Dispose();
            }

            // If you wish to further optimize image transfer, you can compress the image using
            // the Zlib algorithm.

            bool useZlibCompression = false;
            if (!useColor && useZlibCompression)
            {
                // m_bitmapData = compress_using_zlib(m_bitmapData); // insert compression here!
                m_encodingMode |= wgssSTU.encodingMode.EncodingMode_Zlib;
            }

            // Calculate the size and cache the inking pen.

            SizeF s = this.AutoScaleDimensions;
            float inkWidthMM = 0.7F;
            m_penInk = new Pen(Color.DarkBlue, inkWidthMM / 25.4F * ((s.Width + s.Height) / 2F));
            m_penInk.StartCap = m_penInk.EndCap = System.Drawing.Drawing2D.LineCap.Round;
            m_penInk.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;

            // Add the delagate that receives pen data.
            m_tablet.onPenData += new wgssSTU.ITabletEvents2_onPenDataEventHandler(onPenData);
            m_tablet.onGetReportException += new wgssSTU.ITabletEvents2_onGetReportExceptionEventHandler(onGetReportException);

            // Initialize the screen
            clearScreen();

            // Enable the pen data on the screen (if not already)
            m_tablet.setInkingMode(0x01);
        }