Ejemplo 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);
        }
Ejemplo n.º 2
0
        private void buttonSetColor_Click(object sender, EventArgs e)
        {
            colorDialog.ShowDialog();

            if (!Led.SetColorForLed(selectedLed, colorDialog.Color))
            {
                MessageBox.Show($"There was an issue setting the color for {selectedLed.ToString()}.");
            }
        }
Ejemplo n.º 3
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));
            }
        }