// Line processing (interlopation)
        private void LineProcessingUpdate(object sender, ElapsedEventArgs e)
        {
            try {
                // B-Spline smoothing
                if (linePoints.Count > 3)
                {
                    int      i;
                    int      splineX;
                    int      splineY;
                    double[] a  = new double[5];
                    double[] b  = new double[5];
                    Point    p1 = linePoints[0];
                    Point    p2 = linePoints[1];
                    Point    p3 = linePoints[2];
                    Point    p4 = linePoints[3];

                    a[0] = (-p1.X + 3 * p2.X - 3 * p3.X + p4.X) / 6.0;
                    a[1] = (3 * p1.X - 6 * p2.X + 3 * p3.X) / 6.0;
                    a[2] = (-3 * p1.X + 3 * p3.X) / 6.0;
                    a[3] = (p1.X + 4 * p2.X + p3.X) / 6.0;
                    b[0] = (-p1.Y + 3 * p2.Y - 3 * p3.Y + p4.Y) / 6.0;
                    b[1] = (3 * p1.Y - 6 * p2.Y + 3 * p3.Y) / 6.0;
                    b[2] = (-3 * p1.Y + 3 * p3.Y) / 6.0;
                    b[3] = (p1.Y + 4 * p2.Y + p3.Y) / 6.0;

                    smoothPoints.Add(new Point((int)a[3], (int)b[3]));

                    for (i = 1; i <= config.smoothingInterpolation - 1; i++)
                    {
                        float t = Convert.ToSingle(i) / Convert.ToSingle(config.smoothingInterpolation);
                        splineX = (int)((a[2] + t * (a[1] + t * a[0])) * t + a[3]);
                        splineY = (int)((b[2] + t * (b[1] + t * b[0])) * t + b[3]);
                        if (smoothPoints.Last <Point>() != new Point(splineX, splineY))
                        {
                            smoothPoints.Add(new Point(splineX, splineY));
                        }
                    }
                    linePoints.RemoveAt(0);
                }
                else if (MouseHook.GetCursorPosition() != position && isDrawing)
                {
                    if (config.disableCatchUp)
                    {
                        if (mouseMoving)
                        {
                            linePoints.Add(position);
                        }
                    }
                    else
                    {
                        linePoints.Add(position);
                    }
                }
            }
            catch {
                // Fail processing gracefully
            }
        }
 // Interface handling
 private void button_SmoothOnOff_Click(object sender, EventArgs e)
 {
     if (smoothingOn)
     {
         // Off
         button_smoothOnOff.BackColor = Color.Gainsboro;
         MouseHook.moveEnabled        = true;
         MouseHook.downEnabled        = true;
         smoothingOn = false;
         isDrawing   = false;
         lineSmoothingTimer.Stop();
         lineProcessingTimer.Stop();
         try {
             settings.checkBox_disableAutoDetection.Enabled = true;
         }
         catch {
             // Fail gracefully
         }
         if (config.disableAutoDetection)
         {
             checkBox_tabletMode.Enabled = true;
         }
     }
     else
     {
         // On
         button_smoothOnOff.BackColor = Color.Azure;
         linePoints.Clear();
         smoothPoints.Clear();
         position = MouseHook.GetCursorPosition();
         smoothPoints.Add(position);
         if (config.smoothOnDraw)
         {
             MouseHook.moveEnabled = true;
             isDrawing             = false;
         }
         else
         {
             MouseHook.moveEnabled = false;
             isDrawing             = true;
             lineProcessingTimer.Start();
             lineSmoothingTimer.Start();
         }
         smoothingOn = true;
         try {
             settings.checkBox_disableAutoDetection.Enabled = false;
         }
         catch {
             // Fail
         }
         if (config.disableAutoDetection)
         {
             checkBox_tabletMode.Enabled = false;
         }
     }
 }
        private void MouseMoveHandler(object sender, EventArgs e)
        {
            if (!smoothingOn)
            {
                overlay.cursorPos = MouseHook.GetCursorPosition();
                overlay.Invalidate();
            }

            if (config.smoothOnDraw && !isDrawing && MouseHook.moveEnabled)
            {
                overlay.cursorPos = MouseHook.GetCursorPosition();
                overlay.Invalidate();
            }
        }
 // Mouse event handling
 private void MouseDownHandler(object sender, EventArgs e)
 {
     if (smoothingOn)
     {
         if (config.smoothOnDraw && !isDrawing)
         {
             linePoints.Clear();
             smoothPoints.Clear();
             MouseHook.moveEnabled = false;
             Point p = MouseHook.GetCursorPosition();
             smoothPoints.Add(p);
             linePoints.Add(p);
             linePoints.Add(p);
             linePoints.Add(p);
             position  = p;
             isDrawing = true;
             lineProcessingTimer.Start();
             lineSmoothingTimer.Start();
         }
     }
 }
 private void MouseUpHandler(object sender, EventArgs e)
 {
     if (smoothingOn)
     {
         if (config.smoothOnDraw && isDrawing)
         {
             MouseHook.downEnabled = false;
             isDrawing             = false;
             lineProcessingTimer.Stop();
             linePoints.Clear();
             if (!config.snapToCursor)
             {
                 Point guidePos = overlay.cursorPos;
                 MouseHook.SetCursorPos(guidePos.X, guidePos.Y);
             }
             else
             {
                 overlay.cursorPos = MouseHook.GetCursorPosition();
             }
         }
     }
 }