From 7ee6ddd9a763cdc742d36d002d6a834c651efd28 Mon Sep 17 00:00:00 2001
From: Ilya Zhuravlev <whatever@xyz.is>
Date: Thu, 8 Jul 2021 19:27:26 -0400
Subject: [PATCH] vialrgb: initial

---
 common_features.mk |  5 +++++
 quantum/via.c      | 19 +++++++++++++++---
 quantum/vial.c     |  6 ++++--
 quantum/vial.h     |  1 +
 quantum/vialrgb.c  | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 quantum/vialrgb.h  | 21 +++++++++++++++++++
 6 files changed, 97 insertions(+), 5 deletions(-)
 create mode 100644 quantum/vialrgb.c
 create mode 100644 quantum/vialrgb.h

diff --git a/common_features.mk b/common_features.mk
index fe349018e6..26eaf4829b 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -474,6 +474,11 @@ ifeq ($(strip $(VIAL_ENCODERS_ENABLE)), yes)
     OPT_DEFS += -DVIAL_ENCODERS_ENABLE
 endif
 
+ifeq ($(strip $(VIALRGB_ENABLE)), yes)
+    SRC += $(QUANTUM_DIR)/vialrgb.c
+    OPT_DEFS += -DVIALRGB_ENABLE
+endif
+
 ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
     OPT_DEFS += -DDYNAMIC_KEYMAP_ENABLE
     SRC += $(QUANTUM_DIR)/dynamic_keymap.c
diff --git a/quantum/via.c b/quantum/via.c
index 32d428682d..6403c5f41a 100644
--- a/quantum/via.c
+++ b/quantum/via.c
@@ -52,6 +52,10 @@
 #include "vial.h"
 #endif
 
+#ifdef VIALRGB_ENABLE
+#include "vialrgb.h"
+#endif
+
 // Forward declare some helpers.
 #if defined(VIA_QMK_BACKLIGHT_ENABLE)
 void via_qmk_backlight_set_value(uint8_t *data);
@@ -322,10 +326,13 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
 #if defined(VIA_QMK_RGBLIGHT_ENABLE)
             via_qmk_rgblight_set_value(command_data);
 #endif
+#if defined(VIALRGB_ENABLE)
+            vialrgb_set_value(data, length);
+#endif
 #if defined(VIA_CUSTOM_LIGHTING_ENABLE)
             raw_hid_receive_kb(data, length);
 #endif
-#if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE)
+#if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIALRGB_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE)
             // Return the unhandled state
             *command_id = id_unhandled;
 #endif
@@ -338,10 +345,13 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
 #if defined(VIA_QMK_RGBLIGHT_ENABLE)
             via_qmk_rgblight_get_value(command_data);
 #endif
+#if defined(VIALRGB_ENABLE)
+            vialrgb_get_value(data, length);
+#endif
 #if defined(VIA_CUSTOM_LIGHTING_ENABLE)
             raw_hid_receive_kb(data, length);
 #endif
-#if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE)
+#if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIALRGB_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE)
             // Return the unhandled state
             *command_id = id_unhandled;
 #endif
@@ -354,10 +364,13 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
 #if defined(VIA_QMK_RGBLIGHT_ENABLE)
             eeconfig_update_rgblight_current();
 #endif
+#if defined(VIALRGB_ENABLE)
+            vialrgb_save(data, length);
+#endif
 #if defined(VIA_CUSTOM_LIGHTING_ENABLE)
             raw_hid_receive_kb(data, length);
 #endif
-#if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE)
+#if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIALRGB_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE)
             // Return the unhandled state
             *command_id = id_unhandled;
 #endif
diff --git a/quantum/vial.c b/quantum/vial.c
index b67aaa9f21..94a370db87 100644
--- a/quantum/vial.c
+++ b/quantum/vial.c
@@ -44,8 +44,6 @@ _Static_assert(VIAL_UNLOCK_NUM_KEYS < 15, "Max 15 unlock keys");
 _Static_assert(sizeof(vial_unlock_combo_rows) == sizeof(vial_unlock_combo_cols), "The number of unlock cols and rows should be the same");
 #endif
 
-#define VIAL_RAW_EPSIZE 32
-
 #ifndef VIAL_ENCODER_KEYCODE_DELAY
 #define VIAL_ENCODER_KEYCODE_DELAY 10
 #endif
@@ -82,11 +80,15 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) {
         case vial_get_keyboard_id: {
             uint8_t keyboard_uid[] = VIAL_KEYBOARD_UID;
 
+            memset(msg, 0, length);
             msg[0] = VIAL_PROTOCOL_VERSION & 0xFF;
             msg[1] = (VIAL_PROTOCOL_VERSION >> 8) & 0xFF;
             msg[2] = (VIAL_PROTOCOL_VERSION >> 16) & 0xFF;
             msg[3] = (VIAL_PROTOCOL_VERSION >> 24) & 0xFF;
             memcpy(&msg[4], keyboard_uid, 8);
+#ifdef VIALRGB_ENABLE
+            msg[12] = 1; /* bit flag to indicate vialrgb is supported - so third-party apps don't have to query json */
+#endif
             break;
         }
         /* Retrieve keyboard definition size */
diff --git a/quantum/vial.h b/quantum/vial.h
index 9a910dd8a9..74e648fa23 100644
--- a/quantum/vial.h
+++ b/quantum/vial.h
@@ -20,6 +20,7 @@
 #include <stdbool.h>
 
 #define VIAL_PROTOCOL_VERSION ((uint32_t)0x00000004)
+#define VIAL_RAW_EPSIZE 32
 
 void vial_init(void);
 void vial_handle_cmd(uint8_t *data, uint8_t length);
diff --git a/quantum/vialrgb.c b/quantum/vialrgb.c
new file mode 100644
index 0000000000..e29d2b4cf9
--- /dev/null
+++ b/quantum/vialrgb.c
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "vialrgb.h"
+
+#include <inttypes.h>
+#include "rgb_matrix.h"
+#include "vial.h"
+
+/* Based on https://github.com/qmk/qmk_firmware/pull/13036 */
+
+void vialrgb_get_value(uint8_t *data, uint8_t length) {
+    if (length != VIAL_RAW_EPSIZE) return;
+
+    /* data[0] is used by VIA command id */
+    uint8_t cmd = data[1];
+    uint8_t *args = &data[2];
+    switch (cmd) {
+    case vialrgb_get_mode: {
+        args[0] = rgb_matrix_get_mode();
+        args[1] = rgb_matrix_get_speed();
+        args[2] = rgb_matrix_get_hue();
+        args[3] = rgb_matrix_get_sat();
+        args[4] = rgb_matrix_get_val();
+        break;
+    }
+    }
+}
+
+void vialrgb_set_value(uint8_t *data, uint8_t length) {
+    if (length != VIAL_RAW_EPSIZE) return;
+
+    /* data[0] is used by VIA command id */
+    uint8_t cmd = data[1];
+    uint8_t *args = &data[2];
+    switch (cmd) {
+    case vialrgb_set_mode: {
+        rgb_matrix_mode_noeeprom(args[0]);
+        rgb_matrix_set_speed_noeeprom(args[1]);
+        rgb_matrix_sethsv_noeeprom(args[2], args[3], args[4]);
+        break;
+    }
+    }
+}
+
+void vialrgb_save(uint8_t *data, uint8_t length) {
+    (void)data;
+    (void)length;
+
+    eeconfig_update_rgb_matrix();
+}
diff --git a/quantum/vialrgb.h b/quantum/vialrgb.h
new file mode 100644
index 0000000000..a18a6c8ebf
--- /dev/null
+++ b/quantum/vialrgb.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/* Start at 0x40 in order to not conflict with existing "enum via_lighting_value",
+   even though they likely wouldn't be enabled together with vialrgb */
+enum {
+    vialrgb_set_mode = 0x40,
+};
+
+enum {
+    vialrgb_get_mode = 0x40,
+};
+
+void vialrgb_get_value(uint8_t *data, uint8_t length);
+void vialrgb_set_value(uint8_t *data, uint8_t length);
+void vialrgb_save(uint8_t *data, uint8_t length);
+
+#if defined(VIALRGB_ENABLE) && !defined(RGB_MATRIX_ENABLE)
+#error VIALRGB_ENABLE=yes requires RGB_MATRIX_ENABLE=yes
+#endif