Files
OpenRGB/Controllers/WinbondGamingKeyboardController/RGBController_WinbondGamingKeyboard.cpp

852 lines
30 KiB
C++

/*---------------------------------------------------------*\
| RGBController_WinbondGamingKeyboard.cpp |
| |
| RGBController for Winbond Gaming Keyboard |
| |
| Daniel Gibson 03 Dec 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "RGBController_WinbondGamingKeyboard.h"
#include "RGBControllerKeyNames.h"
#include "KeyboardLayoutManager.h"
#include "LogManager.h"
/**------------------------------------------------------------------*\
@name Winbond Gaming Keyboard
@category Keyboard
@type USB
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectWinbondGamingKeyboard
@comment Also known as Pulsar PCMK, and KT108 (by various manufacturers)
\*-------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------*\
| - MSG_NUM is between 0 and (incl) 7, indicating which HID message contains the key's LED |
| - IDX is between 0 and (incl.) 17 (0 to 5 for message 7), |
| indicating the index of that LED within the message. |
| - 1 << 16 is set so KV(0,0) doesn't have the same value as 0 (the default "not assigned" value) |
\*-----------------------------------------------------------------------------------------------*/
#define KV(MSG_NUM, IDX) ((MSG_NUM) << 8 | (IDX) | (1 << 16))
static std::vector<keyboard_led> additional_mm_leds =
{
{
0, // zone
0, // row
17, // col
KV(1,0), // value
KEY_EN_MEDIA_VOLUME_UP, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
},
{
0, // zone
0, // row
18, // col
KV(1,1), // value
KEY_EN_MEDIA_VOLUME_DOWN, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
},
{
0, // zone
0, // row
19, // col
KV(1,2), // value
KEY_EN_MEDIA_MUTE, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
},
{
0, // zone
0, // row
20, // col
KV(1,3), // value
"Key: Cylinder?!", // name; TODO: no idea what the symbol meant, was a cylinder..
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
}
};
static layout_values winbond_gaming_keyboard_full_layouts =
{
{}, // "std::vector<unsigned int> default_values" is set in InitLayouts()
{ // std::map<KEYBOARD_LAYOUT, std::vector<keyboard_led> > regional_overlay;
{ KEYBOARD_LAYOUT_ISO_QWERTY,
{
/*---------------------------------------------------------*\
| just setting the values for some keys that should already |
| be defined by KeyboardLayoutManager's keyboard_zone_main |
\*---------------------------------------------------------*/
{
0, // zone
3, // row
12, // col
KV(4,7), // value
KEY_EN_POUND, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_SWAP_ONLY // opcode
},
{
0, // zone
4, // row
1, // col
KV(4,17), // value
KEY_EN_ISO_BACK_SLASH, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_SWAP_ONLY // opcode
},
}
},
{ KEYBOARD_LAYOUT_JIS,
{
/*------------------------------------------------*\
| that extra key before backspace on JIS keyboards |
\*------------------------------------------------*/
{
0, // zone
1, // row
13, // col
KV(1,17), // value
KEY_JP_YEN, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
}
}
}
/*----------------------------------------------------------------------------------*\
| TODO: KV(5,10) could be that extra key left of right shift on ABNT keyboards (/ ?) |
\*----------------------------------------------------------------------------------*/
}
};
static layout_values winbond_gaming_keyboard_tkl_layouts =
{
{}, // "std::vector<unsigned int> default_values" is set in InitLayouts()
{ // std::map<KEYBOARD_LAYOUT, std::vector<keyboard_led> > regional_overlay;
{ KEYBOARD_LAYOUT_ISO_QWERTY,
{
/*---------------------------------------------------------*\
| just setting the values for some keys that should already |
| be defined by KeyboardLayoutManager's keyboard_zone_main |
\*---------------------------------------------------------*/
{
0, // zone
3, // row
12, // col
KV(4,7), // value
KEY_EN_POUND, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_SWAP_ONLY // opcode
},
{
0, // zone
4, // row
1, // col
KV(4,17), // value
KEY_EN_ISO_BACK_SLASH, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_SWAP_ONLY // opcode
},
}
},
{ KEYBOARD_LAYOUT_JIS,
{
/*------------------------------------------------*\
| that extra key before backspace on JIS keyboards |
\*------------------------------------------------*/
{
0, // zone
1, // row
13, // col
KV(1,17), // value
KEY_JP_YEN, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
}
}
}
/*----------------------------------------------------------------------------------*\
| TODO: KV(5,10) could be that extra key left of right shift on ABNT keyboards (/ ?) |
\*----------------------------------------------------------------------------------*/
}
};
static layout_values winbond_gaming_keyboard_60_layouts =
{
{}, // "std::vector<unsigned int> default_values" is set in InitLayouts()
{ // std::map<KEYBOARD_LAYOUT, std::vector<keyboard_led> > regional_overlay;
{ KEYBOARD_LAYOUT_ISO_QWERTY,
{
/*---------------------------------------------------------*\
| just setting the values for some keys that should already |
| be defined by KeyboardLayoutManager's keyboard_zone_main |
\*---------------------------------------------------------*/
{
0, // zone
3, // row
12, // col
KV(4,7), // value
KEY_EN_POUND, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_SWAP_ONLY // opcode
},
{
0, // zone
4, // row
1, // col
KV(4,17), // value
KEY_EN_ISO_BACK_SLASH, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_SWAP_ONLY // opcode
},
}
},
{ KEYBOARD_LAYOUT_JIS,
{
/*------------------------------------------------*\
| that extra key before backspace on JIS keyboards |
\*------------------------------------------------*/
{
0, // zone
1, // row
13, // col
KV(1,17), // value
KEY_JP_YEN, // name
KEY_EN_UNUSED, // translated name
KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT // opcode
}
}
}
/*----------------------------------------------------------------------------------*\
| TODO: KV(5,10) could be that extra key left of right shift on ABNT keyboards (/ ?) |
\*----------------------------------------------------------------------------------*/
}
};
static void InitLayouts(layout_values& keyboard_layouts, KEYBOARD_SIZE kb_size, std::string vendor)
{
/*-------------------------------------------------------------------*\
| using kvs ("keyvals" or sth like that) as an alias for |
| keyboard_layouts.default_values, to make the code below |
| shorter/more readable |
\*-------------------------------------------------------------------*/
std::vector<unsigned int>& kvs = keyboard_layouts.default_values;
/*------------------------------------------------------------------------------------*\
| Message X: what indices the keys have within the USB HID messages to set their color |
| "??" means "that index exists, but doesn't seem to be used on my TKL ISO keyboard" |
| |
| A Note regarding kb_size: I wrote this with my Pulsar PCMK TKL keyboard, there the |
| LED positions ( KV(MSGNUM, IDX) ) were like on a fullsize keyboard, |
| i.e. there USB messages had space for NumPad keys (or their LEDs). |
| No idea if that's also true for e.g. 60% keyboards, and it's also possible that |
| some positions of NumPad LEDs are incorrect, I only guessed them. |
\*------------------------------------------------------------------------------------*/
/* Message 0: ---------------------------------------------------------------*\
| 0 = Esc, ??, 2 = F1, F2, F3, F4, ??, 7 = F5, F6, F7, F8, F9, F10, F11, F12, |
| 15 = Print, ScrollLock, 17 = Pause |
\*---------------------------------------------------------------------------*/
if(kb_size & KEYBOARD_ZONE_FN_ROW)
{
kvs.push_back( KV(0,0) ); // Esc
// F1 to F4
for(int i=2; i <= 5; ++i)
{
kvs.push_back( KV(0,i) );
}
// F5 to F12
for(int i=7; i <= 14; ++i)
{
kvs.push_back( KV(0,i) );
}
}
if(kb_size & KEYBOARD_ZONE_EXTRA)
{
// PrintScreen, ScrollLock, Pause
for(int i=15; i <= 17; ++i)
{
kvs.push_back( KV(0,i) );
}
}
/* Message 1: ------------------------------------------------------------------------*\
| 0-3 = (could be multimedia keys above numblock?), 4 = BKTK, 1, 2, 3, 4, 5, |
| 10 = 6, 7, 8, 9, 0, '-', 16 = '=', 17 = (that extra key before backspace on JIS?) |
\*------------------------------------------------------------------------------------*/
// KV(1,0) to KV(1,3) are probably 4 extra multimedia keys above the numblock
// BKTK ("Quake console key"), 1, 2, ... 0, -, =
if(kb_size & KEYBOARD_ZONE_MAIN)
{
for(int i=4; i <= 16; ++i)
{
kvs.push_back( KV(1,i) );
}
// KV(1,17) might be that extra Yen key before backspace on JIS keyboards
}
/* Message 2: ------------------------------------------------------------*\
| 0 = Backspace, Ins, Pos1, 3 = PgUp, 4-7 = (NumLock, Num/, Num*, Num- ?), |
| 8 = Tab, Q, W, E, R, T, ..., 16 = I, 17 = O |
\*------------------------------------------------------------------------*/
// Backspace
if(kb_size & KEYBOARD_ZONE_MAIN)
{
kvs.push_back( KV(2,0) );
}
// Ins, Home, PgUp
if(kb_size & KEYBOARD_ZONE_EXTRA)
{
for(int i=1; i <= 3; ++i)
{
kvs.push_back( KV(2,i) );
}
}
// NumLock, NP/, NP*, NP-
if(kb_size & KEYBOARD_ZONE_NUMPAD)
{
for(int i=4; i <= 7; ++i)
{
kvs.push_back( KV(2,i) );
}
}
// Tab, Q, ..., I, O
if(kb_size & KEYBOARD_ZONE_MAIN)
{
for(int i=8; i <= 17; ++i)
{
kvs.push_back( KV(2,i) );
}
}
/* Message 3: -----------------------------------------------------------*\
| 0 = P, [ (Ü), ] (+), 3 = (US-\ ?), ??, 5 = Del, End, 7 = PgDown, |
| 8-1 = (Num7, Num8, Num9, Num+ ?), 12 = CapsLock, ??, 14 = A, S, D, F |
\*-----------------------------------------------------------------------*/
// P, Ü/[, +/]
if(kb_size & KEYBOARD_ZONE_MAIN)
{
for(int i=0; i <= 2; ++i)
{
kvs.push_back( KV(3,i) );
}
// Backslash
if(vendor != "Hator")
{
kvs.push_back( KV(3,3) );
}
else
{
kvs.push_back( KV(3,4) );
}
}
// Del, End, PgDown
if(kb_size & KEYBOARD_ZONE_EXTRA)
{
for(int i=5; i <= 7; ++i)
{
kvs.push_back( KV(3,i) );
}
}
// NP7-NP9, NP+
if(kb_size & KEYBOARD_ZONE_NUMPAD)
{
for(int i=8; i <= 11; ++i)
{
kvs.push_back( KV(3,i) );
}
}
if(kb_size & KEYBOARD_ZONE_MAIN)
{
// CapsLock
kvs.push_back( KV(3,12) );
// A, S, D, F
for(int i=14; i <= 17; ++i)
{
kvs.push_back( KV(3,i) );
}
}
/* Message 4: -------------------------------------------------------------*\
| 0 = G, H, J, K, L, ; (Ö), " (Ä), 7 = #, 8 = Enter, 9 - 15 = ?? |
| (maybe 12-14 are Num4-6, maybe 15 = Num+ ?), 16 = Shift, 17 = ISO-\ (<) |
\*-------------------------------------------------------------------------*/
if(kb_size & KEYBOARD_ZONE_MAIN)
{
// G, H, ..., L, Ö/;, Ä/"
for(int i=0; i <= 6; ++i)
{
kvs.push_back( KV(4,i) );
}
// KV(4,7) is the ISO # key that doesn't exist on ANSI (set in overlay)
// even though # is no ANSI key, that default_values array expects it to be there..
kvs.push_back( KV(4,7) );
// Enter - assuming that on ANSI it uses the same LED index
kvs.push_back( KV(4,8) );
}
if(kb_size & KEYBOARD_ZONE_NUMPAD)
{
// NP4-6 - not sure if those are really at 12-14, would fit though
for(int i=12; i <= 14; ++i)
{
kvs.push_back( KV(4,i) );
}
}
if(kb_size & KEYBOARD_ZONE_MAIN)
{
// Left Shift
kvs.push_back( KV(4,16) );
// KV(4,17) is the ISO |\ (or <) key that doesn't exist on ANSI (set in overlay)
// apparently it must be listed anyway..
kvs.push_back( KV(4,17) );
}
/* Message 5: --------------------------------------------------------*\
| 0 = Z/Y, X, C, V, B, N, M, ',', '.' , 9 = / or -, ??, ??, |
| 12 = Shift, ??, 14 = Up, 15-17 ?? (maybe 16 and 17 are Num1, Num2, |
| and Num3, NumEnter are in next msg?) |
\*--------------------------------------------------------------------*/
if(kb_size & KEYBOARD_ZONE_MAIN)
{
// Z (Y), X, .., M, ',', '.', / (- on DE)
for(int i=0; i <= 9; ++i)
{
kvs.push_back( KV(5,i) );
}
// KV(5,10) could be that extra key left of right shift on ABNT keyboards (/ ?)
kvs.push_back( KV(5,12) ); // Right Shift
}
if(kb_size & KEYBOARD_ZONE_EXTRA)
{
kvs.push_back( KV(5,14) ); // Up
}
if(kb_size & KEYBOARD_ZONE_NUMPAD)
{
kvs.push_back( KV(5,16) ); // Num1
kvs.push_back( KV(5,17) ); // Num2
}
/* Message 6: -------------------------------------------------------------*\
| 0 = (Num3 ?), (Num Enter ?), 2 = Ctrl, Win, 4 = Alt, .. ?? .., 8 = Space, |
| .. ?? .., 12 = AltGr, Fn, Menu, 15 = Ctrl, ??, 17 = Left |
\*-------------------------------------------------------------------------*/
// Num3, Num Enter
if(kb_size & KEYBOARD_ZONE_NUMPAD)
{
for(int i=0; i <= 1; ++i)
{
kvs.push_back( KV(6,i) );
}
}
if(kb_size & KEYBOARD_ZONE_MAIN)
{
// LeftCtrl, Win, LeftAlt
for(int i=2; i <= 4; ++i)
{
kvs.push_back( KV(6,i) );
}
// Space
kvs.push_back( KV(6,8) );
// RightAlt, Fn, RMenu, RightCtrl
for(int i=12; i <= 15; ++i)
{
kvs.push_back( KV(6,i) );
}
}
if(kb_size & KEYBOARD_ZONE_EXTRA)
kvs.push_back( KV(6,17) ); // Left
/* Message 7: -------------------------------------------------------*\
| 0 = Down, 1 = Right, 2-5 = ?? (maybe 2 or 3 = Num0, 4 = NumDecimal, |
| 5 = NumEnter, more likely: 3 = Num0, 5 = NumDec) |
\*-------------------------------------------------------------------*/
if(kb_size & KEYBOARD_ZONE_EXTRA)
{
kvs.push_back( KV(7,0) ); // Down
kvs.push_back( KV(7,1) ); // Right
}
if(kb_size & KEYBOARD_ZONE_NUMPAD)
{
kvs.push_back( KV(7,3) ); // Num0 - TODO: or 7,2 or 7,4 ?
kvs.push_back( KV(7,5) ); // NumDec - TODO: or 7,4 ?
}
/*-------------------------------------------------------------------*\
| for fullsize keyboards, add multimedia keys to all layouts/overlays |
\*-------------------------------------------------------------------*/
if(kb_size == KEYBOARD_SIZE_FULL)
{
for(std::pair<const KEYBOARD_LAYOUT, std::vector<keyboard_led>>& overlay: keyboard_layouts.regional_overlay)
{
for(const keyboard_led& mm_key_led : additional_mm_leds)
{
overlay.second.push_back(mm_key_led);
}
}
/*---------------------------------------------------------------------------------*\
| there is no overlay for the ANSI layout defined yet, add one just for the MM keys |
\*---------------------------------------------------------------------------------*/
keyboard_layouts.regional_overlay.insert({ KEYBOARD_LAYOUT_ANSI_QWERTY, additional_mm_leds });
}
}
RGBController_WinbondGamingKeyboard::RGBController_WinbondGamingKeyboard(WinbondGamingKeyboardController* ctrl)
: controller(ctrl)
{
type = DEVICE_TYPE_KEYBOARD;
name = ctrl->GetName();
vendor = ctrl->GetVendor();
description = ctrl->GetDescription();
location = ctrl->GetDeviceLocation();
serial = ctrl->GetSerialString();
version = ctrl->GetVersion();
{
mode m;
m.name = "Custom";
m.value = WINBOND_GK_MODE_CUSTOM;
m.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
m.color_mode = MODE_COLORS_PER_LED;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Static";
m.value = WINBOND_GK_MODE_STATIC;
m.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
m.color_mode = MODE_COLORS_MODE_SPECIFIC;
m.colors_min = m.colors_max = 1; // one color for all keys
m.colors.push_back(ToRGBColor(255,255,255)); // default to white
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Neon";
m.value = WINBOND_GK_MODE_NEON;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0));
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Breathing";
m.value = WINBOND_GK_MODE_BREATHE;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0));
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Wave";
m.value = WINBOND_GK_MODE_WAVE;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE
| MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD
| MODE_FLAG_HAS_DIRECTION_HV; // NOTE: this is really outer to inner or inner to outer
m.direction = MODE_DIRECTION_RIGHT;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0));
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Snake";
m.value = WINBOND_GK_MODE_SNAKE;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE
| MODE_FLAG_HAS_DIRECTION_UD; // NOTE: more like CW/CCW
m.direction = MODE_DIRECTION_DOWN;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0));
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
/*------------------------------------------------------------------------*\
|the following modes are ones that only show effects when a key is pressed |
| and otherwise only a background color |
\*------------------------------------------------------------------------*/
{
mode m;
m.name = "Aurora (on keypress)";
m.value = WINBOND_GK_MODE_AURORA;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE
| MODE_FLAG_HAS_DIRECTION_HV; // NOTE: more like to inner/to outer
m.direction = MODE_DIRECTION_HORIZONTAL;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0)); // TODO: set background to white so keyboard isn't dark?
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Ripple (on keypress)";
m.value = WINBOND_GK_MODE_RIPPLE;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0)); // TODO: set background to white so keyboard isn't dark?
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
{
mode m;
m.name = "Reactive (on keypress)";
m.value = WINBOND_GK_MODE_REACTIVE;
m.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
m.colors.push_back(ToRGBColor(255,0,0));
m.colors.push_back(ToRGBColor(0,0,0)); // TODO: set background to white so keyboard isn't dark?
m.colors_min = 0;
m.colors_max = 2;
m.color_mode = MODE_COLORS_RANDOM;
m.brightness_min = 0;
m.brightness_max = 4;
m.brightness = 1;
m.speed_min = 0;
m.speed_max = 4;
m.speed = 2;
modes.push_back(m);
}
/*--------------------------------------------------------------------------------*\
| NOTE: logo light has static, neon (WINBOND_GK_MODE_LOGO_NEON), breathe, wave |
| all logo modes have brightness, all but static have speed and 2 colors + random |
\*--------------------------------------------------------------------------------*/
SetupZones();
}
RGBController_WinbondGamingKeyboard::~RGBController_WinbondGamingKeyboard()
{
delete controller;
}
void RGBController_WinbondGamingKeyboard::SetupZones()
{
zone new_zone;
new_zone.name = ZONE_EN_KEYBOARD;
new_zone.type = ZONE_TYPE_MATRIX;
layout_values* layouts = &winbond_gaming_keyboard_full_layouts;
KEYBOARD_SIZE kb_size = controller->GetSize();
std::string vendor = controller->GetVendor();
if(kb_size == KEYBOARD_SIZE_TKL)
{
layouts = &winbond_gaming_keyboard_tkl_layouts;
}
else if(kb_size == KEYBOARD_SIZE_SIXTY)
{
layouts = &winbond_gaming_keyboard_60_layouts;
}
else // size is full or something not supported directly - default to full
{
kb_size = KEYBOARD_SIZE_FULL;
}
if(layouts->default_values.empty())
{
InitLayouts(*layouts, kb_size, vendor);
}
KeyboardLayoutManager new_kb(controller->GetLayout(), kb_size, *layouts);
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_zone.matrix_map->height = new_kb.GetRowCount();
new_zone.matrix_map->width = new_kb.GetColumnCount();
new_zone.matrix_map->map = new unsigned int[new_map->height * new_map->width];
new_zone.leds_count = new_kb.GetKeyCount();
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
/*---------------------------------------------------------*\
| Matrix map still uses declared zone rows and columns |
| as the packet structure depends on the matrix map |
\*---------------------------------------------------------*/
new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT);
/*---------------------------------------------------------*\
| Create LEDs for the Matrix zone |
| Place keys in the layout to populate the matrix |
\*---------------------------------------------------------*/
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
{
led new_led;
new_led.name = new_kb.GetKeyNameAt((unsigned int)led_idx);
new_led.value = new_kb.GetKeyValueAt((unsigned int)led_idx);
leds.push_back(new_led);
}
zones.push_back(new_zone);
/*---------------------------------------------------------------------------*\
| special case: logo LEDs |
| it's 3 LEDs, but the colors can't be set separately, so represent it as one |
\*---------------------------------------------------------------------------*/
if(controller->HasLogoLight())
{
zone logo_zone;
logo_zone.name = "Logo Light";
logo_zone.type = ZONE_TYPE_SINGLE;
logo_zone.leds_min = 1;
logo_zone.leds_max = 1;
logo_zone.leds_count = 1;
logo_zone.matrix_map = NULL;
led zone_led;
zone_led.name = "Logo LEDs";
zone_led.value = KV(255, 0); // using message num 255 as special case for logo LED
leds.push_back(zone_led);
zones.push_back(logo_zone);
}
SetupColors();
}
#undef KV
void RGBController_WinbondGamingKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_WinbondGamingKeyboard::DeviceUpdateLEDs()
{
controller->SetLEDsData(colors, leds, modes[active_mode].brightness);
}
void RGBController_WinbondGamingKeyboard::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_WinbondGamingKeyboard::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_WinbondGamingKeyboard::DeviceUpdateMode()
{
controller->SetMode(modes[active_mode]);
}