Merge branch 'master' into Dark_Core_RGB_PRO

This commit is contained in:
Clofriwen
2022-08-15 15:42:28 +02:00
committed by GitHub
26 changed files with 1625 additions and 241 deletions
+27
View File
@@ -0,0 +1,27 @@
---
runs:
using: composite
steps:
- name: Create `cmake` symbolic link
run: |
if ! command -v cmake &> /dev/null && command -v cmake3 &> /dev/null; then
ln --symbolic cmake3 /usr/bin/cmake
fi
shell: bash --noprofile --norc -euxo pipefail {0}
- name: Prepare `build` directory
run: |
cmake -S . -B build \
-LA \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE:-Debug} \
-DFORCE_INIT_SYSTEM=systemd \
-DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX:-/usr} \
-DSAFE_INSTALL=ON \
-DSAFE_UNINSTALL=ON
shell: bash --noprofile --norc -euxo pipefail {0}
- name: Build
run: |
export CMAKE_BUILD_PARALLEL_LEVEL=${BUILD_PARALLEL_LEVEL:-$(nproc)}
cmake --build build
shell: bash --noprofile --norc -euxo pipefail {0}
+7
View File
@@ -0,0 +1,7 @@
---
runs:
using: composite
steps:
- name: Install
run: cmake --build build --target install
shell: bash --noprofile --norc -euxo pipefail {0}
+31
View File
@@ -0,0 +1,31 @@
---
runs:
using: composite
steps:
- name: Create `cpack` symbolic link
run: |
if ! command -v cpack &> /dev/null && command -v cpack3 &> /dev/null; then
ln --symbolic cpack3 /usr/bin/cpack
fi
shell: bash --noprofile --norc -euxo pipefail {0}
- name: Use `TGZ` generator
run: |
echo "CPACK_OPTIONS=-G TGZ" >> ${GITHUB_ENV}
shell: bash --noprofile --norc -euxo pipefail {0}
if: startsWith(matrix.image, 'archlinux:')
- name: Use `RPM` generator
run: |
echo "CPACK_OPTIONS=-G RPM" >> ${GITHUB_ENV}
shell: bash --noprofile --norc -euxo pipefail {0}
if: |
startsWith(matrix.image, 'almalinux:') ||
startsWith(matrix.image, 'amazonlinux:') ||
startsWith(matrix.image, 'fedora:') ||
startsWith(matrix.image, 'rockylinux:')
- name: Package
run: cpack --config CPackConfig.cmake ${CPACK_OPTIONS:-}
shell: bash --noprofile --norc -euxo pipefail {0}
working-directory: build
@@ -0,0 +1,155 @@
---
inputs:
archlinux-build-dependencies:
default: >-
cmake
git
libdbusmenu-qt5
libpulse
libsystemd
libxcb
make
pkgconf
qt5-base
qt5-tools
qt5-x11extras
quazip
xcb-util-wm
zlib
debian-build-dependencies:
default: >-
cmake
git
libdbusmenu-qt5-dev
libpulse-dev
libqt5x11extras5-dev
libquazip5-dev
libudev-dev
libxcb-ewmh-dev
libxcb-screensaver0-dev
libxcb1-dev
qtbase5-dev
qttools5-dev
zlib1g-dev
debian-package-dependencies:
default: >-
dpkg-dev
file
fedora-build-dependencies:
default: >-
cmake
dbusmenu-qt5-devel
git
glibc
libxcb-devel
make
pulseaudio-libs-devel
qt5-linguist
qt5-qtbase-devel
qt5-qtx11extras-devel
quazip-qt5-devel
systemd-devel
xcb-util-devel
xcb-util-wm-devel
zlib-devel
fedora-package-dependencies:
default: >-
rpm-build
rhel-build-dependencies:
default: >-
cmake3
dbusmenu-qt5-devel
git
glibc
libxcb-devel
make
pulseaudio-libs-devel
qt5-linguist
qt5-qtbase-devel
qt5-qtx11extras-devel
quazip-qt5-devel
systemd-devel
xcb-util-devel
xcb-util-wm-devel
zlib-devel
rhel-package-dependencies:
default: >-
rpm-build
ubuntu-build-dependencies:
default: >-
cmake
git
libdbusmenu-qt5-dev
libpulse-dev
libqt5x11extras5-dev
libquazip5-dev
libudev-dev
libxcb-ewmh-dev
libxcb-screensaver0-dev
libxcb1-dev
qtbase5-dev
qttools5-dev
zlib1g-dev
ubuntu-package-dependencies:
default: >-
dpkg-dev
file
runs:
using: composite
steps:
- name: Install Dependencies (AlmaLinux/Amazon Linux/Rocky Linux)
uses: ./.github/actions/dependencies/install/yum
with:
dependencies: epel-release
packages: >-
${{ inputs.rhel-build-dependencies }}
${{ inputs.rhel-package-dependencies }}
${{ matrix.compiler == 'LLVM' && 'clang' || 'gcc gcc-c++' }}
if: |
startsWith(matrix.image, 'almalinux:') ||
startsWith(matrix.image, 'amazonlinux:') ||
startsWith(matrix.image, 'rockylinux:')
- name: Install Dependencies (Arch Linux)
uses: ./.github/actions/dependencies/install/pacman
with:
packages: >-
${{ inputs.archlinux-build-dependencies }}
${{ matrix.compiler == 'LLVM' && 'clang' || 'gcc' }}
if: startsWith(matrix.image, 'archlinux:')
- name: Install Dependencies (Debian)
uses: ./.github/actions/dependencies/install/apt-get
with:
packages: >-
${{ inputs.debian-build-dependencies }}
${{ inputs.debian-package-dependencies }}
${{ matrix.compiler == 'LLVM' && 'clang' || 'g++ gcc' }}
if: startsWith(matrix.image, 'debian:')
- name: Install Dependencies (Fedora)
uses: ./.github/actions/dependencies/install/yum
with:
packages: >-
${{ inputs.fedora-build-dependencies }}
${{ inputs.fedora-package-dependencies }}
${{ matrix.compiler == 'LLVM' && 'clang' || 'gcc gcc-c++' }}
if: startsWith(matrix.image, 'fedora:')
- name: Install Dependencies (Ubuntu)
uses: ./.github/actions/dependencies/install/apt-get
with:
packages: >-
${{ inputs.ubuntu-build-dependencies }}
${{ inputs.ubuntu-package-dependencies }}
${{ matrix.compiler == 'LLVM' && 'clang' || 'g++ gcc' }}
if: startsWith(matrix.image, 'ubuntu:')
@@ -0,0 +1,18 @@
---
inputs:
packages:
description: List of package(s) to install
required: true
runs:
using: composite
steps:
- name: Update package information
run: apt-get --yes update
shell: bash --noprofile --norc -euxo pipefail {0}
- name: Install package(s)
env:
DEBIAN_FRONTEND: noninteractive
run: apt-get --yes install ${{ inputs.packages }}
shell: bash --noprofile --norc -euxo pipefail {0}
@@ -0,0 +1,12 @@
---
inputs:
packages:
description: List of package(s) to install
required: true
runs:
using: composite
steps:
- name: Install package(s)
run: pacman --sync --refresh --sysupgrade --noconfirm ${{ inputs.packages }}
shell: bash --noprofile --norc -euxo pipefail {0}
@@ -0,0 +1,44 @@
---
inputs:
dependencies:
description: List of package(s) to pre-install
required: false
groups:
description: List of group(s) to install
required: false
packages:
description: List of package(s) to install
required: true
runs:
using: composite
steps:
- name: Enable PowerTools repository (AlmaLinux 8/Rocky Linux 8)
run: |
dnf --assumeyes --skip-broken install "dnf-command(config-manager)"
dnf config-manager --set-enabled powertools
shell: bash --noprofile --norc -euxo pipefail {0}
if: matrix.image == 'almalinux:8' || matrix.image == 'rockylinux:8'
- name: Enable EPEL repository (Amazon Linux 2)
run: amazon-linux-extras install epel -y
shell: bash --noprofile --norc -euxo pipefail {0}
if: matrix.image == 'amazonlinux:2' && contains(inputs.dependencies, 'epel-release')
- name: Install dependency package(s)
run: |
if [ -n "${{ inputs.dependencies }}" ]; then
yum --assumeyes install ${{ inputs.dependencies }}
fi
shell: bash --noprofile --norc -euxo pipefail {0}
- name: Install group(s)
run: |
if [ -n '${{ inputs.groups }}' ]; then
yum --assumeyes groups install ${{ inputs.groups }}
fi
shell: bash --noprofile --norc -euxo pipefail {0}
- name: Install package(s)
run: yum --assumeyes --skip-broken install ${{ inputs.packages }}
shell: bash --noprofile --norc -euxo pipefail {0}
+30
View File
@@ -0,0 +1,30 @@
---
inputs:
new_package_name:
default: ckb-next.${{ matrix.image }}.${{ matrix.compiler || 'GNU' }}.${{ matrix.build_type || 'Debug' }}
description: Name of package file (without suffix)
required: false
old_package_name:
default: ckb-next
description: Name of package file (without suffix)
required: false
runs:
using: composite
steps:
- name: Rename package
run: |
mkdir -p /tmp/package
for OLD_PACKAGE_FILE in ${{ inputs.old_package_name }}.*; do
NEW_PACKAGE_FILE=$(echo ${OLD_PACKAGE_FILE} | sed -e 's/${{ inputs.old_package_name }}/${{ inputs.new_package_name }}/' -e 's/:/-/')
mv ${OLD_PACKAGE_FILE} /tmp/package/${NEW_PACKAGE_FILE}
done
shell: bash --noprofile --norc -euxo pipefail {0}
working-directory: build
- name: Upload package
uses: actions/upload-artifact@v3
with:
name: Packages
path: /tmp/package/*
+68
View File
@@ -0,0 +1,68 @@
---
name: Build
on:
- push
jobs:
Linux:
name: ${{ matrix.image }} (${{ matrix.compiler }})
runs-on: ubuntu-latest
strategy:
matrix:
image:
- 'amazonlinux:2'
- 'archlinux:latest'
- 'almalinux:8'
- 'rockylinux:8'
- 'debian:10'
- 'debian:11'
- 'fedora:35'
- 'fedora:36'
- 'ubuntu:20.04'
- 'ubuntu:22.04'
build_type:
- Release
compiler:
- GNU
fail-fast: false
container:
env:
BUILD_TYPE: ${{ matrix.build_type || 'Debug' }}
CC: ${{ matrix.compiler == 'LLVM' && 'clang' || 'gcc' }}
CXX: ${{ matrix.compiler == 'LLVM' && 'clang++' || 'g++' }}
image: ${{ matrix.image }}
steps:
- name: Install `git`
run: |
if command -v apt-get &> /dev/null; then
apt-get --quiet --quiet update && apt-get --quiet --quiet install git
elif command -v pacman &> /dev/null; then
pacman --sync --refresh --sysupgrade --noconfirm git
elif command -v yum &> /dev/null; then
yum --assumeyes install git
fi
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/actions/dependencies/install
- name: Build `ckb-next`
uses: ./.github/actions/cmake/build
- name: Install `ckb-next`
uses: ./.github/actions/cmake/install
- name: Run `ckb-next-daemon --help`
run: |
ckb-next-daemon --help
- name: Package `ckb-next`
uses: ./.github/actions/cmake/package
- name: Upload `ckb-next` package to workflow artifacts
uses: ./.github/actions/upload-package
+1
View File
@@ -1,6 +1,7 @@
CMakeLists.txt.user
bin/
build/
!.github/actions/cmake/build
*.app/
cmake-build*/
*.pkg
+34 -48
View File
@@ -24,58 +24,44 @@
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# - Try to find PulseAudioSimple
#
# Once done this will define:
# PULSEAUDIO_FOUND - system has pulseaudio simple
# PULSEAUDIO_INCLUDE_DIRS - the pulseaudio simple include directory
# PULSEAUDIO_LIBRARIES - Link these to use pulseaudio simple
# PULSEAUDIOSIMPLE_FOUND - system has pulseaudio simple
# PULSEAUDIOSIMPLE_INCLUDE_DIRS - the pulseaudio simple include directory
# PULSEAUDIOSIMPLE_LIBRARIES - Link these to use pulseaudio simple
# PULSEAUDIO_FOUND - system has pulseaudio
# PULSEAUDIO_INCLUDE_DIRS - the pulseaudio include directory
# PULSEAUDIO_LIBRARIES - Link these to use pulseaudio
foreach (pulsevariablename PULSEAUDIOSIMPLE PULSEAUDIO)
find_path(${pulsevariablename}_INCLUDE_DIR
NAMES
pulseaudio.h
PATH_SUFFIXES pulse
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
find_path(PULSEAUDIO_INCLUDE_DIR
NAMES
pulseaudio.h
PATH_SUFFIXES pulse
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
set(pulselibname pulse)
set(pulsepackagename PulseAudio)
if (${pulsevariablename} STREQUAL "PULSEAUDIOSIMPLE")
set(pulselibname pulse-simple)
set(pulsepackagename PulseAudioSimple)
endif ()
find_library(PULSEAUDIO_LIBRARY
NAMES
pulse
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
find_library(${pulsevariablename}_LIBRARY
NAMES
${pulselibname}
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(PULSEAUDIO_INCLUDE_DIRS
${PULSEAUDIO_DIR}
)
set(PULSEAUDIO_LIBRARIES
${PULSEAUDIO_LIBRARY}
)
set(${pulsevariablename}_INCLUDE_DIRS
${${pulsevariablename}_DIR}
)
set(${pulsevariablename}_LIBRARIES
${${pulsevariablename}_LIBRARY}
)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set PULSEAUDIO_FOUND to TRUE if
# all listed variables are TRUE
find_package_handle_standard_args(PulseAudio DEFAULT_MSG PULSEAUDIO_LIBRARY PULSEAUDIO_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set ${pulsevariablename}_FOUND to TRUE if
# all listed variables are TRUE
find_package_handle_standard_args(${pulsepackagename} DEFAULT_MSG ${pulsevariablename}_LIBRARY ${pulsevariablename}_INCLUDE_DIR)
# show the ${pulsevariablename}_INCLUDE_DIRS and ${pulsevariablename}_LIBRARIES variables only in the advanced view
mark_as_advanced(${pulsevariablename}_INCLUDE_DIRS ${pulsevariablename}_LIBRARIES)
endforeach (pulsevariablename)
# show the PULSEAUDIO_INCLUDE_DIRS and PULSEAUDIO_LIBRARIES variables only in the advanced view
mark_as_advanced(PULSEAUDIO_INCLUDE_DIRS PULSEAUDIO_LIBRARIES)
+4 -4
View File
@@ -27,8 +27,8 @@
if (NOT USE_PORTAUDIO)
find_package(PulseAudio)
if (NOT ${PULSEAUDIOSIMPLE_FOUND})
message(WARNING "Missing PulseAudio Simple API. Not building mviz.")
if (NOT ${PULSEAUDIO_FOUND})
message(WARNING "Missing PulseAudio API. Not building mviz.")
return()
endif ()
endif ()
@@ -61,9 +61,9 @@ else ()
target_include_directories(
mviz
PRIVATE
"${PULSEAUDIOSIMPLE_INCLUDE_DIRS}")
"${PULSEAUDIO_INCLUDE_DIRS}")
set(AUDIO_LIBRARIES "${PULSEAUDIOSIMPLE_LIBRARIES}")
set(AUDIO_LIBRARIES "${PULSEAUDIO_LIBRARIES}")
endif ()
if (MACOS)
+375 -166
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2017 Devon Richards
* Copyright (C) 2019 Tasos Sahanidis <[email protected]>
* Copyright (C) 2019 - 2022 Tasos Sahanidis <[email protected]>
* mviz is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
@@ -17,36 +17,62 @@
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <assert.h>
#ifdef USE_PORTAUDIO
#include <portaudio.h>
PaStream *stream = NULL;
long int devid = 0;
#else
#include <pulse/simple.h>
pa_simple *stream = NULL;
#endif
#include <pulse/pulseaudio.h>
static pa_mainloop* pa_ml;
static pa_context* pa_ctx;
static pa_stream* pa_str;
static pa_context_state_t pa_state = PA_CONTEXT_UNCONNECTED;
typedef struct {
char* dev;
bool ok;
} server_info_cb_data;
#include <kissfft/kiss_fftr.h>
#include <ckb-next/animation.h>
#define MAX_RANGE 1024
int translated_frame[MAX_RANGE] = { 0 };
//#define range 768 // ~15KHz
long int range = 512;
double div_fact = 2000000.0;
#define APPEND(a, b) a ## b
#define F_CONST(num) APPEND(num, f)
#define M_PI_F F_CONST(M_PI)
#define FFT_SIZE 1024
static float translated_frame[FFT_SIZE/4] = { 0.f };
#define MAX_LATENCY 16666
static float powers[FFT_SIZE/2] = { 0.f };
static float hann_res[FFT_SIZE] = { 0.f };
static kiss_fft_cfg config;
static ckb_gradient color = { 0 };
static unsigned char bg_a, bg_r, bg_g, bg_b;
static double div_fact = 100.0;
// Normalisation factor * 100
double norm_f = 0.06;
long int v_offset = 0;
static double norm_f = 0.06;
static long int v_offset = 0;
static size_t actual_fft_size = 0;
static unsigned int* key_lit = NULL;
// int linear = 0;
static int single_colour = 0;
int single_colour = 0;
#define ENUMVALSTR_(x) #x
#define ENUMVALSTR(x) ENUMVALSTR_(x)
typedef enum {
CAPTURE_DEV_SERVER,
CAPTURE_DEV_MONITOR,
CAPTURE_DEV_SOURCE,
CAPTURE_DEV_MAX,
} default_device_t;
// We have to use long int here as this is the only int the functions can understand
// Default value is CAPTURE_DEV_SERVER to not break older profiles
static long int default_device = CAPTURE_DEV_SERVER, old_default_device = CAPTURE_DEV_SERVER;
void ckb_info(){
CKB_NAME("Music Visualization");
CKB_VERSION("1.0");
CKB_COPYRIGHT("2017-2019", "RULER501 & TasosSah");
CKB_COPYRIGHT("2017-2022", "RULER501 & TasosSah");
CKB_LICENSE("GPLv2+");
CKB_GUID("{097D69F0-70B2-48B8-AFE2-25CA1DB0D92C}");
CKB_DESCRIPTION("A collection of music visualization effects.<br><a href=\"https://github.com/ckb-next/ckb-next/wiki/Animations#mviz-music-visualizer\">Set-up instructions</a>");
@@ -56,149 +82,297 @@ void ckb_info(){
CKB_PARAM_ARGB("bgcolour", "Background:", "", 0xFF, 0x00, 0x00, 0x00);
CKB_PARAM_DOUBLE("norm_f", "Normalisation:", "", 7.5, 0.1, 20.0);
CKB_PARAM_DOUBLE("div_fact", "Sensitivity:", "", 70.0, 1.0, 100.0);
#ifdef USE_PORTAUDIO
CKB_PARAM_LONG("devid", "Device:\n(See About)", "", 0, 0, 100);
#endif
CKB_PARAM_LONG("v_offset", "Vertical Offset:", "", 0, 0, 100);
CKB_PARAM_LONG("range", "Range:", "", 512, 1, MAX_RANGE);
// CKB_PARAM_BOOL("linear", "Use linear scale", "0");
CKB_PARAM_BOOL("singlecol", "Single Colour", 0);
CKB_PARAM_LONG("default_device", "Audio device type:", "", CAPTURE_DEV_MONITOR, CAPTURE_DEV_SERVER, CAPTURE_DEV_MAX-1);
// Timing/input parameters
CKB_KPMODE(CKB_KP_NONE);
CKB_TIMEMODE(CKB_TIME_ABSOLUTE);
CKB_TIMEMODE(CKB_TIME_DURATION);
CKB_REPEAT(FALSE);
CKB_LIVEPARAMS(TRUE);
// Presets
CKB_PRESET_START("Default");
CKB_PRESET_PARAM("trigger", "0");
CKB_PRESET_PARAM("kptrigger", "1");
#define MON_STR " (Monitor)"
#define SRC_STR " (Source)"
#define CST_SRC " (Custom)"
char enumstr[2];
// Spectrum
CKB_PRESET_START("Spectrum" MON_STR);
CKB_PRESET_PARAM("trigger", "1");
CKB_PRESET_PARAM("kptrigger", "0");
CKB_PRESET_PARAM("norm_f", "7.5");
CKB_PRESET_PARAM("v_offset", "0");
CKB_PRESET_PARAM("singlecol", "0");
// CKB_PRESET_PARAM("linear", "0");
snprintf(enumstr, sizeof(enumstr), "%1d", (int)CAPTURE_DEV_MONITOR);
CKB_PRESET_PARAM("default_device", enumstr);
CKB_PRESET_END;
CKB_PRESET_START("Spectrum" SRC_STR);
CKB_PRESET_PARAM("trigger", "1");
CKB_PRESET_PARAM("kptrigger", "0");
CKB_PRESET_PARAM("norm_f", "7.5");
CKB_PRESET_PARAM("v_offset", "0");
CKB_PRESET_PARAM("singlecol", "0");
snprintf(enumstr, sizeof(enumstr), "%1d", (int)CAPTURE_DEV_SOURCE);
CKB_PRESET_PARAM("default_device", enumstr);
CKB_PRESET_END;
CKB_PRESET_START("Single Colour");
CKB_PRESET_PARAM("trigger", "0");
CKB_PRESET_PARAM("kptrigger", "1");
CKB_PRESET_START("Spectrum" CST_SRC);
CKB_PRESET_PARAM("trigger", "1");
CKB_PRESET_PARAM("kptrigger", "0");
CKB_PRESET_PARAM("norm_f", "7.5");
CKB_PRESET_PARAM("v_offset", "0");
CKB_PRESET_PARAM("singlecol", "0");
snprintf(enumstr, sizeof(enumstr), "%1d", (int)CAPTURE_DEV_SERVER);
CKB_PRESET_PARAM("default_device", enumstr);
CKB_PRESET_END;
// Single Colour
CKB_PRESET_START("Single Colour" MON_STR);
CKB_PRESET_PARAM("trigger", "1");
CKB_PRESET_PARAM("kptrigger", "0");
CKB_PRESET_PARAM("norm_f", "7.5");
CKB_PRESET_PARAM("v_offset", "0");
CKB_PRESET_PARAM("singlecol", "1");
snprintf(enumstr, sizeof(enumstr), "%1d", (int)CAPTURE_DEV_MONITOR);
CKB_PRESET_PARAM("default_device", enumstr);
CKB_PRESET_END;
CKB_PRESET_START("Single Colour" SRC_STR);
CKB_PRESET_PARAM("trigger", "1");
CKB_PRESET_PARAM("kptrigger", "0");
CKB_PRESET_PARAM("norm_f", "7.5");
CKB_PRESET_PARAM("v_offset", "0");
CKB_PRESET_PARAM("singlecol", "1");
snprintf(enumstr, sizeof(enumstr), "%1d", (int)CAPTURE_DEV_SOURCE);
CKB_PRESET_PARAM("default_device", enumstr);
CKB_PRESET_END;
CKB_PRESET_START("Single Colour" CST_SRC);
CKB_PRESET_PARAM("trigger", "1");
CKB_PRESET_PARAM("kptrigger", "0");
CKB_PRESET_PARAM("norm_f", "7.5");
CKB_PRESET_PARAM("v_offset", "0");
CKB_PRESET_PARAM("singlecol", "1");
snprintf(enumstr, sizeof(enumstr), "%1d", (int)CAPTURE_DEV_SERVER);
CKB_PRESET_PARAM("default_device", enumstr);
CKB_PRESET_END;
}
double powers[1024] = { 0.0 };
double hann_res[2048] = { 0.0 };
kiss_fft_cfg config;
kiss_fft_cpx inbuf[2048] = { 0 };
kiss_fft_cpx outbuf[2048] = { 0 };
ckb_gradient color = { 0 };
unsigned char bg_a, bg_r, bg_g, bg_b;
void destroyCapture(){
if(stream == NULL)
return;
#ifdef USE_PORTAUDIO
Pa_CloseStream(stream);
#else
pa_simple_free(stream);
#if 0
static void mviz_destroy_capture(){
if(pa_str){
pa_stream_disconnect(pa_str);
pa_stream_unref(pa_str);
}
if(pa_ctx){
pa_context_disconnect(pa_ctx);
pa_context_unref(pa_ctx);
}
if(pa_ml)
pa_mainloop_free(pa_ml);
pa_str = pa_ctx = pa_ml = NULL;
}
#endif
stream = NULL;
static void pa_state_cb(pa_context* ctx, void* userdata) {
pa_context_state_t* pa_state_p = userdata;
*pa_state_p = pa_context_get_state(ctx);
}
void initCapture(){
if(stream != NULL)
return;
#ifdef USE_PORTAUDIO
PaStreamParameters inputParams;
PaError err;
static void pa_read_cb(pa_stream* p, size_t nbytes, void* userdata){
size_t datasz = 0;
size_t* effective_data = userdata;
const float* dataptr;
if(devid > -1 && devid < Pa_GetDeviceCount())
inputParams.device = devid;
else
inputParams.device = Pa_GetDefaultInputDevice();
pa_stream_peek(p, (const void**)&dataptr, &datasz);
if(dataptr && datasz){
kiss_fft_cpx inbuf[FFT_SIZE] = { 0 };
kiss_fft_cpx outbuf[FFT_SIZE];
const PaDeviceInfo* inputInfo = Pa_GetDeviceInfo(inputParams.device);
fprintf(stderr, "Recording from %s", inputInfo->name);
// If we get too many samples, ignore the extra ones
const size_t samples = datasz / sizeof(*dataptr) > FFT_SIZE ? FFT_SIZE : datasz / sizeof(*dataptr);
inputParams.channelCount = 1;
inputParams.sampleFormat = paInt16;
inputParams.suggestedLatency = inputInfo->defaultLowInputLatency;
inputParams.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(&stream, &inputParams, NULL, 44100, 2048, paNoFlag, NULL, NULL);
if(err != paNoError)
fprintf(stderr, "Error opening PortAudio stream %d\n", err);
err = Pa_StartStream(stream);
if(err != paNoError)
fprintf(stderr, "Error starting PortAudio stream %d\n", err);
for(size_t i = 0; i < samples; i++){
inbuf[i].r = dataptr[i] * hann_res[i];
//inbuf[i].i = 0;
}
kiss_fft(config, inbuf, outbuf);
// FFT is symmetric because there are no imaginary elements
*effective_data = samples / 2;
for(size_t i = 0; i < *effective_data; i++)
powers[i] = sqrtf(outbuf[i].r * outbuf[i].r + outbuf[i].i * outbuf[i].i);
} else {
*effective_data = 0;
}
pa_stream_drop(p);
}
static void server_info_cb(pa_context* c, const pa_server_info* i, void* userdata){
server_info_cb_data* cb_data = userdata;
int major, minor, patch;
// We have to check for PipeWire since it currently doesn't know what to do with "@DEFAULT_MONITOR@"
// When these old PW versions become irrelevant, this entire callback can be removed, and the switch in the else block
// can be moved to the init capture function.
// FIXME: Add the version of PW the bug was fixed in
#if 0
#define PIPEWIRE_BUG_FIX_VER (major == 0 && minor <= 3 && patch < 57)
#else
static const pa_sample_spec ss ={
.format = PA_SAMPLE_S16LE,
.rate = 44100,
.channels = 1
};
stream = pa_simple_new(NULL, "CKB Music Viz", PA_STREAM_RECORD, NULL, "CKB Music Viz", &ss, NULL, NULL, NULL);
#define PIPEWIRE_BUG_FIX_VER 1
#endif
if(sscanf(i->server_name, "PulseAudio (on PipeWire %d.%d.%d)", &major, &minor, &patch) == 3 && PIPEWIRE_BUG_FIX_VER){
DBG("Applying workaround for PipeWire %d.%d.%d", major, minor, patch);
switch(default_device){
case CAPTURE_DEV_MONITOR:
cb_data->dev = malloc(strlen(i->default_sink_name) + strlen(".monitor") + 1);
sprintf(cb_data->dev, "%s.monitor", i->default_sink_name);
break;
case CAPTURE_DEV_SOURCE:
cb_data->dev = strdup(i->default_source_name);
break;
case CAPTURE_DEV_SERVER:
break;
default:
abort();
}
} else {
const char* dev;
switch(default_device){
case CAPTURE_DEV_MONITOR:
dev = "@DEFAULT_MONITOR@";
break;
case CAPTURE_DEV_SOURCE:
dev = "@DEFAULT_SOURCE@";
break;
case CAPTURE_DEV_SERVER:
dev = NULL;
break;
default:
abort();
}
if(dev)
cb_data->dev = strdup(dev);
}
cb_data->ok = true;
}
static bool mviz_init_capture(){
if(!pa_ml)
pa_ml = pa_mainloop_new();
if(!pa_ctx){
pa_ctx = pa_context_new(pa_mainloop_get_api(pa_ml), "ckb-next music visualizer");
pa_context_connect(pa_ctx, NULL, 0, NULL);
pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_state);
while(pa_state != PA_CONTEXT_FAILED && pa_state != PA_CONTEXT_TERMINATED && pa_state != PA_CONTEXT_READY)
pa_mainloop_iterate(pa_ml, 1, NULL);
if (pa_state != PA_CONTEXT_READY){
pa_context_disconnect(pa_ctx);
pa_context_unref(pa_ctx);
pa_ctx = NULL;
pa_state = PA_CONTEXT_UNCONNECTED;
return true;
}
}
if(!pa_str){
static_assert(sizeof(float) == 4, "Expected 32 bit floats");
static const pa_sample_spec ss = {
.format = PA_SAMPLE_FLOAT32LE,
.rate = 48000,
.channels = 1
};
pa_proplist* pl = pa_proplist_new();
pa_proplist_sets(pl, PA_PROP_APPLICATION_ICON_NAME, "ckb-next");
pa_proplist_sets(pl, PA_PROP_APPLICATION_NAME, "ckb-next");
DBG("New PA capture stream");
pa_str = pa_stream_new_with_proplist(pa_ctx, "capture", &ss, NULL, pl);
pa_proplist_free(pl);
pa_buffer_attr bufattr = {
.maxlength = (uint32_t)-1,
};
bufattr.fragsize = pa_usec_to_bytes(MAX_LATENCY, &ss);
server_info_cb_data cb_data = {
.dev = NULL,
.ok = false
};
pa_context_get_server_info(pa_ctx, server_info_cb, &cb_data);
while(!cb_data.ok)
pa_mainloop_iterate(pa_ml, 1, NULL);
DBG("Capture dev: %s", cb_data.dev ? cb_data.dev : "null");
pa_stream_connect_record(pa_str, cb_data.dev, &bufattr, PA_STREAM_ADJUST_LATENCY);
free(cb_data.dev);
pa_stream_set_read_callback(pa_str, pa_read_cb, &actual_fft_size);
}
return false;
}
void ckb_init(ckb_runctx* context){
config = kiss_fft_alloc(2048, 0, NULL, NULL);
key_lit = calloc(context->keycount, sizeof(*key_lit));
config = kiss_fft_alloc(FFT_SIZE, 0, NULL, NULL);
#ifdef USE_PORTAUDIO
#ifdef __linux__
putenv("PULSE_LATENCY_MSEC=90");
#endif
PaError err = Pa_Initialize();
if(err != paNoError){
fprintf(stderr, "Error initialising PortAudio %d\n", err);
}
#else
// We do not need to wait for the device id on pulseaudio
initCapture();
#endif
for (int i = 0; i < FFT_SIZE; i++)
hann_res[i] = (1.f - cosf(2.f * M_PI_F * i / (float)(FFT_SIZE-1))) * 0.5f;
}
for (int i = 0; i < 2048; i++)
hann_res[i] = (1 - cos(2 * M_PI * i / 2048)) * 0.5;
static void stream_state_cb(pa_stream* s, void* userdata) {
(*(pa_stream_state_t*)userdata) = pa_stream_get_state(s);
}
void ckb_parameter(ckb_runctx* context, const char* name, const char* value){
CKB_PARSE_AGRADIENT("color", &color){};
CKB_PARSE_LONG("v_offset", &v_offset){};
CKB_PARSE_DOUBLE("norm_f", &norm_f){
norm_f /= 100;
norm_f /= 120.0;
};
CKB_PARSE_DOUBLE("div_fact", &div_fact){
div_fact = 101 - div_fact;
div_fact *= 100000.0;
div_fact = (101.0 - div_fact) * 12.0;
};
CKB_PARSE_AGRADIENT("color", &color){};
CKB_PARSE_ARGB("bgcolour", &bg_a, &bg_r, &bg_g, &bg_b){};
CKB_PARSE_LONG("range", &range){};
CKB_PARSE_BOOL("singlecol", &single_colour){};
CKB_PARSE_LONG("default_device", &default_device){
// If we have an existing stream, destroy it and recreate it
if(pa_str && old_default_device != default_device){
DBG("Disconnecting PA stream");
// pa_stream_disconnect sometimes randomly fails with -15, so if that happens, keep retrying...
// If we don't do this, we'll end up with multiple streams that have not been cleaned up
pa_stream_state_t state = PA_STREAM_READY;
pa_stream_set_state_callback(pa_str, stream_state_cb, &state);
int disconnect = pa_stream_disconnect(pa_str);
// CKB_PARSE_BOOL("linear", &linear){};
while(state == PA_STREAM_READY){
DBG("Stream state: %d", state);
pa_mainloop_iterate(pa_ml, 1, NULL);
if(disconnect == -PA_ERR_BADSTATE){
DBG("pa_stream_disconnect() returned Bad State. Retrying after loop iteration...");
disconnect = pa_stream_disconnect(pa_str);
}
}
#ifdef USE_PORTAUDIO
CKB_PARSE_LONG("devid", &devid){
// 0 is considered a valid value for portaudio, we use 0 for default
devid -= 1;
// If we were already running, close the previous stream
destroyCapture();
// Create a new stream
initCapture();
pa_stream_unref(pa_str);
pa_str = NULL;
mviz_init_capture();
old_default_device = default_device;
}
};
#endif
}
void ckb_keypress(ckb_runctx* context, ckb_key* key, int x, int y, int state){
@@ -206,85 +380,109 @@ void ckb_keypress(ckb_runctx* context, ckb_key* key, int x, int y, int state){
}
void ckb_start(ckb_runctx* context, int state){
return;
mviz_init_capture();
}
void ckb_time(ckb_runctx* context, double delta){
return;
ckb_key* keys = context->keys;
for(unsigned int i = 0; i < context->keycount; i++){
unsigned int sub = round(delta*50.0*(context->height-keys[i].y+10));
if(key_lit[i] >= sub)
key_lit[i] -= sub;
else
key_lit[i] = 0;
}
}
void getFreqDec(){
int16_t data[2048] = { 0 };
#define BIN_FN (height * ((translated_frame[bin]) / (float)div_fact) * ((float)norm_f * (i + 1) + 2))
// If we want to average
// (height * ((translated_frame[bin] / step) / (float)div_fact) * ((float)norm_f * (i + 1) + 2))
static size_t lin_to_log(unsigned int height)
{
size_t bin = 0;
size_t step = 1;
size_t i;
for(i = 1; i <= actual_fft_size; i++) {
if(stream == NULL)
return;
if(powers[i - 1] > translated_frame[bin])
translated_frame[bin] = powers[i - 1];
// If we want to average
//translated_frame[bin] += powers[i - 1];
#ifdef USE_PORTAUDIO
Pa_ReadStream(stream, data, 2048);
#else
pa_simple_read(stream, data, sizeof(data), NULL);
#endif
// Runs every time a multiple of step is hit
if(!(i % step))
{
// Scale it to the height of the device
translated_frame[bin] = BIN_FN;
bin++;
}
for(int i = 0; i < 2048; i++){
inbuf[i].r = data[i] * hann_res[i];
inbuf[i].i = 0;
// Check if we have to change the step
// The loop starts from 1 so that this doesn't trigger on 0
if (!(i % (step * 10)))
step *= 10;
}
kiss_fft(config, inbuf, outbuf);
translated_frame[bin] = BIN_FN;
for(int j = 0; j < 1024; j++)
powers[j] = sqrt(outbuf[j].r*outbuf[j].r + outbuf[j].i*outbuf[j].i);
//DBG("Total number of bins %zu\n", bin);
return bin + 1;
}
void translate_frame_vertically(int height){
for(int i = 0; i < range; i++)
translated_frame[i] = round(height * (powers[i]/(div_fact * 3)) * (norm_f * (i + 1) + 2));
}
int get_key_value(int width, int x){
int cur_pos = range * x / width;
cur_pos = (cur_pos > range - 1 ? range - 1 : cur_pos);
int newval = translated_frame[cur_pos];
// Each key takes 18 nearby values from the array
// Pick the largest one for this key.
if(cur_pos > 17){
for(int i = 0; i < 18; i++)
if(translated_frame[cur_pos - i] > newval)
newval = translated_frame[cur_pos - i];
}
static inline float get_key_value(unsigned int width, int x, size_t bins){
size_t cur_pos = bins * x / width;
cur_pos = (cur_pos > bins - 1 ? 1 - 1 : cur_pos);
float newval = translated_frame[cur_pos];
// Check this position and one nearby one, and pick the max
if(cur_pos > 0 && translated_frame[cur_pos - 1] > newval)
newval = translated_frame[cur_pos - 1];
return newval;
}
void grad_to_key(ckb_runctx* context, ckb_key* key, int key_y){
// Get colour for this key
// Map the LEDs to the gradient, bottom (0) is at 0%, top (height) is at 100%
float key_colour = (100.f / context->height) * key_y;
float a, r, g, b;
ckb_grad_color(&a, &r, &g, &b, &color, key_colour);
key->a = roundf(a);
key->r = roundf(r);
key->g = roundf(g);
key->b = roundf(b);
}
int ckb_frame(ckb_runctx* context){
CKB_KEYCLEAR(context);
// Don't process anything if the main loop hasn't been initialised yet
if(!pa_ml)
return 0;
if(pa_state == PA_CONTEXT_FAILED){
if(pa_str){
pa_stream_disconnect(pa_str);
pa_stream_unref(pa_str);
}
if(pa_ctx){
pa_context_disconnect(pa_ctx);
pa_context_unref(pa_ctx);
}
pa_str = NULL;
pa_ctx = NULL;
pa_state = PA_CONTEXT_UNCONNECTED;
clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_sec = 1}, NULL);
mviz_init_capture();
}
if(pa_state != PA_CONTEXT_READY)
return 0;
for(int i = 0; i < 5 && pa_mainloop_iterate(pa_ml, 0, NULL) > 0; i++)
clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = 500000}, NULL);
ckb_key* keys = context->keys;
ckb_key* maxkey = keys + context->keycount;
getFreqDec();
memset(translated_frame, 0, sizeof(translated_frame));
if(single_colour){
translate_frame_vertically(100);
CKB_KEYCLEAR(context);
const size_t bins = lin_to_log(100);
// Find the max value
int max_light = translated_frame[0];
for(int i = 0; i < range; i++)
float max_light = translated_frame[0];
for(size_t i = 0; i < bins; i++)
if(translated_frame[i] > max_light)
max_light = translated_frame[i];
float a, r, g, b;
ckb_grad_color(&a, &r, &g, &b, &color, max_light);
for(ckb_key* key = keys; key < maxkey; key++){
// TODO DEDUP
key->a = roundf(a);
key->r = roundf(r);
key->g = roundf(g);
@@ -294,13 +492,24 @@ int ckb_frame(ckb_runctx* context){
return 0;
}
const size_t bins = lin_to_log(context->height);
for(ckb_key* key = keys; key < maxkey; key++){
translate_frame_vertically(context->height);
int key_y = context->height - key->y;
// Blank out the key if it is not supposed to be on
if(key_y + v_offset <= get_key_value(context->width, key->x)){
grad_to_key(context, key, key_y);
} else {
// If the key is supposed to be on, light it up and reset its counter
// If the key's counter is 0, then turn it off
if(key_y + v_offset <= get_key_value(context->width, key->x, bins)){
// Get colour for this key
// Map the LEDs to the gradient, bottom (0) is at 0%, top (height) is at 100%
float key_colour = (100.f / context->height) * key_y;
float a, r, g, b;
ckb_grad_color(&a, &r, &g, &b, &color, key_colour);
key->a = roundf(a);
key->r = roundf(r);
key->g = roundf(g);
key->b = roundf(b);
key_lit[key - keys] = 200;
} else if(key_lit[key - keys] == 0){
key->a = bg_a;
key->r = bg_r;
key->g = bg_g;
+7 -4
View File
@@ -18,10 +18,10 @@
#define BRAGI_BRIGHTNESS 0x02
#define BRAGI_MODE 0x03
#define BRAGI_ANGLE_SNAP 0x07
#define BRAG_APP_VER 0x13
#define BRAG_BLD_VER 0x14
#define BRAG_RADIO_APP_VER 0x15
#define BRAG_RADIO_BLD_VER 0x16
#define BRAGI_APP_VER 0x13
#define BRAGI_BLD_VER 0x14
#define BRAGI_RADIO_APP_VER 0x15
#define BRAGI_RADIO_BLD_VER 0x16
#define BRAGI_DPI_INDEX 0x1E
#define BRAGI_DPI_MASK 0x1F
#define BRAGI_DPI_X 0x21
@@ -30,6 +30,8 @@
#define BRAGI_DPI1_COLOR 0x30
#define BRAGI_DPI2_COLOR 0x31
#define BRAGI_HWLAYOUT 0x41
#define BRAGI_BRIGHTNESS_COARSE 0x44
// Untested. Only known because CUE complained about it in its logs
#define BRAGI_MAX_POLLRATE 0x96
@@ -56,6 +58,7 @@
// Resources (used to get handles)
#define BRAGI_RES_LIGHTING 0x01
#define BRAGI_RES_LIGHTING_MONOCHROME 0x10
#define BRAGI_RES_PAIRINGID 0x05
// ckb-specific macros
+14 -5
View File
@@ -75,7 +75,10 @@ static int setactive_bragi(usbdevice* kb, int active){
}
// The daemon will always send RGB data through handle 0 (), so go ahead and open it
int light = bragi_open_handle(kb, BRAGI_LIGHTING_HANDLE, BRAGI_RES_LIGHTING);
uchar res = BRAGI_RES_LIGHTING;
if(IS_MONOCHROME_DEV(kb))
res = BRAGI_RES_LIGHTING_MONOCHROME;
int light = bragi_open_handle(kb, BRAGI_LIGHTING_HANDLE, res);
if(light < 0)
return light;
@@ -115,19 +118,19 @@ static int start_bragi_common(usbdevice* kb){
// Read FW versions
kb->fwversion = kb->bldversion = kb->radioappversion = kb->radiobldversion = UINT32_MAX;
prop = bragi_get_property(kb, BRAG_APP_VER);
prop = bragi_get_property(kb, BRAGI_APP_VER);
if(prop >= 0)
kb->fwversion = bragi_fwver_bswap(prop);
prop = bragi_get_property(kb, BRAG_BLD_VER);
prop = bragi_get_property(kb, BRAGI_BLD_VER);
if(prop >= 0)
kb->bldversion = bragi_fwver_bswap(prop);
prop = bragi_get_property(kb, BRAG_RADIO_APP_VER);
prop = bragi_get_property(kb, BRAGI_RADIO_APP_VER);
if(prop >= 0)
kb->radioappversion = bragi_fwver_bswap(prop);
prop = bragi_get_property(kb, BRAG_RADIO_BLD_VER);
prop = bragi_get_property(kb, BRAGI_RADIO_BLD_VER);
if(prop >= 0)
kb->radiobldversion = bragi_fwver_bswap(prop);
@@ -146,6 +149,12 @@ static int start_bragi_common(usbdevice* kb){
kb->usbdelay = USB_DELAY_DEFAULT;
// Check if the device supports fine or coarse brightness
if(bragi_get_property(kb, BRAGI_BRIGHTNESS) >= 0)
kb->brightness_mode = BRIGHTNESS_HARDWARE_FINE;
else if(bragi_get_property(kb, BRAGI_BRIGHTNESS_COARSE) >= 0)
kb->brightness_mode = BRIGHTNESS_HARDWARE_COARSE;
// Read pairing ID
if(IS_WIRELESS_DEV(kb)){
int pair = bragi_open_handle(kb, BRAGI_GENERIC_HANDLE, BRAGI_RES_PAIRINGID);
+4
View File
@@ -339,6 +339,10 @@ static int _mkdevpath(usbdevice* kb){
if(HAS_FEATURES(kb, FEAT_BATTERY))
fputs(" battery", ffile);
if(kb->brightness_mode == BRIGHTNESS_HARDWARE_COARSE)
fputs(" hwbright_coarse", ffile);
else if(kb->brightness_mode == BRIGHTNESS_HARDWARE_FINE)
fputs(" hwbright_fine", ffile);
fputc('\n', ffile);
fclose(ffile);
check_chmod(fpath, S_GID_READ);
+15 -6
View File
@@ -71,16 +71,25 @@ static int updatergb_bragi(usbdevice* kb, int force, const size_t led_offset){
int laston = memcmp(lastlight->r + led_offset, pkt, CPY_SZ(r)) ||
memcmp(lastlight->g + led_offset, pkt, CPY_SZ(g)) ||
memcmp(lastlight->b + led_offset, pkt, CPY_SZ(b));
if (newon != laston || force)
bragi_set_property(kb, BRAGI_BRIGHTNESS, newon ? 1000 : 0);
if (newon != laston || force){
if(kb->brightness_mode == BRIGHTNESS_HARDWARE_COARSE)
bragi_set_property(kb, BRAGI_BRIGHTNESS_COARSE, newon ? 3 : 0);
else if(kb->brightness_mode == BRIGHTNESS_HARDWARE_FINE)
bragi_set_property(kb, BRAGI_BRIGHTNESS, newon ? 1000 : 0);
}
static_assert(sizeof(pkt) >= 7 + N_KEYS_EXTENDED * 3, "Bragi RGB packet must be large enough to fit all possible zones in the keymap");
memcpy(pkt + 7, newlight->r + led_offset, CPY_SZ(r));
memcpy(pkt + 7 + CPY_SZ(r), newlight->g + led_offset, CPY_SZ(g));
memcpy(pkt + 7 + CPY_SZ(r) + CPY_SZ(g), newlight->b + led_offset, CPY_SZ(b));
size_t bytes = zones;
if(bragi_write_to_handle(kb, pkt, BRAGI_LIGHTING_HANDLE, sizeof(pkt), 3 * zones))
memcpy(pkt + 7, newlight->r + led_offset, CPY_SZ(r));
if(!IS_MONOCHROME_DEV(kb)) {
bytes *= 3; // 3 channels
memcpy(pkt + 7 + CPY_SZ(r), newlight->g + led_offset, CPY_SZ(g));
memcpy(pkt + 7 + CPY_SZ(r) + CPY_SZ(g), newlight->b + led_offset, CPY_SZ(b));
}
if(bragi_write_to_handle(kb, pkt, BRAGI_LIGHTING_HANDLE, sizeof(pkt), bytes))
return 1;
lastlight->forceupdate = newlight->forceupdate = 0;
+5
View File
@@ -378,6 +378,11 @@ typedef struct usbdevice_ {
uchar bragi_in_ep;
uchar wl_pairing_id[PAIR_ID_SIZE];
bool needs_fw_update;
enum {
BRIGHTNESS_SOFTWARE,
BRIGHTNESS_HARDWARE_FINE,
BRIGHTNESS_HARDWARE_COARSE,
} brightness_mode;
} usbdevice;
#endif // STRUCTURES_H
+7 -2
View File
@@ -46,9 +46,12 @@ const dpi_list mouse_dpi_list[] = {
const device_desc models[] = {
// Keyboards
{ V_CORSAIR, P_K55, },
{ V_CORSAIR, P_K55_PRO, },
{ V_CORSAIR, P_K55_PRO_XT, },
{ V_CORSAIR, P_K60_PRO_RGB, },
{ V_CORSAIR, P_K60_PRO_RGB_LP, },
{ V_CORSAIR, P_K60_PRO_RGB_SE, },
{ V_CORSAIR, P_K60_PRO_MONO, },
{ V_CORSAIR, P_K63_NRGB, },
{ V_CORSAIR, P_K63_NRGB_WL, },
{ V_CORSAIR, P_K63_NRGB_WL2, },
@@ -200,12 +203,14 @@ const char* product_str(ushort product){
return "k63";
if(product == P_K63_NRGB_WL || product == P_K63_NRGB_WL2 || product == P_K63_NRGB_WL3 || product == P_K63_NRGB_WL4)
return "k63_wireless";
if(product == P_K60_PRO_RGB || product == P_K60_PRO_RGB_LP || product == P_K60_PRO_RGB_SE)
if(product == P_K60_PRO_RGB || product == P_K60_PRO_RGB_LP || product == P_K60_PRO_RGB_SE || product == P_K60_PRO_MONO)
return "k60";
if(product == P_K57_U || product == P_K57_D)
if(product == P_K57_U || product == P_K57_D || product == P_K55_PRO_XT)
return "k57_wireless";
if(product == P_K55)
return "k55";
if(product == P_K55_PRO)
return "k55pro";
if(product == P_STRAFE || product == P_STRAFE_NRGB || product == P_STRAFE_NRGB_2)
return "strafe";
if(product == P_STRAFE_MK2)
+4 -3
View File
@@ -47,6 +47,7 @@
#define P_K55_PRO_XT 0x1ba1
#define IS_K55(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K55 || (kb)->product == P_K55_PRO || (kb)->product == P_K55_PRO_XT))
#define P_K57_D 0x1b62
#define P_K57_U 0x1b6e
@@ -211,7 +212,7 @@ const char* product_str(ushort product);
/// The difference between non RGB and monochrome is, that monochrome has lights, but just in one color.
/// nonRGB has no lights.
/// Change this if new \b monochrome devices are added
#define IS_MONOCHROME(vendor, product) ((vendor) == (V_CORSAIR) && ((product) == (P_K63_NRGB) || (product) == (P_K63_NRGB_WL) || (product) == (P_K63_NRGB_WL2) || (product) == (P_K63_NRGB_WL3) || (product) == (P_K63_NRGB_WL4) || (product) == (P_K68_NRGB) || (product) == (P_STRAFE_NRGB) || (product) == (P_STRAFE_NRGB_2)))
#define IS_MONOCHROME(vendor, product) ((vendor) == (V_CORSAIR) && ((product) == (P_K63_NRGB) || (product) == (P_K63_NRGB_WL) || (product) == (P_K63_NRGB_WL2) || (product) == (P_K63_NRGB_WL3) || (product) == (P_K63_NRGB_WL4) || (product) == (P_K68_NRGB) || (product) == (P_STRAFE_NRGB) || (product) == (P_STRAFE_NRGB_2) || (product) == (P_K60_PRO_MONO)))
/// For calling with a usbdevice*, vendor and product are extracted and IS_LEGACY() is returned.
#define IS_LEGACY_DEV(kb) IS_LEGACY((kb)->vendor, (kb)->product)
@@ -265,13 +266,13 @@ const char* product_str(ushort product);
#define USES_FILE_HWSAVE(kb) ((kb)->product == P_K95_PLATINUM || (kb)->product == P_K70_MK2 || (kb)->product == P_K70_MK2SE || (kb)->product == P_STRAFE_MK2 || (kb)->product == P_GLAIVE || (kb)->product == P_SCIMITAR_PRO || (kb)->product == P_SCIMITAR_ELITE || (kb)->product == P_K70_MK2LP || (kb)->product == P_M65_RGB_ELITE || (kb)->product == P_IRONCLAW || (kb)->product == P_HARPOON_PRO || IS_K63_WL(kb) || IS_DARK_CORE_NXP(kb) || (kb)->product == P_IRONCLAW_W_U || (kb)->product == P_IRONCLAW_W_D || (kb)->product == P_NIGHTSWORD)
/// Devices here support setting the pollrate through software
#define SUPPORTS_ADJRATE(kb) ((kb)->product == P_K60_PRO_RGB || (kb)->product == P_K60_PRO_RGB_LP || (kb)->product == P_K60_PRO_RGB_SE || (kb)->product == P_K63_NRGB || (kb)->product == P_K66 || (kb)->product == P_K68 || (kb)->product == P_K68_NRGB || (kb)->product == P_K70_MK2 || (kb)->product == P_K70_MK2SE || (kb)->product == P_K70_MK2LP || (kb)->product == P_K95_PLATINUM || (kb)->product == P_STRAFE || (kb)->product == P_STRAFE_NRGB || (kb)->product == P_STRAFE_NRGB_2 || (kb)->product == P_STRAFE_MK2 || (kb)->product == P_M55_RGB_PRO || (kb)->product == P_M65 || (kb)->product == P_M65_PRO || (kb)->product == P_M65_RGB_ELITE || (kb)->product == P_M95 || (kb)->product == P_SABRE_O || (kb)->product == P_SABRE_L || (kb)->product == P_SABRE_N || (kb)->product == P_SABRE_O2 || (kb)->product == P_SCIMITAR || (kb)->product == P_SCIMITAR_ELITE || (kb)->product == P_SCIMITAR_PRO || (kb)->product == P_HARPOON || (kb)->product == P_HARPOON_PRO || (kb)->product == P_GLAIVE || (kb)->product == P_KATAR || (kb)->product == P_KATAR_PRO_XT || (kb)->product == P_KATAR_PRO || (kb)->product == P_NIGHTSWORD || IS_DARK_CORE_NXP(kb) || (kb)->product == P_K95_PLATINUM_XT || (kb)->product == P_GLAIVE_PRO)
#define SUPPORTS_ADJRATE(kb) ((kb)->product == P_K60_PRO_RGB || (kb)->product == P_K60_PRO_MONO || (kb)->product == P_K60_PRO_RGB_LP || (kb)->product == P_K60_PRO_RGB_SE || (kb)->product == P_K63_NRGB || (kb)->product == P_K66 || (kb)->product == P_K68 || (kb)->product == P_K68_NRGB || (kb)->product == P_K70_MK2 || (kb)->product == P_K70_MK2SE || (kb)->product == P_K70_MK2LP || (kb)->product == P_K95_PLATINUM || (kb)->product == P_STRAFE || (kb)->product == P_STRAFE_NRGB || (kb)->product == P_STRAFE_NRGB_2 || (kb)->product == P_STRAFE_MK2 || (kb)->product == P_M55_RGB_PRO || (kb)->product == P_M65 || (kb)->product == P_M65_PRO || (kb)->product == P_M65_RGB_ELITE || (kb)->product == P_M95 || (kb)->product == P_SABRE_O || (kb)->product == P_SABRE_L || (kb)->product == P_SABRE_N || (kb)->product == P_SABRE_O2 || (kb)->product == P_SCIMITAR || (kb)->product == P_SCIMITAR_ELITE || (kb)->product == P_SCIMITAR_PRO || (kb)->product == P_HARPOON || (kb)->product == P_HARPOON_PRO || (kb)->product == P_GLAIVE || (kb)->product == P_KATAR || (kb)->product == P_KATAR_PRO_XT || (kb)->product == P_KATAR_PRO || (kb)->product == P_NIGHTSWORD || IS_DARK_CORE_NXP(kb) || (kb)->product == P_K95_PLATINUM_XT || (kb)->product == P_GLAIVE_PRO || (kb)->product == P_K55_PRO || (kb)->product == P_K55_PRO_XT)
// Bragi devices that use macros for media keys. Currently used to apply a terrible workaround.
#define BRAGI_HAS_MEDIA_MACRO(kb) (IS_K60PRORGB(kb))
// Devices that have volume wheels (or don't)
#define DEV_HAS_VOLWHEEL(kb) (!(IS_K65(kb) || IS_K63(kb) || (kb)->product == P_K57_U || BRAGI_HAS_MEDIA_MACRO(kb)))
#define DEV_HAS_VOLWHEEL(kb) (!(IS_K65(kb) || IS_K63(kb) || (kb)->product == P_K57_U || IS_K55(kb) || BRAGI_HAS_MEDIA_MACRO(kb)))
// Devices that use the NXP protocol and have the DPI stage RGB data in the DPI packet
#define NXP_RGB_IN_DPI_PKT(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_GLAIVE_PRO || IS_DARK_CORE_NXP(kb)))
+2
View File
@@ -28,6 +28,8 @@ void bragi_fill_input_eps(usbdevice* kb)
kb->bragi_in_ep = 0x82;
break;
case P_K57_U:
case P_K55_PRO:
case P_K55_PRO_XT:
kb->bragi_out_ep = 0x1;
kb->bragi_in_ep = 0x82;
break;
+2
View File
@@ -344,6 +344,8 @@ void Kb::load(){
demoProfile = ":/txt/demoprofile_st100.ini";
else if(map.model() == KeyMap::NIGHTSWORD)
demoProfile = ":/txt/demoprofile_nightsword.ini";
else if(map.model() == KeyMap::K55PRO)
demoProfile = ":/txt/demoprofile_k55pro.ini";
QSettings demoSettings(demoProfile, QSettings::IniFormat, this);
CkbDemoSettings cSettings(demoSettings);
KbProfile* demo = new KbProfile(this, map, cSettings, "{BA7FC152-2D51-4C26-A7A6-A036CC93D924}");
+2 -2
View File
@@ -108,12 +108,12 @@ void KbLightWidget::newSelection(const QStringList& selection){
ui->selLabel->setText(tr("Click to select"));
} else if(count == 1) {
// This is done this way to aid translation
if(!light->map().isKeyboard() || light->map().model() == KeyMap::K55)
if(!light->map().isKeyboard() || light->map().model() == KeyMap::K55 || light->map().model() == KeyMap::K55PRO)
ui->selLabel->setText(tr("1 zone selected"));
else
ui->selLabel->setText(tr("1 key selected"));
} else {
if(!light->map().isKeyboard() || light->map().model() == KeyMap::K55)
if(!light->map().isKeyboard() || light->map().model() == KeyMap::K55 || light->map().model() == KeyMap::K55PRO)
ui->selLabel->setText(tr("%1 zones selected").arg(count));
else
ui->selLabel->setText(tr("%1 keys selected").arg(count));
+27
View File
@@ -11,6 +11,9 @@
// K55 Zone Size
#define ZS 97, 75
// K55 PRO Zone Size
#define ZSP 59, 75
// Key positions (K95 - English)
// This is the master key map that includes ANSI, ISO and JP-106 layouts - use patchANSI(), patchISO() or patchJP106() to finalize it
static const Key K95Keys[] = {
@@ -264,6 +267,14 @@ static const Key K55Zones[] = {
};
#define K55_ZONES (sizeof(K55Zones) / sizeof(Key))
static const Key K55PROZones[] = {
{nullptr, "Zone 1", "zone1", 26, 45, ZSP, true, false},
{nullptr, "Zone 2", "zone2", 83, 45, ZSP, true, false},
{nullptr, "Zone 3", "zone3", 140, 45, ZSP, true, false},
{nullptr, "Zone 4", "zone4", 197, 45, ZSP, true, false},
{nullptr, "Zone 5", "zone5", 254, 45, ZSP, true, false},
};
#define K55PRO_ZONES (sizeof(K55PROZones) / sizeof(Key))
// Strafe has side lights
#define KSTRAFE_X_START 12
@@ -1008,6 +1019,15 @@ static QHash<QString, Key> getMap(KeyMap::Model model, KeyMap::Layout layout){
// Done!
break;
}
case KeyMap::K55PRO:{
// Keys are the same as the K55, but has 5 zones instead
map = getMap(KeyMap::K55, layout);
// Overwrite the zones
for(const Key* key = K55PROZones; key < K55PROZones + K55PRO_ZONES; key++)
map[key->name] = *key;
break;
}
case KeyMap::M65:{
// M65 isn't a keyboard; all mouse maps are unique.
for(const Key* key = M65Keys; key < M65Keys + KEYCOUNT_M65; key++){
@@ -1456,6 +1476,8 @@ KeyMap::Model KeyMap::getModel(const QString& name){
return K95L;
if(lower == "glaivepro")
return GLAIVEPRO;
if(lower == "k55pro")
return K55PRO;
return NO_MODEL;
}
@@ -1463,6 +1485,8 @@ QString KeyMap::getModel(KeyMap::Model model){
switch(model){
case K55:
return "k55";
case K55PRO:
return "k55pro";
case K57_WL:
return "k57_wireless";
case K60:
@@ -1557,6 +1581,8 @@ int KeyMap::modelWidth(Model model){
case K95:
case K95L:
return K95_WIDTH;
case K55PRO:
return K95P_WIDTH + 1; // FIXME
case K95P:
case K55:
case K57_WL:
@@ -1593,6 +1619,7 @@ int KeyMap::modelWidth(Model model){
int KeyMap::modelHeight(Model model){
switch(model){
case K55:
case K55PRO:
case K57_WL:
case K63:
case K63_WL:
+1 -1
View File
@@ -413,7 +413,7 @@ void KeyWidget::paintEvent(QPaintEvent*){
drawTopLeftCorner(&decPainter, kx, ky, kw, kh, scale);
} else
decPainter.drawRect(QRectF(kx * scale, ky * scale, kw * scale, kh * scale));
} else if (model == KeyMap::K55)
} else if (model == KeyMap::K55 || model == KeyMap::K55PRO)
decPainter.drawRect(QRectF(x * scale, y * scale, w * scale, h * scale));
else if ((model == KeyMap::K70MK2 || model == KeyMap::STRAFE_MK2) && key.friendlyName() == "Logo 1")
drawLogo(&key, &decPainter, offX , offY, scale);
@@ -0,0 +1,729 @@
[%7BBA7FC152-2D51-4C26-A7A6-A036CC93D924%7D]
0\Binding\KeyMap=K55PRO US
0\Binding\UseRealNames=true
0\Binding\WinLock=false
0\GUID={11C11AE3-3195-4DFC-B8AC-2FEA703414E5}
0\HwModified=2a5c3bfd
0\Lighting\Animations\List={B60A7D3A-AAC6-4676-8471-D602455A1134}
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\BlendMode=Normal
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Keys=zone3, zone1, zone2, zone4, zone5, rwin, bslash_iso, g10, g11, g12, g13, g14, g15, g16, g17, g18, g7, g8, g9, hash, front, wheel, dpi, thumb, back
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Name=Wave
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Opacity=1
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\angle=120
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\color=0:ffff0000 17:ffffff00 33:ff00ff00 50:ff00ffff 67:ff0000ff 83:ffff00ff 100:ffff0000
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\delay=0
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\duration=3
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kpdelay=0
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kpmode=0
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kpmodestop=false
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kprelease=false
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kprepeat=3
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kpstop=0
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\kptrigger=0
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\length=100.000000
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\repeat=3
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\stop=-1
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\symmetric=0
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\Parameters\trigger=1
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\ScriptGuid={E0BBA19E-C328-4C0E-8E3C-A06D5722B4FC}
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\ScriptName=Wave
0\Lighting\Animations\%7BB60A7D3A-AAC6-4676-8471-D602455A1134%7D\UseRealNames=true
0\Lighting\Brightness=0
0\Lighting\KeyMap=K55PRO US
0\Lighting\Keys\0=#ffffff
0\Lighting\Keys\1=#ffffff
0\Lighting\Keys\2=#ffffff
0\Lighting\Keys\3=#ffffff
0\Lighting\Keys\4=#ffffff
0\Lighting\Keys\5=#ffffff
0\Lighting\Keys\6=#ffffff
0\Lighting\Keys\7=#ffffff
0\Lighting\Keys\8=#ffffff
0\Lighting\Keys\9=#ffffff
0\Lighting\Keys\a=#ffffff
0\Lighting\Keys\b=#ffffff
0\Lighting\Keys\back=#ffffff
0\Lighting\Keys\bslash=#ffffff
0\Lighting\Keys\bslash_iso=#ffffff
0\Lighting\Keys\bspace=#ffffff
0\Lighting\Keys\c=#ffffff
0\Lighting\Keys\caps=#ffffff
0\Lighting\Keys\colon=#ffffff
0\Lighting\Keys\comma=#ffffff
0\Lighting\Keys\d=#ffffff
0\Lighting\Keys\del=#ffffff
0\Lighting\Keys\dot=#ffffff
0\Lighting\Keys\down=#ffffff
0\Lighting\Keys\dpi=#ffffff
0\Lighting\Keys\e=#ffffff
0\Lighting\Keys\end=#ffffff
0\Lighting\Keys\enter=#ffffff
0\Lighting\Keys\equal=#ffffff
0\Lighting\Keys\esc=#ffffff
0\Lighting\Keys\f=#ffffff
0\Lighting\Keys\f1=#ffffff
0\Lighting\Keys\f10=#ffffff
0\Lighting\Keys\f11=#ffffff
0\Lighting\Keys\f12=#ffffff
0\Lighting\Keys\f2=#ffffff
0\Lighting\Keys\f3=#ffffff
0\Lighting\Keys\f4=#ffffff
0\Lighting\Keys\f5=#ffffff
0\Lighting\Keys\f6=#ffffff
0\Lighting\Keys\f7=#ffffff
0\Lighting\Keys\f8=#ffffff
0\Lighting\Keys\f9=#ffffff
0\Lighting\Keys\fn=#ffffff
0\Lighting\Keys\front=#ffffff
0\Lighting\Keys\g=#ffffff
0\Lighting\Keys\g1=#ffffff
0\Lighting\Keys\g10=#ffffff
0\Lighting\Keys\g11=#ffffff
0\Lighting\Keys\g12=#ffffff
0\Lighting\Keys\g13=#ffffff
0\Lighting\Keys\g14=#ffffff
0\Lighting\Keys\g15=#ffffff
0\Lighting\Keys\g16=#ffffff
0\Lighting\Keys\g17=#ffffff
0\Lighting\Keys\g18=#ffffff
0\Lighting\Keys\g2=#ffffff
0\Lighting\Keys\g3=#ffffff
0\Lighting\Keys\g4=#ffffff
0\Lighting\Keys\g5=#ffffff
0\Lighting\Keys\g6=#ffffff
0\Lighting\Keys\g7=#ffffff
0\Lighting\Keys\g8=#ffffff
0\Lighting\Keys\g9=#ffffff
0\Lighting\Keys\grave=#ffffff
0\Lighting\Keys\h=#ffffff
0\Lighting\Keys\hash=#ffffff
0\Lighting\Keys\home=#ffffff
0\Lighting\Keys\i=#ffffff
0\Lighting\Keys\ins=#ffffff
0\Lighting\Keys\j=#ffffff
0\Lighting\Keys\k=#ffffff
0\Lighting\Keys\l=#ffffff
0\Lighting\Keys\lalt=#ffffff
0\Lighting\Keys\lbrace=#ffffff
0\Lighting\Keys\lctrl=#ffffff
0\Lighting\Keys\left=#ffffff
0\Lighting\Keys\light=#ffffff
0\Lighting\Keys\lock=#ffffff
0\Lighting\Keys\lshift=#ffffff
0\Lighting\Keys\lwin=#ffffff
0\Lighting\Keys\m=#ffffff
0\Lighting\Keys\m1=#ffffff
0\Lighting\Keys\m2=#ffffff
0\Lighting\Keys\m3=#ffffff
0\Lighting\Keys\minus=#ffffff
0\Lighting\Keys\mr=#ffffff
0\Lighting\Keys\mute=#ffffff
0\Lighting\Keys\n=#ffffff
0\Lighting\Keys\next=#ffffff
0\Lighting\Keys\num0=#ffffff
0\Lighting\Keys\num1=#ffffff
0\Lighting\Keys\num2=#ffffff
0\Lighting\Keys\num3=#ffffff
0\Lighting\Keys\num4=#ffffff
0\Lighting\Keys\num5=#ffffff
0\Lighting\Keys\num6=#ffffff
0\Lighting\Keys\num7=#ffffff
0\Lighting\Keys\num8=#ffffff
0\Lighting\Keys\num9=#ffffff
0\Lighting\Keys\numdot=#ffffff
0\Lighting\Keys\numenter=#ffffff
0\Lighting\Keys\numlock=#ffffff
0\Lighting\Keys\numminus=#ffffff
0\Lighting\Keys\numplus=#ffffff
0\Lighting\Keys\numslash=#ffffff
0\Lighting\Keys\numstar=#ffffff
0\Lighting\Keys\o=#ffffff
0\Lighting\Keys\p=#ffffff
0\Lighting\Keys\pause=#ffffff
0\Lighting\Keys\pgdn=#ffffff
0\Lighting\Keys\pgup=#ffffff
0\Lighting\Keys\play=#ffffff
0\Lighting\Keys\prev=#ffffff
0\Lighting\Keys\prtscn=#ffffff
0\Lighting\Keys\q=#ffffff
0\Lighting\Keys\quote=#ffffff
0\Lighting\Keys\r=#ffffff
0\Lighting\Keys\ralt=#ffffff
0\Lighting\Keys\rbrace=#ffffff
0\Lighting\Keys\rctrl=#ffffff
0\Lighting\Keys\right=#ffffff
0\Lighting\Keys\rmenu=#ffffff
0\Lighting\Keys\rshift=#ffffff
0\Lighting\Keys\rwin=#ffffff
0\Lighting\Keys\s=#ffffff
0\Lighting\Keys\scroll=#ffffff
0\Lighting\Keys\slash=#ffffff
0\Lighting\Keys\space=#ffffff
0\Lighting\Keys\stop=#ffffff
0\Lighting\Keys\t=#ffffff
0\Lighting\Keys\tab=#ffffff
0\Lighting\Keys\u=#ffffff
0\Lighting\Keys\up=#ffffff
0\Lighting\Keys\v=#ffffff
0\Lighting\Keys\voldn=#ffffff
0\Lighting\Keys\volup=#ffffff
0\Lighting\Keys\w=#ffffff
0\Lighting\Keys\x=#ffffff
0\Lighting\Keys\y=#ffffff
0\Lighting\Keys\z=#ffffff
0\Lighting\Keys\zone1=#ffffff
0\Lighting\Keys\zone2=#ffffff
0\Lighting\Keys\zone3=#ffffff
0\Lighting\Keys\zone4=#ffffff
0\Lighting\Keys\zone5=#ffffff
0\Lighting\UseRealNames=true
0\Modified=6ec7ad79
0\Name=Rainbow
0\Performance\AngleSnap=false
0\Performance\DPI\0=@Point(400 400)
0\Performance\DPI\0RGB=#ffff0000
0\Performance\DPI\1=@Point(450 450)
0\Performance\DPI\1Disabled=false
0\Performance\DPI\1RGB=#ffffc000
0\Performance\DPI\2=@Point(800 800)
0\Performance\DPI\2Disabled=false
0\Performance\DPI\2RGB=#ffffff00
0\Performance\DPI\3=@Point(1500 1500)
0\Performance\DPI\3Disabled=false
0\Performance\DPI\3RGB=#ff00ff00
0\Performance\DPI\4=@Point(3000 3000)
0\Performance\DPI\4Disabled=false
0\Performance\DPI\4RGB=#ff00ffff
0\Performance\DPI\5=@Point(6000 6000)
0\Performance\DPI\5Disabled=false
0\Performance\DPI\5RGB=#ffffffff
0\Performance\DPI\6RGB=#ffc0c0c0
0\Performance\DPI\CurIdx=1
0\Performance\Indicators\0\Enable=false
0\Performance\Indicators\0\Hardware=0
0\Performance\Indicators\0\RGB0=#ff00ff00
0\Performance\Indicators\0\RGB1=#ff000000
0\Performance\Indicators\1\Enable=false
0\Performance\Indicators\1\Hardware=0
0\Performance\Indicators\1\RGB0=#ff00ff00
0\Performance\Indicators\1\RGB1=#ff000000
0\Performance\Indicators\2\Enable=false
0\Performance\Indicators\2\Hardware=0
0\Performance\Indicators\2\RGB0=#ff00ff00
0\Performance\Indicators\2\RGB1=#ff000000
0\Performance\Indicators\3\Enable=true
0\Performance\Indicators\3\RGB0=#00ffffff
0\Performance\Indicators\3\RGB1=#ff000000
0\Performance\Indicators\4\Enable=true
0\Performance\Indicators\4\RGB0=#ffff0000
0\Performance\Indicators\4\RGB1=#ff000000
0\Performance\Indicators\5\Enable=true
0\Performance\Indicators\5\RGB0=#ffff0000
0\Performance\Indicators\5\RGB1=#ffffff00
0\Performance\Indicators\5\RGB2=#ffffffff
0\Performance\Indicators\6\Enable=true
0\Performance\Indicators\6\RGB0=#ffffffff
0\Performance\Indicators\6\RGB1=#ff000000
0\Performance\Indicators\7\Enable=true
0\Performance\Indicators\7\RGB0=#00ffffff
0\Performance\Indicators\7\RGB1=#ff000000
0\Performance\Indicators\7\RGB2=#ff000000
0\Performance\Indicators\DPI=true
0\Performance\LiftHeight=3
0\Performance\MuteDevice=sink
0\WindowInfo\enabled=false
1\Binding\KeyMap=K55PRO US
1\Binding\UseRealNames=true
1\Binding\WinLock=false
1\GUID={982F6B59-8399-4FA6-8AF4-3BC63A62D9AD}
1\HwModified=d6674c5
1\Lighting\Animations\List={9EA4750E-790A-4DCE-90D0-CAAB36CCA693}
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\BlendMode=Normal
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Keys=zone3, zone2, zone4, bslash_iso, hash, front, wheel, dpi, thumb, back
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Name=Breath
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Opacity=1
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\color=0:00ffffff 50:ffffffff 100:00ffffff
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\delay=0
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\duration=5
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kpdelay=0
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kphold=1
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kpmode=0
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kpmodestop=false
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kprelease=false
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kprepeat=5
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kpstop=0
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\kptrigger=0
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\randomize=0
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\repeat=5
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\stop=-1
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\Parameters\trigger=1
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\ScriptGuid={54DD2975-E192-457D-BCFC-D912A24E33B4}
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\ScriptName=Gradient
1\Lighting\Animations\%7B9EA4750E-790A-4DCE-90D0-CAAB36CCA693%7D\UseRealNames=true
1\Lighting\Brightness=0
1\Lighting\KeyMap=K55PRO US
1\Lighting\Keys\0=#ffffff
1\Lighting\Keys\1=#ffffff
1\Lighting\Keys\2=#ffffff
1\Lighting\Keys\3=#ffffff
1\Lighting\Keys\4=#ffffff
1\Lighting\Keys\5=#ffffff
1\Lighting\Keys\6=#ffffff
1\Lighting\Keys\7=#ffffff
1\Lighting\Keys\8=#ffffff
1\Lighting\Keys\9=#ffffff
1\Lighting\Keys\a=#ff0000
1\Lighting\Keys\b=#ff0000
1\Lighting\Keys\back=#ff0000
1\Lighting\Keys\bslash=#ff0000
1\Lighting\Keys\bslash_iso=#ff0000
1\Lighting\Keys\bspace=#ffffff
1\Lighting\Keys\c=#ff0000
1\Lighting\Keys\caps=#ffffff
1\Lighting\Keys\colon=#ff0000
1\Lighting\Keys\comma=#ff0000
1\Lighting\Keys\d=#ff0000
1\Lighting\Keys\del=#ffffff
1\Lighting\Keys\dot=#ff0000
1\Lighting\Keys\down=#ff0000
1\Lighting\Keys\dpi=#ff0000
1\Lighting\Keys\e=#ff0000
1\Lighting\Keys\end=#ffffff
1\Lighting\Keys\enter=#ffffff
1\Lighting\Keys\equal=#ffffff
1\Lighting\Keys\esc=#ffffff
1\Lighting\Keys\f=#ff0000
1\Lighting\Keys\f1=#ffffff
1\Lighting\Keys\f10=#ffffff
1\Lighting\Keys\f11=#ffffff
1\Lighting\Keys\f12=#ffffff
1\Lighting\Keys\f2=#ffffff
1\Lighting\Keys\f3=#ffffff
1\Lighting\Keys\f4=#ffffff
1\Lighting\Keys\f5=#ffffff
1\Lighting\Keys\f6=#ffffff
1\Lighting\Keys\f7=#ffffff
1\Lighting\Keys\f8=#ffffff
1\Lighting\Keys\f9=#ffffff
1\Lighting\Keys\fn=#ffffff
1\Lighting\Keys\front=#ff0000
1\Lighting\Keys\g=#ff0000
1\Lighting\Keys\g1=#ff8080
1\Lighting\Keys\g10=#ff8080
1\Lighting\Keys\g11=#ff8080
1\Lighting\Keys\g12=#ff8080
1\Lighting\Keys\g13=#ff8080
1\Lighting\Keys\g14=#ff8080
1\Lighting\Keys\g15=#ff8080
1\Lighting\Keys\g16=#ff8080
1\Lighting\Keys\g17=#ff8080
1\Lighting\Keys\g18=#ff8080
1\Lighting\Keys\g2=#ff8080
1\Lighting\Keys\g3=#ff8080
1\Lighting\Keys\g4=#ff8080
1\Lighting\Keys\g5=#ff8080
1\Lighting\Keys\g6=#ff8080
1\Lighting\Keys\g7=#ff8080
1\Lighting\Keys\g8=#ff8080
1\Lighting\Keys\g9=#ff8080
1\Lighting\Keys\grave=#ffffff
1\Lighting\Keys\h=#ff0000
1\Lighting\Keys\hash=#ff0000
1\Lighting\Keys\home=#ffffff
1\Lighting\Keys\i=#ff0000
1\Lighting\Keys\ins=#ffffff
1\Lighting\Keys\j=#ff0000
1\Lighting\Keys\k=#ff0000
1\Lighting\Keys\l=#ff0000
1\Lighting\Keys\lalt=#ffffff
1\Lighting\Keys\lbrace=#ff0000
1\Lighting\Keys\lctrl=#ffffff
1\Lighting\Keys\left=#ff0000
1\Lighting\Keys\light=#ffffff
1\Lighting\Keys\lock=#ffffff
1\Lighting\Keys\lshift=#ffffff
1\Lighting\Keys\lwin=#ffffff
1\Lighting\Keys\m=#ff0000
1\Lighting\Keys\m1=#ffffff
1\Lighting\Keys\m2=#ffffff
1\Lighting\Keys\m3=#ffffff
1\Lighting\Keys\minus=#ffffff
1\Lighting\Keys\mr=#ffffff
1\Lighting\Keys\mute=#ffffff
1\Lighting\Keys\n=#ff0000
1\Lighting\Keys\next=#ff8080
1\Lighting\Keys\num0=#ff8080
1\Lighting\Keys\num1=#ff8080
1\Lighting\Keys\num2=#ff8080
1\Lighting\Keys\num3=#ff8080
1\Lighting\Keys\num4=#ff8080
1\Lighting\Keys\num5=#ff8080
1\Lighting\Keys\num6=#ff8080
1\Lighting\Keys\num7=#ff8080
1\Lighting\Keys\num8=#ff8080
1\Lighting\Keys\num9=#ff8080
1\Lighting\Keys\numdot=#ff8080
1\Lighting\Keys\numenter=#ff8080
1\Lighting\Keys\numlock=#ff8080
1\Lighting\Keys\numminus=#ff8080
1\Lighting\Keys\numplus=#ff8080
1\Lighting\Keys\numslash=#ff8080
1\Lighting\Keys\numstar=#ff8080
1\Lighting\Keys\o=#ff0000
1\Lighting\Keys\p=#ff0000
1\Lighting\Keys\pause=#ffffff
1\Lighting\Keys\pgdn=#ffffff
1\Lighting\Keys\pgup=#ffffff
1\Lighting\Keys\play=#ff8080
1\Lighting\Keys\prev=#ff8080
1\Lighting\Keys\prtscn=#ffffff
1\Lighting\Keys\q=#ff0000
1\Lighting\Keys\quote=#ff0000
1\Lighting\Keys\r=#ff0000
1\Lighting\Keys\ralt=#ffffff
1\Lighting\Keys\rbrace=#ff0000
1\Lighting\Keys\rctrl=#ffffff
1\Lighting\Keys\right=#ff0000
1\Lighting\Keys\rmenu=#ffffff
1\Lighting\Keys\rshift=#ffffff
1\Lighting\Keys\rwin=#ffffff
1\Lighting\Keys\s=#ff0000
1\Lighting\Keys\scroll=#ffffff
1\Lighting\Keys\slash=#ff0000
1\Lighting\Keys\space=#ff0000
1\Lighting\Keys\stop=#ff8080
1\Lighting\Keys\t=#ff0000
1\Lighting\Keys\tab=#ffffff
1\Lighting\Keys\thumb=#ff0000
1\Lighting\Keys\u=#ff0000
1\Lighting\Keys\up=#ff0000
1\Lighting\Keys\v=#ff0000
1\Lighting\Keys\voldn=#ffffff
1\Lighting\Keys\volup=#ffffff
1\Lighting\Keys\w=#ff0000
1\Lighting\Keys\wheel=#ff0000
1\Lighting\Keys\x=#ff0000
1\Lighting\Keys\y=#ff0000
1\Lighting\Keys\z=#ff0000
1\Lighting\Keys\zone1=#ffffff
1\Lighting\Keys\zone2=#ff0000
1\Lighting\Keys\zone3=#ff0000
1\Lighting\Keys\zone4=#ff0000
1\Lighting\Keys\zone5=#ffffff
1\Lighting\UseRealNames=true
1\Modified=7e9c7b68
1\Name=Breathing
1\Performance\AngleSnap=false
1\Performance\DPI\0=@Point(400 400)
1\Performance\DPI\0RGB=#ffff0000
1\Performance\DPI\1=@Point(450 450)
1\Performance\DPI\1Disabled=false
1\Performance\DPI\1RGB=#ffffc000
1\Performance\DPI\2=@Point(800 800)
1\Performance\DPI\2Disabled=false
1\Performance\DPI\2RGB=#ffffff00
1\Performance\DPI\3=@Point(1500 1500)
1\Performance\DPI\3Disabled=false
1\Performance\DPI\3RGB=#ff00ff00
1\Performance\DPI\4=@Point(3000 3000)
1\Performance\DPI\4Disabled=false
1\Performance\DPI\4RGB=#ff00ffff
1\Performance\DPI\5=@Point(6000 6000)
1\Performance\DPI\5Disabled=false
1\Performance\DPI\5RGB=#ffffffff
1\Performance\DPI\6RGB=#ffc0c0c0
1\Performance\DPI\CurIdx=1
1\Performance\Indicators\0\Enable=false
1\Performance\Indicators\0\Hardware=0
1\Performance\Indicators\0\RGB0=#ff00ff00
1\Performance\Indicators\0\RGB1=#ff000000
1\Performance\Indicators\1\Enable=false
1\Performance\Indicators\1\Hardware=0
1\Performance\Indicators\1\RGB0=#ff00ff00
1\Performance\Indicators\1\RGB1=#ff000000
1\Performance\Indicators\2\Enable=false
1\Performance\Indicators\2\Hardware=0
1\Performance\Indicators\2\RGB0=#ff00ff00
1\Performance\Indicators\2\RGB1=#ff000000
1\Performance\Indicators\3\Enable=true
1\Performance\Indicators\3\RGB0=#00ffffff
1\Performance\Indicators\3\RGB1=#ff000000
1\Performance\Indicators\4\Enable=true
1\Performance\Indicators\4\RGB0=#ffff0000
1\Performance\Indicators\4\RGB1=#ff000000
1\Performance\Indicators\5\Enable=true
1\Performance\Indicators\5\RGB0=#ffff0000
1\Performance\Indicators\5\RGB1=#ffffff00
1\Performance\Indicators\5\RGB2=#ffffffff
1\Performance\Indicators\6\Enable=true
1\Performance\Indicators\6\RGB0=#ffffffff
1\Performance\Indicators\6\RGB1=#ff000000
1\Performance\Indicators\7\Enable=true
1\Performance\Indicators\7\RGB0=#00ffffff
1\Performance\Indicators\7\RGB1=#ff000000
1\Performance\Indicators\7\RGB2=#ff000000
1\Performance\Indicators\DPI=true
1\Performance\LiftHeight=3
1\Performance\MuteDevice=sink
1\WindowInfo\enabled=false
2\Binding\KeyMap=K55PRO US
2\Binding\UseRealNames=true
2\Binding\WinLock=false
2\GUID={57C94A3A-80E6-4182-B067-6D4A14AD497C}
2\HwModified=417c3862
2\Lighting\Animations\List={51E79A62-3C5C-4732-925C-098499E81A21}, {913D4ABD-246C-4008-9CFB-F4B91CC991F1}
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\BlendMode=Multiply
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Keys=zone3, zone1, zone2, zone4, zone5, rwin, bslash_iso, m1, m2, m3, g10, g11, g12, g13, g14, g15, g16, g17, g18, g7, g8, g9, hash, front, wheel, dpi, thumb, back
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Name=Random
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Opacity=1
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\delay=0
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\duration=0.5
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\fade=0
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\kpdelay=0
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\kpmode=1
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\kpmodestop=false
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\kprelease=false
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\kpstop=-1
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\kptrigger=0
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\stop=-1
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\trigger=1
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\Parameters\useopacity=0
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\ScriptGuid={22418DA4-A181-4B93-A4D3-03682BA283D2}
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\ScriptName=Random
2\Lighting\Animations\%7B51E79A62-3C5C-4732-925C-098499E81A21%7D\UseRealNames=true
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\BlendMode=Add
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Keys=zone3, zone1, zone2, zone4, zone5, rwin, bslash_iso, g10, g11, g12, g13, g14, g15, g16, g17, g18, g7, g8, g9, hash
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Name=Ripple
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Opacity=1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\color=0:ffff007f 100:00ff007f
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\delay=0
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\duration=1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kpdelay=0
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kpmode=0
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kpmodestop=false
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kprelease=false
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kprepeat=1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kpstop=0
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\kptrigger=1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\length=10
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\randomize=0
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\repeat=1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\stop=-1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\symmetric=1
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\trigger=0
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\x_offset=0.000000
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\Parameters\y_offset=0.000000
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\ScriptGuid={097D69F0-70B2-48B8-AFE2-25A1CDB02C9D}
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\ScriptName=Ripple
2\Lighting\Animations\%7B913D4ABD-246C-4008-9CFB-F4B91CC991F1%7D\UseRealNames=true
2\Lighting\Brightness=0
2\Lighting\KeyMap=K55PRO US
2\Lighting\Keys\0=#aa00ff
2\Lighting\Keys\1=#aa00ff
2\Lighting\Keys\2=#aa00ff
2\Lighting\Keys\3=#aa00ff
2\Lighting\Keys\4=#aa00ff
2\Lighting\Keys\5=#aa00ff
2\Lighting\Keys\6=#aa00ff
2\Lighting\Keys\7=#aa00ff
2\Lighting\Keys\8=#aa00ff
2\Lighting\Keys\9=#aa00ff
2\Lighting\Keys\a=#aa00ff
2\Lighting\Keys\b=#aa00ff
2\Lighting\Keys\back=#aa00ff
2\Lighting\Keys\bslash=#aa00ff
2\Lighting\Keys\bslash_iso=#9700ff
2\Lighting\Keys\bspace=#aa00ff
2\Lighting\Keys\c=#aa00ff
2\Lighting\Keys\caps=#aa00ff
2\Lighting\Keys\colon=#9700ff
2\Lighting\Keys\comma=#aa00ff
2\Lighting\Keys\d=#aa00ff
2\Lighting\Keys\del=#aa00ff
2\Lighting\Keys\dot=#aa00ff
2\Lighting\Keys\down=#aa00ff
2\Lighting\Keys\dpi=#aa00ff
2\Lighting\Keys\e=#aa00ff
2\Lighting\Keys\end=#aa00ff
2\Lighting\Keys\enter=#aa00ff
2\Lighting\Keys\equal=#aa00ff
2\Lighting\Keys\esc=#aa00ff
2\Lighting\Keys\f=#aa00ff
2\Lighting\Keys\f1=#aa00ff
2\Lighting\Keys\f10=#aa00ff
2\Lighting\Keys\f11=#aa00ff
2\Lighting\Keys\f12=#aa00ff
2\Lighting\Keys\f2=#aa00ff
2\Lighting\Keys\f3=#aa00ff
2\Lighting\Keys\f4=#aa00ff
2\Lighting\Keys\f5=#aa00ff
2\Lighting\Keys\f6=#aa00ff
2\Lighting\Keys\f7=#aa00ff
2\Lighting\Keys\f8=#aa00ff
2\Lighting\Keys\f9=#aa00ff
2\Lighting\Keys\fn=#ffffff
2\Lighting\Keys\front=#aa00ff
2\Lighting\Keys\g=#aa00ff
2\Lighting\Keys\g1=#aa00ff
2\Lighting\Keys\g10=#aa00ff
2\Lighting\Keys\g11=#aa00ff
2\Lighting\Keys\g12=#aa00ff
2\Lighting\Keys\g13=#aa00ff
2\Lighting\Keys\g14=#aa00ff
2\Lighting\Keys\g15=#aa00ff
2\Lighting\Keys\g16=#aa00ff
2\Lighting\Keys\g17=#aa00ff
2\Lighting\Keys\g18=#aa00ff
2\Lighting\Keys\g2=#aa00ff
2\Lighting\Keys\g3=#aa00ff
2\Lighting\Keys\g4=#aa00ff
2\Lighting\Keys\g5=#aa00ff
2\Lighting\Keys\g6=#aa00ff
2\Lighting\Keys\g7=#aa00ff
2\Lighting\Keys\g8=#aa00ff
2\Lighting\Keys\g9=#aa00ff
2\Lighting\Keys\grave=#aa00ff
2\Lighting\Keys\h=#aa00ff
2\Lighting\Keys\hash=#9700ff
2\Lighting\Keys\home=#aa00ff
2\Lighting\Keys\i=#aa00ff
2\Lighting\Keys\ins=#aa00ff
2\Lighting\Keys\j=#aa00ff
2\Lighting\Keys\k=#aa00ff
2\Lighting\Keys\l=#aa00ff
2\Lighting\Keys\lalt=#aa00ff
2\Lighting\Keys\lbrace=#aa00ff
2\Lighting\Keys\lctrl=#aa00ff
2\Lighting\Keys\left=#aa00ff
2\Lighting\Keys\light=#aa00ff
2\Lighting\Keys\lock=#aa00ff
2\Lighting\Keys\lshift=#aa00ff
2\Lighting\Keys\lwin=#aa00ff
2\Lighting\Keys\m=#aa00ff
2\Lighting\Keys\m1=#aa00ff
2\Lighting\Keys\m2=#aa00ff
2\Lighting\Keys\m3=#aa00ff
2\Lighting\Keys\minus=#aa00ff
2\Lighting\Keys\mr=#aa00ff
2\Lighting\Keys\mute=#aa00ff
2\Lighting\Keys\n=#aa00ff
2\Lighting\Keys\next=#aa00ff
2\Lighting\Keys\num0=#aa00ff
2\Lighting\Keys\num1=#aa00ff
2\Lighting\Keys\num2=#aa00ff
2\Lighting\Keys\num3=#aa00ff
2\Lighting\Keys\num4=#aa00ff
2\Lighting\Keys\num5=#aa00ff
2\Lighting\Keys\num6=#aa00ff
2\Lighting\Keys\num7=#aa00ff
2\Lighting\Keys\num8=#aa00ff
2\Lighting\Keys\num9=#aa00ff
2\Lighting\Keys\numdot=#aa00ff
2\Lighting\Keys\numenter=#aa00ff
2\Lighting\Keys\numlock=#aa00ff
2\Lighting\Keys\numminus=#aa00ff
2\Lighting\Keys\numplus=#aa00ff
2\Lighting\Keys\numslash=#aa00ff
2\Lighting\Keys\numstar=#aa00ff
2\Lighting\Keys\o=#aa00ff
2\Lighting\Keys\p=#aa00ff
2\Lighting\Keys\pause=#aa00ff
2\Lighting\Keys\pgdn=#aa00ff
2\Lighting\Keys\pgup=#aa00ff
2\Lighting\Keys\play=#aa00ff
2\Lighting\Keys\prev=#aa00ff
2\Lighting\Keys\prtscn=#aa00ff
2\Lighting\Keys\q=#aa00ff
2\Lighting\Keys\quote=#aa00ff
2\Lighting\Keys\r=#aa00ff
2\Lighting\Keys\ralt=#aa00ff
2\Lighting\Keys\rbrace=#aa00ff
2\Lighting\Keys\rctrl=#aa00ff
2\Lighting\Keys\right=#aa00ff
2\Lighting\Keys\rmenu=#aa00ff
2\Lighting\Keys\rshift=#aa00ff
2\Lighting\Keys\rwin=#aa00ff
2\Lighting\Keys\s=#aa00ff
2\Lighting\Keys\scroll=#aa00ff
2\Lighting\Keys\slash=#aa00ff
2\Lighting\Keys\space=#aa00ff
2\Lighting\Keys\stop=#aa00ff
2\Lighting\Keys\t=#aa00ff
2\Lighting\Keys\tab=#aa00ff
2\Lighting\Keys\thumb=#aa00ff
2\Lighting\Keys\u=#aa00ff
2\Lighting\Keys\up=#aa00ff
2\Lighting\Keys\v=#aa00ff
2\Lighting\Keys\voldn=#ffffff
2\Lighting\Keys\volup=#ffffff
2\Lighting\Keys\w=#aa00ff
2\Lighting\Keys\wheel=#aa00ff
2\Lighting\Keys\x=#aa00ff
2\Lighting\Keys\y=#aa00ff
2\Lighting\Keys\z=#aa00ff
2\Lighting\Keys\zone1=#a900fe
2\Lighting\Keys\zone2=#a900fe
2\Lighting\Keys\zone3=#a900fe
2\Lighting\Keys\zone4=#a900fe
2\Lighting\Keys\zone5=#a900fe
2\Lighting\UseRealNames=true
2\Modified=191a9162
2\Name=Trippy
2\Performance\AngleSnap=false
2\Performance\DPI\0=@Point(400 400)
2\Performance\DPI\0RGB=#ffff0000
2\Performance\DPI\1=@Point(450 450)
2\Performance\DPI\1Disabled=false
2\Performance\DPI\1RGB=#ff4000ff
2\Performance\DPI\2=@Point(800 800)
2\Performance\DPI\2Disabled=false
2\Performance\DPI\2RGB=#ff8000ff
2\Performance\DPI\3=@Point(1500 1500)
2\Performance\DPI\3Disabled=false
2\Performance\DPI\3RGB=#ffff00ff
2\Performance\DPI\4=@Point(3000 3000)
2\Performance\DPI\4Disabled=false
2\Performance\DPI\4RGB=#ffff80ff
2\Performance\DPI\5=@Point(6000 6000)
2\Performance\DPI\5Disabled=false
2\Performance\DPI\5RGB=#ffffffff
2\Performance\DPI\6RGB=#ff000000
2\Performance\DPI\CurIdx=1
2\Performance\Indicators\0\Enable=false
2\Performance\Indicators\0\Hardware=0
2\Performance\Indicators\0\RGB0=#ff00ff00
2\Performance\Indicators\0\RGB1=#ff000000
2\Performance\Indicators\1\Enable=false
2\Performance\Indicators\1\Hardware=0
2\Performance\Indicators\1\RGB0=#ff00ff00
2\Performance\Indicators\1\RGB1=#ff000000
2\Performance\Indicators\2\Enable=false
2\Performance\Indicators\2\Hardware=0
2\Performance\Indicators\2\RGB0=#ff00ff00
2\Performance\Indicators\2\RGB1=#ff000000
2\Performance\Indicators\3\Enable=true
2\Performance\Indicators\3\RGB0=#00ffffff
2\Performance\Indicators\3\RGB1=#ff000000
2\Performance\Indicators\4\Enable=true
2\Performance\Indicators\4\RGB0=#ffff0000
2\Performance\Indicators\4\RGB1=#ff000000
2\Performance\Indicators\5\Enable=true
2\Performance\Indicators\5\RGB0=#ffff0000
2\Performance\Indicators\5\RGB1=#ffffff00
2\Performance\Indicators\5\RGB2=#ffffffff
2\Performance\Indicators\6\Enable=true
2\Performance\Indicators\6\RGB0=#ffffffff
2\Performance\Indicators\6\RGB1=#ff000000
2\Performance\Indicators\7\Enable=true
2\Performance\Indicators\7\RGB0=#00ffffff
2\Performance\Indicators\7\RGB1=#ff000000
2\Performance\Indicators\7\RGB2=#ff000000
2\Performance\Indicators\DPI=true
2\Performance\LiftHeight=3
2\Performance\MuteDevice=sink
2\WindowInfo\enabled=false
CurrentMode={11C11AE3-3195-4DFC-B8AC-2FEA703414E5}
HwModified=40b6f054
ModeCount=3
Modified=e1b94a7e
Name=Demo