| // Copyright 2022 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "rgbkbd/rgb_keyboard_controller_impl.h" |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "base/check.h" |
| #include "base/logging.h" |
| #include "base/notreached.h" |
| |
| namespace rgbkbd { |
| |
| RgbKeyboardControllerImpl::RgbKeyboardControllerImpl(RgbKeyboard* keyboard) |
| : keyboard_(keyboard), background_color_(kWhiteBackgroundColor) {} |
| RgbKeyboardControllerImpl::~RgbKeyboardControllerImpl() = default; |
| |
| uint32_t RgbKeyboardControllerImpl::GetRgbKeyboardCapabilities() { |
| if (!capabilities_.has_value()) { |
| capabilities_ = keyboard_->GetRgbKeyboardCapabilities(); |
| if (capabilities_.value() == RgbKeyboardCapabilities::kIndividualKey) { |
| PopulateRainbowModeMap(); |
| } |
| } |
| |
| return static_cast<uint32_t>(capabilities_.value()); |
| } |
| |
| void RgbKeyboardControllerImpl::SetKeyColor(const KeyColor& key_color) { |
| keyboard_->SetKeyColor(key_color.key, key_color.color.r, key_color.color.g, |
| key_color.color.b); |
| } |
| |
| void RgbKeyboardControllerImpl::SetAllKeyColors(const Color& color) { |
| keyboard_->SetAllKeyColors(color.r, color.g, color.b); |
| } |
| |
| void RgbKeyboardControllerImpl::SetCapsLockState(bool enabled) { |
| caps_lock_enabled_ = enabled; |
| // Per zone keyboards can not independently set left/right shift RGB colors. |
| // TODO(michaelcheco): Prevent this call from happening for per zone keyboards |
| // higher up in the stack. |
| if (IsZonedKeyboard()) { |
| LOG(ERROR) << "Attempted to set caps lock color for a per zone keyboard"; |
| return; |
| } |
| |
| SetKeyColor({kLeftShiftKey, GetCurrentCapsLockColor(kLeftShiftKey)}); |
| SetKeyColor({kRightShiftKey, GetCurrentCapsLockColor(kRightShiftKey)}); |
| } |
| |
| void RgbKeyboardControllerImpl::SetStaticBackgroundColor(uint8_t r, |
| uint8_t g, |
| uint8_t b) { |
| background_type_ = BackgroundType::kStaticSingleColor; |
| background_color_ = Color(r, g, b); |
| SetAllKeyColors(background_color_); |
| |
| // If Capslock was enabled, re-color the highlight keys. |
| if (caps_lock_enabled_) { |
| SetCapsLockState(/*caps_lock_enabled_=*/true); |
| } |
| } |
| |
| void RgbKeyboardControllerImpl::SetKeyboardClient(RgbKeyboard* keyboard) { |
| DCHECK(keyboard); |
| keyboard_ = keyboard; |
| } |
| |
| void RgbKeyboardControllerImpl::SetKeyboardCapabilityForTesting( |
| RgbKeyboardCapabilities capability) { |
| capabilities_ = capability; |
| if (capabilities_.value() == RgbKeyboardCapabilities::kIndividualKey) { |
| PopulateRainbowModeMap(); |
| } else { |
| individual_key_rainbow_mode_map_.clear(); |
| } |
| } |
| |
| const base::span<const KeyColor> |
| RgbKeyboardControllerImpl::GetRainbowModeForKeyboard() const { |
| DCHECK(capabilities_.has_value()); |
| switch (capabilities_.value()) { |
| case RgbKeyboardCapabilities::kNone: |
| NOTREACHED(); |
| return base::span<const KeyColor>(); |
| case RgbKeyboardCapabilities::kIndividualKey: |
| return base::span<const KeyColor>(kRainbowModeIndividualKey, |
| std::size(kRainbowModeIndividualKey)); |
| case RgbKeyboardCapabilities::kFourZoneFortyLed: |
| return base::span<const KeyColor>( |
| kRainbowModeFourZoneFortyLed, |
| std::size(kRainbowModeFourZoneFortyLed)); |
| case RgbKeyboardCapabilities::kFourZoneTwelveLed: |
| return base::span<const KeyColor>( |
| kRainbowModeFourZoneTwelveLed, |
| std::size(kRainbowModeFourZoneTwelveLed)); |
| case RgbKeyboardCapabilities::kFourZoneFourLed: |
| return base::span<const KeyColor>(kRainbowModeFourZoneFourLed, |
| std::size(kRainbowModeFourZoneFourLed)); |
| } |
| } |
| |
| void RgbKeyboardControllerImpl::SetRainbowMode() { |
| background_type_ = BackgroundType::kStaticRainbow; |
| for (const auto& entry : GetRainbowModeForKeyboard()) { |
| // Check if caps lock is enabled to avoid overriding the caps lock |
| // highlight keys. |
| if (caps_lock_enabled_ && IsShiftKey(entry.key)) { |
| continue; |
| } |
| keyboard_->SetKeyColor(entry.key, entry.color.r, entry.color.g, |
| entry.color.b); |
| } |
| } |
| |
| // TODO(jimmyxgong): Implement this stub. |
| void RgbKeyboardControllerImpl::SetAnimationMode(RgbAnimationMode mode) { |
| NOTIMPLEMENTED(); |
| } |
| |
| const std::vector<KeyColor> |
| RgbKeyboardControllerImpl::GetRainbowModeColorsWithoutShiftKeysForTesting() { |
| DCHECK(capabilities_ == RgbKeyboardCapabilities::kIndividualKey); |
| std::vector<KeyColor> vec; |
| for (const auto& entry : kRainbowModeIndividualKey) { |
| if (entry.key == kLeftShiftKey || entry.key == kRightShiftKey) { |
| continue; |
| } |
| vec.push_back(entry); |
| } |
| return vec; |
| } |
| |
| Color RgbKeyboardControllerImpl::GetCurrentCapsLockColor( |
| uint32_t key_idx) const { |
| if (caps_lock_enabled_) { |
| return GetCapsLockHighlightColor(); |
| } |
| |
| if (background_type_ == BackgroundType::kStaticRainbow) { |
| return GetRainbowColorForKey(key_idx); |
| } |
| |
| return background_color_; |
| } |
| |
| Color RgbKeyboardControllerImpl::GetCapsLockHighlightColor() const { |
| return (background_color_ == kWhiteBackgroundColor) |
| ? kCapsLockHighlightAlternate |
| : kCapsLockHighlightDefault; |
| } |
| |
| Color RgbKeyboardControllerImpl::GetRainbowColorForKey(uint32_t key_idx) const { |
| DCHECK(capabilities_ == RgbKeyboardCapabilities::kIndividualKey); |
| return individual_key_rainbow_mode_map_.at(key_idx); |
| } |
| |
| void RgbKeyboardControllerImpl::PopulateRainbowModeMap() { |
| std::vector<std::pair<uint32_t, Color>> vec; |
| vec.reserve(std::size(kRainbowModeIndividualKey)); |
| for (auto i = 0; i < std::size(kRainbowModeIndividualKey); i++) { |
| vec.push_back(std::make_pair(kRainbowModeIndividualKey[i].key, |
| kRainbowModeIndividualKey[i].color)); |
| } |
| individual_key_rainbow_mode_map_ = |
| base::flat_map<uint32_t, Color>(std::move(vec)); |
| } |
| |
| bool RgbKeyboardControllerImpl::IsZonedKeyboard() const { |
| DCHECK(capabilities_.has_value()); |
| return capabilities_.value() != RgbKeyboardCapabilities::kIndividualKey; |
| } |
| |
| void RgbKeyboardControllerImpl::ReinitializeOnDeviceReconnected() { |
| SetKeyColor({kLeftShiftKey, GetCurrentCapsLockColor(kLeftShiftKey)}); |
| SetKeyColor({kRightShiftKey, GetCurrentCapsLockColor(kRightShiftKey)}); |
| switch (background_type_) { |
| case BackgroundType::kStaticSingleColor: |
| SetStaticBackgroundColor(background_color_.r, background_color_.g, |
| background_color_.b); |
| break; |
| case BackgroundType::kStaticRainbow: |
| SetRainbowMode(); |
| break; |
| } |
| } |
| |
| } // namespace rgbkbd |