Esempio n. 1
0
        private void FormSpectralTest_Load(object sender, EventArgs e)
        {
            comboDeviceType.DataSource = Enum.GetValues(typeof(DeviceType));
            comboLedName.DataSource    = Enum.GetValues(typeof(LedName));

            Led.Initialize();

            string status = "";

            status += $"Logitech is enabled: {Led.LogitechIsEnabled().ToString()}\n";
            status += $"Corsair is enabled: {Led.CorsairIsEnabled().ToString()}\n";
            // status += $"Razer is enabled: {Led.RazerIsEnabled().ToString()}\n";

            labelStatus.Text = status;

            Led.SetColor(Color.Black);
            Led.SetColorForLeds(new List <LedName> {
                LedName.W, LedName.A, LedName.S, LedName.D
            }, Color.OrangeRed);
            Led.SetColorForLeds(new List <LedName> {
                LedName.LeftShift, LedName.E, LedName.Q
            }, Color.Green);
            Led.SetColorForLeds(new List <LedName> {
                LedName.One, LedName.Two, LedName.Three, LedName.Four
            }, Color.Blue);
            Led.SetColorForLed(LedName.R, Color.Red);
            Led.SetColorForLed(LedName.F, Color.Purple);
            Led.SetColorForLed(LedName.Spacebar, Color.White);
            Led.SetColorForLed(LedName.MouseZone1, Color.ForestGreen);
            Led.SetColorForLed(LedName.HeadsetLeftZone, Color.SeaGreen);
            Led.SetColorForLed(LedName.MousepadZone1, Color.PaleVioletRed);
            Led.SetColorForLed(LedName.SpeakerLeft, Color.MediumOrchid);
        }
Esempio n. 2
0
 void Start()
 {
     if (Led.Initialize())
     {
         Led.SetColor(Color.black);
         Led.SetColorForLeds(
             new[] { LedName.W, LedName.A, LedName.S, LedName.D },
             Color.magenta
             );
     }
 }
        void patternAnimator_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;

            try
            {
                log.InfoFormat("[{0}] Starting pattern playback", this.Serial);

                List <TriggeredEvent> eventsPlaying = new List <TriggeredEvent>();

                while (!worker.CancellationPending)
                {
                    TriggeredEvent ev = null;

                    lock (EventQueue)
                    {
                        for (int i = 0; i < EventQueue.Count; i++)
                        {
                            ev = EventQueue.Dequeue();

                            for (int j = eventsPlaying.Count - 1; j >= 0; j--)
                            {
                                if (ev.Notification == eventsPlaying[j].Notification && (eventsPlaying[j].Repeat < 0 || eventsPlaying[j].Duration > 0))
                                {
                                    log.DebugFormat("Removing infinite playback notifications as there is another pending");
                                    TriggeredEvent evPlaying = eventsPlaying[j];
                                    eventsPlaying.RemoveAt(j);
                                    AssignBusyLeds(evPlaying, false);
                                }
                            }

                            if (CanPlayEvent(ev))
                            {
                                break;
                            }
                            else
                            {
                                EventQueue.Enqueue(ev);
                                ev = null;
                            }
                        }
                    }

                    if (ev != null)
                    {
                        if (ev.NotificationSnapshot is PatternNotification)
                        {
                            ev.EventStarted     = DateTime.Now;
                            ev.AnimationStarted = DateTime.Now;

                            PatternNotification notification = ev.NotificationSnapshot as PatternNotification;
                            foreach (Animation animation in notification.Pattern.Animations)
                            {
                                Animation copyAnimation = new Animation();
                                copyAnimation.Assign(animation);
                                ev.Animations.Add(copyAnimation);
                            }

                            ev.Animations[0].ReferenceColor = GetColor(ev.NotificationSnapshot);

                            AssignBusyLeds(ev, true);
                            eventsPlaying.Add(ev);
                        }
                        else
                        {
                            ev.AnimationStarted = DateTime.Now;
                            ev.EventStarted     = DateTime.Now;

                            foreach (Animation animation in ev.Pattern.Animations)
                            {
                                Animation copyAnimation = new Animation();
                                copyAnimation.Assign(animation);
                                ev.Animations.Add(copyAnimation);
                            }

                            ev.Animations[0].ReferenceColor = GetColor(ev.NotificationSnapshot);

                            AssignBusyLeds(ev, true);
                            eventsPlaying.Add(ev);
                        }
                    }

                    //Prepare next frame of data to send to LEDs
                    for (int ii = eventsPlaying.Count - 1; ii >= 0; ii--)
                    {
                        TriggeredEvent evnt = eventsPlaying[ii];

                        RgbColor color = evnt.Animations[evnt.AnimationIndex].GetColor(evnt.AnimationStarted.Value, DateTime.Now, evnt.Animations[evnt.AnimationIndex].ReferenceColor);

                        PatternNotification notification = evnt.NotificationSnapshot as PatternNotification;

                        lock (this)
                        {
                            SetColor(evnt, color.R, color.G, color.B);
                        }

                        if (evnt.Animations[evnt.AnimationIndex].AnimationFinished)
                        {
                            evnt.AnimationIndex += 1;

                            if (evnt.Duration > 0 && evnt.EventStarted.Value.AddMilliseconds(evnt.Duration) <= DateTime.Now)
                            {
                                eventsPlaying.RemoveAt(ii);
                                AssignBusyLeds(evnt, false);
                            }
                            else if (evnt.AnimationIndex == evnt.Animations.Count)
                            {
                                evnt.RepeatCount += 1;

                                if (evnt.Duration > 0 || evnt.Repeat < 0 || evnt.RepeatCount < evnt.Repeat)
                                {
                                    evnt.AnimationStarted = DateTime.Now;
                                    evnt.AnimationIndex   = 0;

                                    evnt.Animations.ForEach(delegate(Animation a) { a.Reset(); });
                                }
                                else
                                {
                                    eventsPlaying.RemoveAt(ii);
                                    AssignBusyLeds(evnt, false);
                                }
                            }
                            else
                            {
                                evnt.Animations[evnt.AnimationIndex].ReferenceColor = GetColor(evnt.NotificationSnapshot);
                                evnt.AnimationStarted = DateTime.Now;
                            }
                        }
                    }

                    if (Led != null && NeedsLedUpdate)
                    {
                        lock (this)
                        {
                            NeedsLedUpdate = false;
                        }

                        int retryCount = 5;

                        if (Led.BlinkStickDevice == BlinkStickDeviceEnum.BlinkStick ||
                            Led.BlinkStickDevice == BlinkStickDeviceEnum.BlinkStickPro && Led.Mode < 2)
                        {
                            while (retryCount > 0)                              //Retry loop
                            {
                                try
                                {
                                    Led.SetColor(LedFrame[0][1], LedFrame[0][0], LedFrame[0][2]);
                                    retryCount = 0;
                                }
                                catch (Exception ex)
                                {
                                    retryCount--;
                                    log.ErrorFormat("Failed to set color: {0}", ex);
                                    if (retryCount > 0)
                                    {
                                        Thread.Sleep(20);
                                        log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                    }
                                    else
                                    {
                                        log.Warn("Failed to set color 5 times, giving up...");
                                    }
                                }
                            }
                        }
                        else
                        {
                            byte[] frame = new byte[this.LedsR * 3];
                            Array.Copy(LedFrame[0], 0, frame, 0, frame.Length);

                            while (retryCount > 0)                             //Retry loop
                            {
                                try
                                {
                                    Led.SetColors(0, frame);
                                    retryCount = 0;
                                }
                                catch (Exception ex)
                                {
                                    retryCount--;
                                    log.ErrorFormat("Failed to set color: {0}", ex);
                                    if (retryCount > 0)
                                    {
                                        Thread.Sleep(20);
                                        log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                    }
                                    else
                                    {
                                        log.Warn("Failed to set color 5 times, giving up...");
                                    }
                                }
                            }

                            int sleep = Math.Max(2, (int)(this.LedsR * 3 * 8f / 400f * 1.2)); //number of LEDs times 3 color elements times 8 bytes divided by speed
                            Thread.Sleep(sleep);

                            if (Led != null && Led.BlinkStickDevice == BlinkStickDeviceEnum.BlinkStickPro)
                            {
                                frame = new byte[this.LedsG * 3];
                                Array.Copy(LedFrame[1], 0, frame, 0, frame.Length);

                                while (retryCount > 0)                                 //Retry loop
                                {
                                    try
                                    {
                                        Led.SetColors(1, frame);
                                        retryCount = 0;
                                    }
                                    catch (Exception ex)
                                    {
                                        retryCount--;
                                        log.ErrorFormat("Failed to set color: {0}", ex);
                                        if (retryCount > 0)
                                        {
                                            Thread.Sleep(20);
                                            log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                        }
                                        else
                                        {
                                            log.Warn("Failed to set color 5 times, giving up...");
                                        }
                                    }
                                }

                                sleep = Math.Max(2, (int)(this.LedsG * 3 * 8f / 400f * 1.2));
                                Thread.Sleep(sleep);

                                frame = new byte[this.LedsB * 3];
                                Array.Copy(LedFrame[2], 0, frame, 0, frame.Length);

                                while (retryCount > 0)                                 //Retry loop
                                {
                                    try
                                    {
                                        Led.SetColors(2, frame);
                                        retryCount = 0;
                                    }
                                    catch (Exception ex)
                                    {
                                        retryCount--;
                                        log.ErrorFormat("Failed to set color: {0}", ex);
                                        if (retryCount > 0)
                                        {
                                            Thread.Sleep(20);
                                            log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                        }
                                        else
                                        {
                                            log.Warn("Failed to set color 5 times, giving up...");
                                        }
                                    }
                                }

                                sleep = Math.Max(2, (int)(this.LedsB * 3 * 8f / 400f * 1.2));
                                Thread.Sleep(sleep);
                            }
                        }
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("Pattern playback crash {0}", ex);
            }

            log.InfoFormat("[{0}] Pattern playback stopped", this.Serial);

            Running = false;
        }
Esempio n. 4
0
        public static void LedUpdateThread_Task()
        {
            Led.Initialize();
            Led.SetColor(0, 0, 0);

            int delay = 100; // Target delay between updates in milliseconds

            // Define a bitmap that will be used to hold the screen data while we copy it to an easy-access array of bytes
            Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                       Screen.PrimaryScreen.Bounds.Height);

            // Instantiation of the pixel array requires knowing the scan width of the screen

            /*It is beneficial to do this once rather than in the loop because creating large
             * arrays is computationally expensive and they aren't disposed immediately*/
            // I was able to reduce average memory usage from 250MB to 63MB by doing this.
            BitmapData init_screen = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);
            int size = Math.Abs(init_screen.Stride) * bitmap.Height; // Stride * Height IS EQUAL TO Number of pixels * bytes per pixel

            bitmap.UnlockBits(init_screen);                          // We don't need this anymore
            byte[] pixels = new byte[size];                          // Creates the array for direct access to pixel data copied via the Marshal

            while (true)
            {
                // Keep track of how long we take to process a screencapture
                Stopwatch timer = new Stopwatch();
                timer.Start();

                using (Graphics capture = Graphics.FromImage(bitmap))
                {
                    try
                    {
                        // Capture the screen and copy it into the bitmap
                        capture.CopyFromScreen(
                            Screen.PrimaryScreen.Bounds.X,
                            Screen.PrimaryScreen.Bounds.Y,
                            0, 0,
                            bitmap.Size,
                            CopyPixelOperation.SourceCopy);
                    }
                    catch
                    {
                        // The copy operation can fail if the user locks the screen, so handling that exception is a good idea.
                        Thread.Sleep(delay);
                        continue;
                    }

                    // Lock the bitmap. This is required if we want to gain direct access to the pixel data, which we absolutely do.
                    BitmapData screen = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                    // Copy the pixels to the array
                    IntPtr pointer = screen.Scan0;
                    Marshal.Copy(pointer, pixels, 0, size);

                    foreach (var key in KeyMap.LookupTable)
                    {
                        // Calculate an average colour for the area around the position
                        int r, g, b, pixel_count;
                        r = g = b = pixel_count = 0;
                        // Loop over region centered around a key's coordinates
                        for (int y = key.Value.Y - key.Value.height / 2; y <= key.Value.Y + key.Value.height / 2; y += 5)
                        {
                            for (int x = key.Value.X - key.Value.width / 2; x <= key.Value.X + key.Value.width / 2; x += 5)
                            {
                                // Skip out of bounds coordinates
                                if (x < 0 ||
                                    y < 0 ||
                                    x >= Screen.PrimaryScreen.Bounds.Width ||
                                    y >= Screen.PrimaryScreen.Bounds.Height)
                                {
                                    continue;
                                }

                                /* Index is the result of a formula for calculating the index to a target pixel
                                 * We multiply x by 4 is because pixel data is encoded in 4 bytes: b,g,r,a
                                 * Note that screen.Stride is the image width also multiplied by 4
                                 * Once you have the index for a desired pixel, an offset of 2,1,0 will yield the red,green,blue values.
                                 * The transparency/alpha channel value at offset 3 is seemingly unused because it appears to be a constant 255.*/
                                long index = (y * screen.Stride) + (x * 4);

                                // Mean average add
                                r += pixels[index + 2];
                                g += pixels[index + 1];
                                b += pixels[index];
                                pixel_count++; // Keep track of how many pixels we are averaging
                            }
                        }
                        if (pixel_count == 0)
                        {
                            continue;
                        }
                        // Mean average divide
                        r /= pixel_count;
                        g /= pixel_count;
                        b /= pixel_count;

                        if (Flags.saturation_enable)
                        {
                            // Extract hue and lightness from colour
                            RGB2HSL.RgbToHls(r, g, b, out double h, out double l, out double s);
                            // Set saturation to max and change that back to rgb
                            RGB2HSL.HlsToRgb(h, l, Math.Min(1, s * Flags.saturation_factor), out r, out g, out b);
                        }

                        // Maximum value clamping at 255
                        r = Math.Min(r, 255);
                        g = Math.Min(g, 255);
                        b = Math.Min(b, 255);

                        // If enabled, draw the debug squares across the screen to illustrate
                        if (Flags.debug_enable)
                        {
                            IntPtr desktop = GetDC(IntPtr.Zero);
                            using (Graphics g_out = Graphics.FromHdc(desktop))
                            {
                                if (Flags.debug_showscanregion)
                                {
                                    // Outline the scan region
                                    g_out.DrawRectangle(Pens.White,
                                                        // Top left point
                                                        key.Value.X + (-key.Value.width / 2),
                                                        key.Value.Y + (-key.Value.height / 2),
                                                        // Dimensions
                                                        key.Value.width,
                                                        key.Value.height);
                                }
                                if (Flags.debug_showkeynames)
                                {
                                    // Write key name for reference
                                    g_out.DrawString(key.Key.ToString(),
                                                     new Font("Arial", 7, FontStyle.Bold),
                                                     Brushes.Cyan,
                                                     // Position top left with 5px margin
                                                     key.Value.X + (-key.Value.width / 2) + 5,
                                                     key.Value.Y + (-key.Value.height / 2) + 5);
                                }

                                // Center box containing calculated colour, with 1px white border
                                g_out.FillRectangle(Brushes.White,
                                                    key.Value.X - 6, key.Value.Y - 6, 12, 12);
                                g_out.FillRectangle(new SolidBrush(Color.FromArgb(r, g, b)),
                                                    key.Value.X - 5, key.Value.Y - 5, 10, 10);
                            }
                            ReleaseDC(IntPtr.Zero, desktop);
                        }

                        // Update the led
                        Led.SetColorForLed(key.Key, (byte)r, (byte)g, (byte)b);
                    }
                    bitmap.UnlockBits(screen); // Don't forget to unlock the bitmap at the end
                }
                // Calculate how long we should sleep to wait the rest of the 100 milliseconds
                // Should the elapsed time exceed the desired wait time, the Max function ensures we never pass a value below 0.
                // If that were to happen then an exception would be thrown.
                timer.Stop();
                Thread.Sleep(Math.Max(0, delay - (int)timer.ElapsedMilliseconds));
            }
        }