diff --git a/.gitmodules b/.gitmodules index 9f9bb705..d2b990b1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "razer-drivers-win32"] path = razer-drivers-win32 url = https://github.com/rsandoz/razer-drivers-win32 -[submodule "dependencies/libcmmk"] - path = dependencies/libcmmk - url = https://github.com/chmod222/libcmmk.git diff --git a/Controllers/CoolerMasterController/CMMKController.cpp b/Controllers/CoolerMasterController/CMMKController.cpp index 974d6f3b..43d7b81e 100644 --- a/Controllers/CoolerMasterController/CMMKController.cpp +++ b/Controllers/CoolerMasterController/CMMKController.cpp @@ -4,34 +4,33 @@ | Driver for Coolermaster MasterKeys Keyboards | | | | Lukas N (chmod222) 28th Jun 2020 | +| Tam D (too.manyhobbies) 25th Apr 2021 | | | \*-------------------------------------------------------------------*/ #include "CMMKController.h" -#include -#include - -CMMKController::CMMKController(hid_device_info* _dev_info, wchar_t *_vendor, wchar_t *_device_name, char *_path) +CMMKController::CMMKController(hid_device* dev, hid_device_info* dev_info) { - std::wstring tmp_vendor_str = _vendor; - std::wstring tmp_device_str = _device_name; + location = dev_info->path; - std::wstring full_name = _vendor + std::wstring{L" "} + _device_name; + const int szTemp = 256; + wchar_t tmpName[szTemp]; - std::wstring_convert, wchar_t> converter; + hid_get_manufacturer_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + device_name = std::string(wName.begin(), wName.end()); - device_name = converter.to_bytes(full_name); + hid_get_product_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + device_name.append(" ").append(std::string(wName.begin(), wName.end())); - cmmk_attach_path(&cmmk_handle, _dev_info->path, _dev_info->product_id, -1); + cmmk_attach_path(&cmmk_handle, dev_info->path, dev_info->product_id, -1); char buf[32] = {0}; - cmmk_get_firmware_version(&cmmk_handle, buf, 32); firmware_version = buf; - - location = _path; } CMMKController::~CMMKController() @@ -39,17 +38,17 @@ CMMKController::~CMMKController() cmmk_detach(&cmmk_handle); } -std::string CMMKController::GetDeviceName() const +std::string CMMKController::GetDeviceName() { return device_name; } -std::string CMMKController::GetLocation() const +std::string CMMKController::GetLocation() { return location; } -std::string CMMKController::GetFirmwareVersion() const +std::string CMMKController::GetFirmwareVersion() { return firmware_version; } @@ -133,14 +132,21 @@ void CMMKController::SetMode(cmmk_effect_stars eff) cmmk_set_effect_stars(&cmmk_handle, &eff); } -bool CMMKController::PositionValid(int y, int x) const +void CMMKController::SetMode(cmmk_effect_snake eff) { - return cmmk_lookup_key_id(&cmmk_handle, y, x) >= 0; + ActivateEffect(CMMK_EFFECT_SNAKE); + cmmk_set_effect_snake(&cmmk_handle, &eff); +} + +bool CMMKController::PositionValid(int y, int x) +{ + return(cmmk_lookup_key_id(&cmmk_handle, y, x) >= 0); } void CMMKController::ActivateMode(int mode) { - if (current_mode != mode) { + if (current_mode != mode) + { cmmk_set_control_mode(&cmmk_handle, mode); current_mode = mode; @@ -152,9 +158,10 @@ void CMMKController::ActivateEffect(int effect) { ActivateMode(CMMK_EFFECT); - if (current_effect != effect) { + if (current_effect != effect) + { cmmk_set_active_effect(&cmmk_handle, (enum cmmk_effect_id)effect); current_effect = effect; } -} \ No newline at end of file +} diff --git a/Controllers/CoolerMasterController/CMMKController.h b/Controllers/CoolerMasterController/CMMKController.h index 049b01fe..4eca06b1 100644 --- a/Controllers/CoolerMasterController/CMMKController.h +++ b/Controllers/CoolerMasterController/CMMKController.h @@ -8,10 +8,7 @@ \*-------------------------------------------------------------------*/ #include -#include - #include - #include #pragma once @@ -19,12 +16,12 @@ class CMMKController { public: - CMMKController(hid_device_info* _dev_info, wchar_t *_vendor, wchar_t *_device_name, char *_path); - virtual ~CMMKController(); + CMMKController(hid_device* dev_handle, hid_device_info* dev_info); + ~CMMKController(); - std::string GetDeviceName() const; - std::string GetLocation() const; - std::string GetFirmwareVersion() const; + std::string GetDeviceName(); + std::string GetLocation(); + std::string GetFirmwareVersion(); void SetFirmwareControl(); void SetManualControl(); @@ -42,15 +39,16 @@ public: void SetMode(cmmk_effect_cross eff); void SetMode(cmmk_effect_raindrops eff); void SetMode(cmmk_effect_stars eff); + void SetMode(cmmk_effect_snake eff); - bool PositionValid(int y, int x) const; + bool PositionValid(int y, int x); private: void ActivateMode(int mode); void ActivateEffect(int effect); - int current_mode = -1; - int current_effect = -1; + int current_mode = -1; + int current_effect = -1; std::string device_name; std::string location; diff --git a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp index 02a51dbb..aa8dc728 100644 --- a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp +++ b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp @@ -3,20 +3,28 @@ #include "CMARGBcontroller.h" #include "CMSmallARGBController.h" #include "CMR6000Controller.h" +#include "CMMKController.h" #include "RGBController.h" #include "RGBController_CMMP750Controller.h" #include "RGBController_CMARGBController.h" #include "RGBController_CMSmallARGBController.h" #include "RGBController_CMR6000Controller.h" +#include "RGBController_CMMKController.h" #include #define COOLERMASTER_VID 0x2516 -#define COOLERMASTER_MP750_XL_PID 0x0109 -#define COOLERMASTER_MP750_MEDIUM_PID 0x0105 -#define COOLERMASTER_ARGB_PID 0x1011 -#define COOLERMASTER_SMALL_ARGB_PID 0x1000 -#define COOLERMASTER_RADEON_6000_PID 0x014D +#define COOLERMASTER_MP750_XL_PID 0x0109 +#define COOLERMASTER_MP750_MEDIUM_PID 0x0105 +#define COOLERMASTER_ARGB_PID 0x1011 +#define COOLERMASTER_SMALL_ARGB_PID 0x1000 +#define COOLERMASTER_RADEON_6000_PID 0x014D +#define COOLERMASTER_MASTERKEYS_PRO_L_PID CMMK_USB_MASTERKEYS_MK750 +#define COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID CMMK_USB_MASTERKEYS_PRO_L_WHITE +#define COOLERMASTER_MASTERKEYS_PRO_S_PID CMMK_USB_MASTERKEYS_PRO_S +#define COOLERMASTER_MASTERKEYS_MK750_PID CMMK_USB_MASTERKEYS_MK750 +#define COOLERMASTER_MASTERKEYS_SK630_PID CMMK_USB_MASTERKEYS_SK630 +#define COOLERMASTER_MASTERKEYS_SK650_PID CMMK_USB_MASTERKEYS_SK650 /******************************************************************************************\ * * @@ -77,8 +85,27 @@ void DetectCoolerMasterGPU(hid_device_info* info, const std::string&) } } -REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1); -REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1); -REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1); -REGISTER_HID_DETECTOR_IPU("Cooler Master Smalll ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1); -REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1); +void DetectCoolerMasterKeyboards(hid_device_info* info, const std::string&) +{ + + hid_device* dev = hid_open_path(info->path); + if(dev) + { + CMMKController* controller = new CMMKController(dev, info); + RGBController_CMMKController* rgb_controller = new RGBController_CMMKController(controller); + // Constructor sets the name + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1 ); +REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1 ); +REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_PID, 1, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID, 1, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_S_PID, 1, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master MK570", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_MK750_PID, 1, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK630_PID, 1, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK650_PID, 1, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master Smalll ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1); +REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 ); diff --git a/Controllers/CoolerMasterController/RGBController_CMMKController.cpp b/Controllers/CoolerMasterController/RGBController_CMMKController.cpp new file mode 100644 index 00000000..18965659 --- /dev/null +++ b/Controllers/CoolerMasterController/RGBController_CMMKController.cpp @@ -0,0 +1,467 @@ +/*-------------------------------------------------------------------*\ +| RGBController_CMMKController.cpp | +| | +| Driver for Coolermaster MasterKeys keyboards | +| | +| Lukas N (chmod222) 28th Jun 2020 | +| Tam D (too.manyhobbies) 25th Apr 2021 | +| | +\*-------------------------------------------------------------------*/ + +#include "RGBController_CMMKController.h" + +#include + +using namespace std::chrono_literals; + +#define CMMK_SPEED_MIN CMMK_SPEED0 +#define CMMK_SPEED_MID CMMK_SPEED2 +#define CMMK_SPEED_MAX CMMK_SPEED4 +#define CMMK_MODE_FIRMWARE 0xFF +#define CMMK_MODE_MANUAL 0x7F + +RGBController_CMMKController::RGBController_CMMKController(CMMKController* cmmk_ctrl) +{ + cmmk = cmmk_ctrl; + + name = cmmk->GetDeviceName(); + type = DEVICE_TYPE_KEYBOARD; + description = "Cooler Master MasterKeys Device"; + version = cmmk->GetFirmwareVersion(); + serial = ""; + location = cmmk->GetLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = CMMK_MODE_MANUAL; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Static; + Static.name = "Static"; + Static.value = CMMK_EFFECT_FULLY_LIT; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.colors_min = 1; + Static.colors_max = 1; + Static.colors.resize(1); + modes.push_back(Static); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = CMMK_EFFECT_BREATHE; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; + Breathing.speed_min = 0x20; + Breathing.speed_max = 0x20; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.colors_min = 1; + Breathing.colors_max = 1; + Breathing.colors.resize(1); + modes.push_back(Breathing); + + mode Cycle; + Cycle.name = "Spectrum Cycle"; + Cycle.value = CMMK_EFFECT_CYCLE; + Cycle.flags = MODE_FLAG_HAS_SPEED; + Cycle.speed_min = CMMK_SPEED_MIN; + Cycle.speed_max = CMMK_SPEED_MAX; + Cycle.color_mode = MODE_COLORS_NONE; + modes.push_back(Cycle); + + mode Single; + Single.name = "Flashing"; + Single.value = CMMK_EFFECT_SINGLE; + Single.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; + Single.speed_min = CMMK_SPEED_MIN; + Single.speed_max = CMMK_SPEED_MAX; + Single.color_mode = MODE_COLORS_MODE_SPECIFIC; + Single.colors_min = 2; + Single.colors_max = 2; + Single.colors.resize(2); + modes.push_back(Single); + + mode Wave; + Wave.name = "Rainbow Wave"; + Wave.value = CMMK_EFFECT_WAVE; + Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD; + Wave.speed_min = CMMK_SPEED_MIN; + Wave.speed_max = CMMK_SPEED_MAX; + Wave.color_mode = MODE_COLORS_MODE_SPECIFIC; + Wave.colors_min = 1; + Wave.colors_max = 1; + Wave.colors.resize(1); + modes.push_back(Wave); + + mode Ripple; + Ripple.name = "Ripple Effect"; + Ripple.value = CMMK_EFFECT_RIPPLE; + Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED; + Ripple.speed_min = CMMK_SPEED_MIN; + Ripple.speed_max = CMMK_SPEED_MAX; + Ripple.colors_min = 2; + Ripple.colors_max = 2; + Ripple.colors.resize(2); + modes.push_back(Ripple); + + mode Cross; + Cross.name = "Cross"; + Cross.value = CMMK_EFFECT_CROSS; + Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; + Cross.speed_min = CMMK_SPEED_MIN; + Cross.speed_max = CMMK_SPEED_MAX; + Cross.colors_min = 2; + Cross.colors_max = 2; + Cross.colors.resize(2); + modes.push_back(Cross); + + mode Raindrops; + Raindrops.name = "Raindrops"; + Raindrops.value = CMMK_EFFECT_RAINDROPS; + Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; + Raindrops.speed_min = CMMK_SPEED_MIN; + Raindrops.speed_max = CMMK_SPEED_MAX; + Raindrops.colors_min = 2; + Raindrops.colors_max = 2; + Raindrops.colors.resize(2); + modes.push_back(Raindrops); + + mode Stars; + Stars.name = "Starfield"; + Stars.value = CMMK_EFFECT_STARS; + Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; + Stars.speed_min = CMMK_SPEED_MIN; + Stars.speed_max = CMMK_SPEED_MAX; + Stars.colors_min = 2; + Stars.colors_max = 2; + Stars.colors.resize(2); + modes.push_back(Stars); + + mode Snake; + Snake.name = "Snake"; + Snake.value = CMMK_EFFECT_SNAKE; + Snake.flags = MODE_FLAG_HAS_SPEED; + Snake.speed_min = CMMK_SPEED_MIN; + Snake.speed_max = CMMK_SPEED_MAX; + modes.push_back(Snake); + + mode FirmwareControl; + FirmwareControl.name = "Firmware Controlled"; + FirmwareControl.value = 0xFF; + FirmwareControl.flags = 0; + modes.push_back(FirmwareControl); + + SetupZones(); +} + +RGBController_CMMKController::~RGBController_CMMKController() +{ + delete cmmk; +} + +void RGBController_CMMKController::SetupMatrixMap() +{ + for(int y = 0; y < CMMK_ROWS_MAX; y++) + { + for(int x = 0; x < CMMK_COLS_MAX; x++) + { + matrix_map[y][x] = 0xFFFFFFFF; + } + } + + for(size_t i = 0; i < leds.size(); i++) + { + led& l = leds[i]; + + int y = (l.value & 0xFF00) >> 8; + int x = (l.value & 0xFF); + + matrix_map[y][x] = i; + } +} + +void RGBController_CMMKController::SetupZones() +{ + for(int y = 0; y < CMMK_ROWS_MAX; y++) + { + for(int x = 0; x < CMMK_COLS_MAX; x++) + { + if(!cmmk->PositionValid(y, x)) + { + continue; + } + + std::stringstream namestrm; + + led key; + + namestrm << "Key @ Row " << (y + 1) << ", Column" << (x + 1); + + key.name = namestrm.str(); + key.value = (y & 0xFF) << 8 | (x & 0xFF); + + leds.push_back(key); + } + } + + zone KeyboardZone; + KeyboardZone.name = "Keyboard"; + KeyboardZone.type = ZONE_TYPE_MATRIX; + KeyboardZone.leds_min = leds.size(); + KeyboardZone.leds_max = leds.size(); + KeyboardZone.leds_count = leds.size(); + KeyboardZone.matrix_map = new matrix_map_type; + KeyboardZone.matrix_map->height = CMMK_ROWS_MAX; + KeyboardZone.matrix_map->width = CMMK_COLS_MAX; + KeyboardZone.matrix_map->map = (unsigned int *)&matrix_map; + + zones.push_back(KeyboardZone); + + SetupMatrixMap(); + SetupColors(); +} + +void RGBController_CMMKController::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +struct rgb map_to_cmmk_rgb(RGBColor input) +{ + return rgb + { + (uint8_t)RGBGetRValue(input), + (uint8_t)RGBGetGValue(input), + (uint8_t)RGBGetBValue(input) + }; +} + +enum cmmk_wave_direction map_to_cmmk_dir(int input) +{ + switch(input) + { + case MODE_DIRECTION_LEFT: + return CMMK_RIGHT_TO_LEFT; + + case MODE_DIRECTION_RIGHT: + return CMMK_LEFT_TO_RIGHT; + + case MODE_DIRECTION_UP: + return CMMK_FRONT_TO_BACK; + + case MODE_DIRECTION_DOWN: + return CMMK_BACK_TO_FRONT; + + default: + return CMMK_RIGHT_TO_LEFT; + } +} + +void copy_buffers(led* buf, RGBColor* colbuf, size_t n, struct cmmk_color_matrix& mat, std::atomic& dirty) +{ + dirty.store(false); + + for(size_t i = 0; i < n; i++) + { + led const& selected_led = buf[i]; + + int y = (selected_led.value & 0xFF00) >> 8; + int x = selected_led.value & 0xFF; + + struct rgb col = map_to_cmmk_rgb(colbuf[i]); + struct rgb ecol = mat.data[y][x]; + + if(ecol.R != col.R || ecol.G != col.G || ecol.B != col.B) + { + dirty.store(true); + + mat.data[y][x] = col; + } + } +} + +void RGBController_CMMKController::DeviceUpdateLEDs() +{ + copy_buffers(leds.data(), colors.data(), leds.size(), current_matrix, dirty); + + if(force_update.load() || dirty.load()) + { + cmmk->SetAll(current_matrix); + + force_update.store(false); + } +} + +void RGBController_CMMKController::UpdateZoneLEDs(int zone_idx) +{ + zone& z = zones[zone_idx]; + + copy_buffers(z.leds, z.colors, z.leds_count, current_matrix, dirty); + + if(force_update.load() || dirty.load()) + { + cmmk->SetAll(current_matrix); + + force_update.store(false); + } +} + +void RGBController_CMMKController::UpdateSingleLED(int led_idx) +{ + led& selected_led = leds[led_idx]; + + int y = (selected_led.value & 0xFF00) >> 8; + int x = selected_led.value & 0xFF; + + current_matrix.data[y][x] = map_to_cmmk_rgb(colors[led_idx]); + + cmmk->SetSingle(y, x, map_to_cmmk_rgb(colors[led_idx])); + dirty.store(false); +} + +void RGBController_CMMKController::SetCustomMode() +{ + active_mode = 1; +} + +void RGBController_CMMKController::DeviceUpdateMode() +{ + force_update.store(true); + + switch(modes[active_mode].value) + { + case CMMK_MODE_FIRMWARE: + cmmk->SetFirmwareControl(); + break; + + case CMMK_MODE_MANUAL: + cmmk->SetManualControl(); + break; + + case CMMK_EFFECT_FULLY_LIT: + { + cmmk_effect_fully_lit fully_lit_effect; + + fully_lit_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]); + + cmmk->SetMode(fully_lit_effect); + } + break; + + case CMMK_EFFECT_BREATHE: + { + cmmk_effect_breathe breathe_effect; + + breathe_effect.speed = (uint8_t)modes[active_mode].speed; + breathe_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]); + + cmmk->SetMode(breathe_effect); + } + break; + + case CMMK_EFFECT_CYCLE: + { + cmmk_effect_cycle cycle_effect; + + cycle_effect.speed = (uint8_t)modes[active_mode].speed; + + cmmk->SetMode(cycle_effect); + } + break; + + case CMMK_EFFECT_SINGLE: + { + cmmk_effect_single single_effect; + + single_effect.speed = (uint8_t)modes[active_mode].speed; + single_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]); + single_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]); + + cmmk->SetMode(single_effect); + } + break; + + case CMMK_EFFECT_WAVE: + { + cmmk_effect_wave wave_effect; + + wave_effect.speed = (uint8_t)modes[active_mode].speed; + wave_effect.direction = map_to_cmmk_dir(modes[active_mode].direction); + wave_effect.start = map_to_cmmk_rgb(modes[active_mode].colors[0]); + + cmmk->SetMode(wave_effect); + } + break; + + case CMMK_EFFECT_RIPPLE: + { + cmmk_effect_ripple ripple_effect; + + ripple_effect.speed = (uint8_t)modes[active_mode].speed; + ripple_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]); + ripple_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]); + + if(modes[active_mode].color_mode == MODE_COLORS_RANDOM) + { + ripple_effect.ripple_type = CMMK_RIPPLE_RANDOM_COLOR; + } + else + { + ripple_effect.ripple_type = CMMK_RIPPLE_GIVEN_COLOR; + } + + cmmk->SetMode(ripple_effect); + } + break; + + case CMMK_EFFECT_CROSS: + { + cmmk_effect_cross cross_effect; + + cross_effect.speed = (uint8_t)modes[active_mode].speed; + cross_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]); + cross_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]); + + cmmk->SetMode(cross_effect); + } + break; + + case CMMK_EFFECT_RAINDROPS: + { + cmmk_effect_raindrops raindrops_effect; + + raindrops_effect.speed = (uint8_t)modes[active_mode].speed; + raindrops_effect.interval = CMMK_SPEED_MID; + raindrops_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]); + raindrops_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]); + + cmmk->SetMode(raindrops_effect); + } + break; + + case CMMK_EFFECT_STARS: + { + cmmk_effect_stars stars_effect; + + stars_effect.speed = (uint8_t)modes[active_mode].speed; + stars_effect.interval = CMMK_SPEED_MID; + stars_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]); + stars_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]); + + cmmk->SetMode(stars_effect); + } + break; + + case CMMK_EFFECT_SNAKE: + { + cmmk_effect_snake snake_effect; + + snake_effect.speed = (uint8_t)modes[active_mode].speed; + + cmmk->SetMode(snake_effect); + } + break; + } +} diff --git a/RGBController/RGBController_CMMKController.h b/Controllers/CoolerMasterController/RGBController_CMMKController.h similarity index 92% rename from RGBController/RGBController_CMMKController.h rename to Controllers/CoolerMasterController/RGBController_CMMKController.h index c86a30eb..3de94528 100644 --- a/RGBController/RGBController_CMMKController.h +++ b/Controllers/CoolerMasterController/RGBController_CMMKController.h @@ -4,6 +4,7 @@ | Driver for Coolermaster MasterKeys keyboards | | | | Lukas N (chmod222) 28th Jun 2020 | +| Tam D (too.manyhobbies) 25th Apr 2021 | | | \*-------------------------------------------------------------------*/ @@ -12,8 +13,6 @@ #include "RGBController.h" #include "CMMKController.h" -#include - class RGBController_CMMKController : public RGBController { public: @@ -28,7 +27,7 @@ public: void UpdateSingleLED(int led); void SetCustomMode(); - void UpdateMode(); + void DeviceUpdateMode(); private: void SetupMatrixMap(); diff --git a/OpenRGB.pro b/OpenRGB.pro index 4ac7d491..e611bf2e 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -51,6 +51,7 @@ INCLUDEPATH += dependencies/CRCpp/ \ dependencies/json/ \ dependencies/libe131/src/ \ + dependencies/libcmmk/include/ \ i2c_smbus/ \ i2c_tools/ \ net_port/ \ @@ -128,6 +129,7 @@ INCLUDEPATH += HEADERS += \ dependencies/ColorWheel/ColorWheel.h \ dependencies/json/json.hpp \ + dependencies/libcmmk/include/libcmmk/libcmmk.h \ LogManager.h \ NetworkClient.h \ NetworkProtocol.h \ @@ -185,10 +187,12 @@ HEADERS += Controllers/CoolerMasterController/CMMP750Controller.h \ Controllers/CoolerMasterController/CMSmallARGBController.h \ Controllers/CoolerMasterController/CMR6000Controller.h \ + Controllers/CoolerMasterController/CMMKController.h \ Controllers/CoolerMasterController/RGBController_CMARGBController.h \ Controllers/CoolerMasterController/RGBController_CMMP750Controller.h \ Controllers/CoolerMasterController/RGBController_CMSmallARGBController.h \ Controllers/CoolerMasterController/RGBController_CMR6000Controller.h \ + Controllers/CoolerMasterController/RGBController_CMMKController.h \ Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \ Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.h \ Controllers/CorsairHydroController/CorsairHydroController.h \ @@ -366,6 +370,7 @@ SOURCES += dependencies/dmiinfo.cpp \ dependencies/ColorWheel/ColorWheel.cpp \ dependencies/libe131/src/e131.c \ + dependencies/libcmmk/src/libcmmk.c \ main.cpp \ cli.cpp \ LogManager.cpp \ @@ -426,11 +431,13 @@ SOURCES += Controllers/CoolerMasterController/CMMP750Controller.cpp \ Controllers/CoolerMasterController/CMSmallARGBController.cpp \ Controllers/CoolerMasterController/CMR6000Controller.cpp \ + Controllers/CoolerMasterController/CMMKController.cpp \ Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp \ Controllers/CoolerMasterController/RGBController_CMARGBController.cpp \ Controllers/CoolerMasterController/RGBController_CMMP750Controller.cpp \ Controllers/CoolerMasterController/RGBController_CMSmallARGBController.cpp \ Controllers/CoolerMasterController/RGBController_CMR6000Controller.cpp \ + Controllers/CoolerMasterController/RGBController_CMMKController.cpp \ Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.cpp \ Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumControllerDetect.cpp \ Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.cpp \ diff --git a/README.md b/README.md index d7008c6e..171020d7 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ There have been two instances of hardware damage in OpenRGB's development and we * OpenRazer-Win32: https://github.com/CalcProgrammer1/openrazer-win32 * Qt-Plus (ColorWheel): https://github.com/liuyanghejerry/Qt-Plus * AMD ADL Libraries: https://github.com/GPUOpen-LibrariesAndSDKs/display-library + * libcmmk: https://github.com/chmod222/libcmmk ## Projects Researched diff --git a/RGBController/RGBController_CMMKController.cpp b/RGBController/RGBController_CMMKController.cpp deleted file mode 100644 index 4c3db044..00000000 --- a/RGBController/RGBController_CMMKController.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/*-------------------------------------------------------------------*\ -| RGBController_CMMKController.cpp | -| | -| Driver for Coolermaster MasterKeys keyboards | -| | -| Lukas N (chmod222) 28th Jun 2020 | -| | -\*-------------------------------------------------------------------*/ - -#include "RGBController_CMMKController.h" - -#include -#include - -using namespace std::chrono_literals; - -RGBController_CMMKController::RGBController_CMMKController(CMMKController* cmmk_ctrl) -{ - cmmk = cmmk_ctrl; - - name = cmmk->GetDeviceName(); - type = DEVICE_TYPE_KEYBOARD; - description = cmmk->GetDeviceName(); - version = cmmk->GetFirmwareVersion(); - serial = ""; - location = cmmk->GetLocation(); - - mode FirmwareControl; - FirmwareControl.name = "Firmware Controlled"; - FirmwareControl.value = 0xff; - FirmwareControl.flags = 0; - modes.push_back(FirmwareControl); - - mode CustomKeys; - CustomKeys.name = "Customized LEDs"; - CustomKeys.value = 0x7f; - CustomKeys.flags = MODE_FLAG_HAS_PER_LED_COLOR; - CustomKeys.color_mode = MODE_COLORS_PER_LED; - modes.push_back(CustomKeys); - - mode FullLit; - FullLit.name = "Single Color"; - FullLit.value = CMMK_EFFECT_FULLY_LIT; - FullLit.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; - FullLit.color_mode = MODE_COLORS_MODE_SPECIFIC; - FullLit.colors_min = 1; - FullLit.colors_max = 1; - FullLit.colors.resize(1); - modes.push_back(FullLit); - - mode Breathe; - Breathe.name = "Breathe"; - Breathe.value = CMMK_EFFECT_BREATHE; - Breathe.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; - Breathe.color_mode = MODE_COLORS_MODE_SPECIFIC; - Breathe.colors_min = 1; - Breathe.colors_max = 1; - Breathe.colors.resize(1); - Breathe.speed_min = CMMK_SPEED0; - Breathe.speed_max = CMMK_SPEED4; - modes.push_back(Breathe); - - mode Cycle; - Cycle.name = "Cycle"; - Cycle.value = CMMK_EFFECT_CYCLE; - Cycle.flags = MODE_FLAG_HAS_SPEED; - Cycle.color_mode = MODE_COLORS_NONE; - Cycle.speed_min = CMMK_SPEED0; - Cycle.speed_max = CMMK_SPEED4; - modes.push_back(Cycle); - - mode Single; - Single.name = "Single Key Fade-Out"; - Single.value = CMMK_EFFECT_SINGLE; - Single.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; - Single.color_mode = MODE_COLORS_MODE_SPECIFIC; - Single.colors_min = 2; - Single.colors_max = 2; - Single.colors.resize(2); - Single.speed_min = CMMK_SPEED0; - Single.speed_max = CMMK_SPEED4; - modes.push_back(Single); - - mode Wave; - Wave.name = "Wave"; - Wave.value = CMMK_EFFECT_WAVE; - Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD; - Wave.color_mode = MODE_COLORS_MODE_SPECIFIC; - Wave.colors_min = 1; - Wave.colors_max = 1; - Wave.colors.resize(1); - Wave.speed_min = CMMK_SPEED0; - Wave.speed_max = CMMK_SPEED4; - modes.push_back(Wave); - - mode Ripple; - Ripple.name = "Ripple Effect"; - Ripple.value = CMMK_EFFECT_RIPPLE; - Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED; - Ripple.colors_min = 2; - Ripple.colors_max = 2; - Ripple.colors.resize(2); - Ripple.speed_min = CMMK_SPEED0; - Ripple.speed_max = CMMK_SPEED4; - modes.push_back(Ripple); - - mode Cross; - Cross.name = "Cross Effect"; - Cross.value = CMMK_EFFECT_CROSS; - Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; - Cross.colors_min = 2; - Cross.colors_max = 2; - Cross.colors.resize(2); - Cross.speed_min = CMMK_SPEED0; - Cross.speed_max = CMMK_SPEED4; - modes.push_back(Cross); - - mode Raindrops; - Raindrops.name = "Raindrops Effect"; - Raindrops.value = CMMK_EFFECT_RAINDROPS; - Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; - Raindrops.colors_min = 2; - Raindrops.colors_max = 2; - Raindrops.colors.resize(2); - Raindrops.speed_min = CMMK_SPEED0; - Raindrops.speed_max = CMMK_SPEED4; - modes.push_back(Raindrops); - - mode Stars; - Stars.name = "Starfield Effect"; - Stars.value = CMMK_EFFECT_STARS; - Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED; - Stars.colors_min = 2; - Stars.colors_max = 2; - Stars.colors.resize(2); - Stars.speed_min = CMMK_SPEED0; - Stars.speed_max = CMMK_SPEED4; - modes.push_back(Stars); - - SetupZones(); -} - -RGBController_CMMKController::~RGBController_CMMKController() -{ - delete cmmk; -} - -void RGBController_CMMKController::SetupMatrixMap() -{ - for (int y = 0; y < CMMK_ROWS_MAX; ++y) { - for (int x = 0; x < CMMK_COLS_MAX; ++x) { - matrix_map[y][x] = 0xFFFFFFFF; - } - } - - for (size_t i = 0; i < leds.size(); ++i) { - led const& l = leds[i]; - - int y = (l.value & 0xFF00) >> 8; - int x = l.value & 0xFF; - - matrix_map[y][x] = i; - } -} - -void RGBController_CMMKController::SetupZones() -{ - for (int y = 0; y < CMMK_ROWS_MAX; ++y) { - for (int x = 0; x < CMMK_COLS_MAX; ++x) { - if (!cmmk->PositionValid(y, x)) { - continue; - } - - std::stringstream namestrm; - - led key; - - namestrm << "Key @ Row " << (y + 1) << ", Column" << (x + 1); - - key.name = namestrm.str(); - key.value = (y & 0xFF) << 8 | (x & 0xFF); - - leds.push_back(key); - } - } - - zone KeyboardZone; - KeyboardZone.name = "Keyboard"; - KeyboardZone.type = ZONE_TYPE_MATRIX; - KeyboardZone.leds_min = leds.size(); - KeyboardZone.leds_max = leds.size(); - KeyboardZone.leds_count = leds.size(); - KeyboardZone.matrix_map = new matrix_map_type; - KeyboardZone.matrix_map->height = CMMK_ROWS_MAX; - KeyboardZone.matrix_map->width = CMMK_COLS_MAX; - KeyboardZone.matrix_map->map = (unsigned int *)&matrix_map; - - zones.push_back(KeyboardZone); - - SetupMatrixMap(); - SetupColors(); -} - -void RGBController_CMMKController::ResizeZone(int /*zone*/, int /*new_size*/) -{ - /*---------------------------------------------------------*\ - | This device does not support resizing zones | - \*---------------------------------------------------------*/ -} - -namespace { - struct rgb map_to_cmmk_rgb(RGBColor input) { - return rgb { - (uint8_t)RGBGetRValue(input), - (uint8_t)RGBGetGValue(input), - (uint8_t)RGBGetBValue(input) - }; - } - - enum cmmk_wave_direction map_to_cmmk_dir(int input) { - switch (input) { - case MODE_DIRECTION_LEFT: return CMMK_RIGHT_TO_LEFT; - case MODE_DIRECTION_RIGHT: return CMMK_LEFT_TO_RIGHT; - case MODE_DIRECTION_UP: return CMMK_FRONT_TO_BACK; - case MODE_DIRECTION_DOWN: return CMMK_BACK_TO_FRONT; - default: assert(false && "unreachable"); - } - } - - void copy_buffers(led* buf, RGBColor* colbuf, size_t n, struct cmmk_color_matrix& mat, std::atomic& dirty) { - dirty.store(false); - - for (size_t i = 0; i < n; ++i) { - led const& selected_led = buf[i]; - - int y = (selected_led.value & 0xFF00) >> 8; - int x = selected_led.value & 0xFF; - - struct rgb col = map_to_cmmk_rgb(colbuf[i]); - struct rgb ecol = mat.data[y][x]; - - if (ecol.R != col.R || ecol.G != col.G || ecol.B != col.B) { - dirty.store(true); - - mat.data[y][x] = col; - } - } - } -} - -void RGBController_CMMKController::DeviceUpdateLEDs() -{ - copy_buffers(leds.data(), colors.data(), leds.size(), current_matrix, dirty); - - if (force_update.load() || dirty.load()) { - cmmk->SetAll(current_matrix); - - force_update.store(false); - } -} - -void RGBController_CMMKController::UpdateZoneLEDs(int _zone) -{ - zone const& z = zones[_zone]; - - copy_buffers(z.leds, z.colors, z.leds_count, current_matrix, dirty); - - if (force_update.load() || dirty.load()) { - cmmk->SetAll(current_matrix); - - force_update.store(false); - } -} - -void RGBController_CMMKController::UpdateSingleLED(int _led) -{ - led const& selected_led = leds[_led]; - - int y = (selected_led.value & 0xFF00) >> 8; - int x = selected_led.value & 0xFF; - - current_matrix.data[y][x] = map_to_cmmk_rgb(colors[_led]); - - cmmk->SetSingle(y, x, map_to_cmmk_rgb(colors[_led])); - dirty.store(false); -} - -void RGBController_CMMKController::SetCustomMode() -{ - force_update.store(true); - - active_mode = 1; -} - -void RGBController_CMMKController::UpdateMode() -{ - force_update.store(true); - - switch(modes[active_mode].value) - { - case 0xff: - cmmk->SetFirmwareControl(); - break; - - case 0x7f: - cmmk->SetManualControl(); - break; - - case CMMK_EFFECT_FULLY_LIT: - cmmk->SetMode(cmmk_effect_fully_lit { - map_to_cmmk_rgb(modes[active_mode].colors[0]) - }); - - break; - - case CMMK_EFFECT_BREATHE: - cmmk->SetMode(cmmk_effect_breathe { - (uint8_t)modes[active_mode].speed, - map_to_cmmk_rgb(modes[active_mode].colors[0]) - }); - - break; - - case CMMK_EFFECT_CYCLE: - cmmk->SetMode(cmmk_effect_cycle { - (uint8_t)modes[active_mode].speed - }); - - break; - - case CMMK_EFFECT_SINGLE: - cmmk->SetMode(cmmk_effect_single { - (uint8_t)modes[active_mode].speed, - - map_to_cmmk_rgb(modes[active_mode].colors[0]), - map_to_cmmk_rgb(modes[active_mode].colors[1]) - }); - - break; - - case CMMK_EFFECT_WAVE: - cmmk->SetMode(cmmk_effect_wave { - (uint8_t)modes[active_mode].speed, - map_to_cmmk_dir(modes[active_mode].direction), - map_to_cmmk_rgb(modes[active_mode].colors[0]) - }); - - break; - - case CMMK_EFFECT_RIPPLE: - cmmk->SetMode(cmmk_effect_ripple { - (uint8_t)modes[active_mode].speed, - modes[active_mode].color_mode == MODE_COLORS_RANDOM - ? CMMK_RIPPLE_RANDOM_COLOR - : CMMK_RIPPLE_GIVEN_COLOR, - map_to_cmmk_rgb(modes[active_mode].colors[0]), - map_to_cmmk_rgb(modes[active_mode].colors[1]) - }); - - break; - - case CMMK_EFFECT_CROSS: - cmmk->SetMode(cmmk_effect_cross { - (uint8_t)modes[active_mode].speed, - map_to_cmmk_rgb(modes[active_mode].colors[0]), - map_to_cmmk_rgb(modes[active_mode].colors[1]) - }); - - break; - - case CMMK_EFFECT_RAINDROPS: - cmmk->SetMode(cmmk_effect_raindrops { - (uint8_t)modes[active_mode].speed, - CMMK_SPEED2, - map_to_cmmk_rgb(modes[active_mode].colors[0]), - map_to_cmmk_rgb(modes[active_mode].colors[1]) - }); - - break; - - case CMMK_EFFECT_STARS: - cmmk->SetMode(cmmk_effect_stars { - (uint8_t)modes[active_mode].speed, - CMMK_SPEED2, - map_to_cmmk_rgb(modes[active_mode].colors[0]), - map_to_cmmk_rgb(modes[active_mode].colors[1]) - }); - - break; - } -} diff --git a/dependencies/libcmmk b/dependencies/libcmmk deleted file mode 160000 index a8472d14..00000000 --- a/dependencies/libcmmk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a8472d1494049eb96c5c4fefbb309654d17ac20d diff --git a/dependencies/libcmmk/include/libcmmk/libcmmk.h b/dependencies/libcmmk/include/libcmmk/libcmmk.h new file mode 100644 index 00000000..2a98cd48 --- /dev/null +++ b/dependencies/libcmmk/include/libcmmk/libcmmk.h @@ -0,0 +1,422 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +#ifndef LIBCMMK_H +#define LIBCMMK_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#define CMMK_ROWS_MAX 7 +#define CMMK_COLS_MAX 22 + +#define CMMK_KEYLIST_SIZE 256 + +/* + * If we have C99 support (which we do, because libusb-1.0 requires it...), define some handy + * macros. + */ +#if __STDC_VERSION__ >= 199901L + /* struct rgb from 0xRRGGBB */ + #define MKRGB(hex) (struct rgb){((hex) >> 16) & 0xFF, ((hex) >> 8) & 0xFF, (hex) & 0xFF } + + /* struct rgb from single parts */ + #define MKRGBS(r, g, b) (struct rgb){ (r), (g), (b) } +#endif + +struct rgb { + unsigned char R; + unsigned char G; + unsigned char B; +}; + + +/* Result codes */ +enum cmmk_result { + CMMK_OK = 0, + CMMK_ERR, /* Non-specific error */ + CMMK_LAYOUT_DETECTION_FAILED, + CMMK_USB_COMM, /* An error happened while trying to talk to the device */ + CMMK_INVAL, /* Invalid parameter given */ +}; + +/* + * Physical USB product IDs for general device type detection only. + */ +enum cmmk_product { + CMMK_USB_MASTERKEYS_PRO_L = 0x003b, + CMMK_USB_MASTERKEYS_PRO_L_WHITE = 0x0047, + CMMK_USB_MASTERKEYS_PRO_S = 0x003c, + CMMK_USB_MASTERKEYS_MK750 = 0x0067, + CMMK_USB_MASTERKEYS_SK630 = 0x0089, + CMMK_USB_MASTERKEYS_SK650 = 0x008d, +}; + +/* + * The specific layout of a given device. + */ +enum cmmk_layout { + CMMK_LAYOUT_US_S, + CMMK_LAYOUT_US_L, /* TODO */ + CMMK_LAYOUT_US_MK750, /* TODO */ + CMMK_LAYOUT_US_SK630, /* TODO */ + CMMK_LAYOUT_US_SK650, /* TODO */ + CMMK_LAYOUT_EU_S, /* TODO */ + CMMK_LAYOUT_EU_L, + CMMK_LAYOUT_EU_MK750, + CMMK_LAYOUT_EU_SK630, + CMMK_LAYOUT_EU_SK650, + + CMMK_LAYOUT_INVAL /* end marker */ +}; + +/* Apparently can be anything in range [0x00, 0x50]. + * Over 0x50 it just stops animating */ +enum cmmk_effect_speed { + CMMK_SPEED0 = 0x46, + CMMK_SPEED1 = 0x41, + CMMK_SPEED2 = 0x38, + CMMK_SPEED3 = 0x3D, + CMMK_SPEED4 = 0x31 +}; + +enum cmmk_wave_direction { + CMMK_LEFT_TO_RIGHT = 0x00, + CMMK_RIGHT_TO_LEFT = 0x04, + CMMK_BACK_TO_FRONT = 0x02, + CMMK_FRONT_TO_BACK = 0x06 +}; + +enum cmmk_ripple_type { + CMMK_RIPPLE_GIVEN_COLOR, /* use the given color */ + CMMK_RIPPLE_RANDOM_COLOR = 0x80 /* use a random color */ +}; + +enum cmmk_control_mode { + /* Firmware controls everything */ + CMMK_FIRMWARE = 0x00, + + /* Firmware controlled effect, configured via software */ + CMMK_EFFECT = 0x01, + + /* Manual control of everything */ + CMMK_MANUAL = 0x02, + + /* Profile setup (may actually be a misnomer, as saving the profile works + * in effect mode as well */ + CMMK_PROFILE_CUSTOMIZATION = 0x03 +}; + +enum cmmk_effect_id { + CMMK_EFFECT_FULLY_LIT = 0x00, + CMMK_EFFECT_BREATHE = 0x01, + CMMK_EFFECT_CYCLE = 0x02, + CMMK_EFFECT_SINGLE = 0x03, + CMMK_EFFECT_WAVE = 0x04, + CMMK_EFFECT_RIPPLE = 0x05, + CMMK_EFFECT_CROSS = 0x06, + CMMK_EFFECT_RAINDROPS = 0x07, + CMMK_EFFECT_STARS = 0x08, + CMMK_EFFECT_SNAKE = 0x09, + CMMK_EFFECT_CUSTOMIZED = 0x0a, + CMMK_EFFECT_MULTILAYER = 0xe0, + CMMK_EFFECT_OFF = 0xfe +}; + +/* These enums are only used for display or similar purposes. + * + * All the important layout information is contained in `enum cmmk_layout'. But because + * most of the time, library users really want the model and layout information separated, + * these two helpers abstract it away a bit. */ +enum cmmk_layout_type { + CMMK_LAYOUT_TYPE_ANSI, + CMMK_LAYOUT_TYPE_ISO +}; + +enum cmmk_product_type { + CMMK_PRODUCT_MASTERKEYS_PRO_L, + CMMK_PRODUCT_MASTERKEYS_PRO_S, + CMMK_PRODUCT_MASTERKEYS_MK750, + CMMK_PRODUCT_MASTERKEYS_SK630, + CMMK_PRODUCT_MASTERKEYS_SK650, +}; + +/* + * Attach to and detach from USB device + */ +struct cmmk { + /* libusb_context *cxt; */ + hid_device *dev; + + /* + * Internal product IDs that are not all that useful outside the library. + */ + int product; + int layout; + + /* + * Lookup map to get matrix positions for keys in constant time. + */ + int8_t rowmap[CMMK_KEYLIST_SIZE]; + int8_t colmap[CMMK_KEYLIST_SIZE]; + + int multilayer_mode; +}; + +/* Helper types because passing multi dim arrays as parameter is yucky */ +struct cmmk_color_matrix { + struct rgb data[CMMK_ROWS_MAX][CMMK_COLS_MAX]; +}; + +struct cmmk_effect_matrix { + uint8_t data[CMMK_ROWS_MAX][CMMK_COLS_MAX]; /* values as type of enum cmmk_effect_id */ +}; + +/* Generic effect type for when type safety becomes too verbose. + * + * No sanity checking is done before sending this off to the firmware, so try to stay within + * normal parameters. */ +struct cmmk_generic_effect { + int p1; + int p2; + int p3; + + struct rgb color1; + struct rgb color2; +}; + +struct cmmk_effect_fully_lit { + struct rgb color; +}; + +struct cmmk_effect_breathe { + int speed; + + struct rgb color; +}; + +struct cmmk_effect_cycle { + int speed; +}; + +struct cmmk_effect_single { + int speed; + + struct rgb active; + struct rgb rest; +}; + +struct cmmk_effect_wave { + int speed; + + enum cmmk_wave_direction direction; + + struct rgb start; +}; + +struct cmmk_effect_ripple { + int speed; + + enum cmmk_ripple_type ripple_type; + + struct rgb active; + struct rgb rest; +}; + +struct cmmk_effect_cross { + int speed; + + struct rgb active; + struct rgb rest; +}; + +struct cmmk_effect_raindrops { + int speed; + int interval; + + struct rgb active; + struct rgb rest; +}; + +struct cmmk_effect_stars { + int speed; + int interval; + + struct rgb active; + struct rgb rest; +}; + +struct cmmk_effect_snake { + int speed; +}; + +/* Tries to find a connected, compatible device. Returns 0 and sets *product to the + * first device it finds */ +int cmmk_find_device(int *product); + +/* + * If layout = -1, try to automatically determine the layout. Otherwise, use one of the values + * enumerated in `enum cmmk_layout'. + * + * Note that autodetection is based on unproven theories right now (see issue #10). + * Your mileage may vary. + * + * If layout autodetection fails, 1 is returned and cmmk_detach is called implicitely. + */ +int cmmk_attach(struct cmmk *dev, int product, int layout); +int cmmk_attach_path(struct cmmk *dev, char const *path, int product, int layout); +int cmmk_detach(struct cmmk *dev); + +/* Resets the layout to the given ID and regenerates lookup tables */ +int cmmk_force_layout(struct cmmk *dev, int layout); + +/* fw must be up to 8 bytes to read the entire version string */ +int cmmk_get_firmware_version(struct cmmk *dev, char *fw, size_t fwsiz); + +enum cmmk_product_type cmmk_get_device_model(struct cmmk *dev); +enum cmmk_layout_type cmmk_get_device_layout(struct cmmk *dev); + +const char * cmmk_product_to_str(int product); +const char * cmmk_layout_to_str(int layout); + +/* + * Enter and leave direct control mode. Any control commands outside of control + * mode are ignored. Enabling control mode while inside control mode will reset + * active effect and allow direct control over LEDs. + */ +int cmmk_set_control_mode(struct cmmk *dev, int mode); + +/* Only meaningful in profile customization mode */ +int cmmk_get_active_profile(struct cmmk *dev, int *prof); +int cmmk_set_active_profile(struct cmmk *dev, int prof); + +int cmmk_save_active_profile(struct cmmk *dev); + +/* Predefined effects */ +int cmmk_get_active_effect(struct cmmk *dev, enum cmmk_effect_id *eff); +int cmmk_set_active_effect(struct cmmk *dev, enum cmmk_effect_id eff); + +/* Fetch the list of enabled effects. Updates "n" with the number of effects actually + * read. + */ +int cmmk_get_enabled_effects( + struct cmmk *dev, + enum cmmk_effect_id *effs, + size_t siz, + size_t *n); + +/* Sets the list of enabled effects. Buffer size is implied and should of course be + * at least as big as n. */ +int cmmk_set_enabled_effects( + struct cmmk *dev, + enum cmmk_effect_id const *effs, + size_t n); + +/* + * Get and set effect configurations. + * + * Caveeat: In customization mode, you can only change the configuration of an effect when it is + * currently active. This does not seem to be the case in effects mode. + */ +int cmmk_get_effect(struct cmmk *dev, enum cmmk_effect_id id, struct cmmk_generic_effect *eff); +int cmmk_set_effect(struct cmmk *dev, enum cmmk_effect_id id, struct cmmk_generic_effect const *eff); + +int cmmk_get_effect_fully_lit(struct cmmk *dev, struct cmmk_effect_fully_lit *eff); +int cmmk_set_effect_fully_lit(struct cmmk *dev, struct cmmk_effect_fully_lit const *eff); + +int cmmk_get_effect_breathe(struct cmmk *dev, struct cmmk_effect_breathe *eff); +int cmmk_set_effect_breathe(struct cmmk *dev, struct cmmk_effect_breathe const *eff); + +int cmmk_get_effect_cycle(struct cmmk *dev, struct cmmk_effect_cycle *eff); +int cmmk_set_effect_cycle(struct cmmk *dev, struct cmmk_effect_cycle const *eff); + +int cmmk_get_effect_single(struct cmmk *dev, struct cmmk_effect_single *eff); +int cmmk_set_effect_single(struct cmmk *dev, struct cmmk_effect_single const *eff); + +int cmmk_get_effect_wave(struct cmmk *dev, struct cmmk_effect_wave *eff); +int cmmk_set_effect_wave(struct cmmk *dev, struct cmmk_effect_wave const *eff); + +int cmmk_get_effect_ripple(struct cmmk *dev, struct cmmk_effect_ripple *eff); +int cmmk_set_effect_ripple(struct cmmk *dev, struct cmmk_effect_ripple const *eff); + +int cmmk_get_effect_cross(struct cmmk *dev, struct cmmk_effect_cross *eff); +int cmmk_set_effect_cross(struct cmmk *dev, struct cmmk_effect_cross const *eff); + +int cmmk_get_effect_raindrops(struct cmmk *dev, struct cmmk_effect_raindrops *eff); +int cmmk_set_effect_raindrops(struct cmmk *dev, struct cmmk_effect_raindrops const *eff); + +int cmmk_get_effect_stars(struct cmmk *dev, struct cmmk_effect_stars *eff); +int cmmk_set_effect_stars(struct cmmk *dev, struct cmmk_effect_stars const *eff); + +int cmmk_get_effect_snake(struct cmmk *dev, struct cmmk_effect_snake *eff); +int cmmk_set_effect_snake(struct cmmk *dev, struct cmmk_effect_snake const *eff); + +/* + * colmap *must* be at least 6x22. Otherwise, segmentation faults ensue. + * + * CAVEAT: The result will be wrong immediately after switching profiles. A few milliseconds + * of delay need to be inserted after the switch and before the query. + */ +int cmmk_get_customized_leds(struct cmmk *dev, struct cmmk_color_matrix *colmap); +int cmmk_set_customized_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap); + +/* + * Switch multilayer mode on (active > 0) or off (active == 0). + * + * Affects effect configuration getters and setters. + */ +int cmmk_switch_multilayer(struct cmmk *dev, int active); + +int cmmk_get_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix *effmap); +int cmmk_set_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix const *effmap); + +/* + * Set the single key `key' to the given color. + */ +int cmmk_set_single_key_by_id(struct cmmk *dev, int key, struct rgb const *color); + +/* + * Set the single key in row `row` and column `col` to the given color. + */ +int cmmk_set_single_key(struct cmmk *dev, int row, int col, struct rgb const *color); +int cmmk_lookup_key_id(struct cmmk *dev, int row, int col); +/* + * Set the entire keyboard to the given color. + */ +int cmmk_set_all_single(struct cmmk *dev, struct rgb const *col); +/* + * Set the entire keyboard in one step from the given map. + * + * Keys in the map are indized by their individual mappings, so + * colmap[K_ESC] will address the ESC key, much like + * set_single_key(..., K_ESC, ...) will. + */ +int cmmk_set_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap); + +#ifdef CMMK_DECLARE_DEBUG_FUNCTIONS + int cmmk_send_anything(struct cmmk *dev, unsigned char *data, size_t data_siz); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* !defined(LIBCMMK_H) */ diff --git a/dependencies/libcmmk/src/libcmmk.c b/dependencies/libcmmk/src/libcmmk.c new file mode 100644 index 00000000..086f2af3 --- /dev/null +++ b/dependencies/libcmmk/src/libcmmk.c @@ -0,0 +1,1065 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +#include + +#ifndef WIN32 +#include /* getuid() */ +#endif +#include /* memset() */ +#include + +#include + +#ifdef CMMK_TRACE +#include +#include +#endif + +/* Initialize keyboard layouts */ +typedef int16_t keyboard_layout[CMMK_ROWS_MAX][CMMK_COLS_MAX]; + +#include "mappings/iso/pro_s.h" +#include "mappings/iso/pro_l.h" +#include "mappings/iso/mk750.h" +#include "mappings/iso/sk630.h" +#include "mappings/iso/sk650.h" + +#include "mappings/ansi/pro_s.h" +#include "mappings/ansi/pro_l.h" +#include "mappings/ansi/mk750.h" +#include "mappings/ansi/sk630.h" +#include "mappings/ansi/sk650.h" + +static keyboard_layout const *keyboard_layouts[] = { + [CMMK_LAYOUT_US_S] = &layout_ansi_pro_s, + [CMMK_LAYOUT_US_L] = &layout_ansi_pro_l, + [CMMK_LAYOUT_US_MK750] = &layout_ansi_mk750, + [CMMK_LAYOUT_US_SK630] = &layout_ansi_sk630, + [CMMK_LAYOUT_US_SK650] = &layout_ansi_sk650, + [CMMK_LAYOUT_EU_S] = &layout_iso_pro_s, + [CMMK_LAYOUT_EU_L] = &layout_iso_pro_l, + [CMMK_LAYOUT_EU_MK750] = &layout_iso_mk750, + [CMMK_LAYOUT_EU_SK630] = &layout_iso_sk630, + [CMMK_LAYOUT_EU_SK650] = &layout_iso_sk650, +}; + +/* Some global definitions */ +enum { + CMMK_USB_VENDOR = 0x2516, + + CMMK_USB_INTERFACE = 1, + + CMMK_USB_EP_IN = 0x04, + CMMK_USB_EP_OUT = 0x83 +}; + +/* linear -> matrix */ +static int transpose(struct cmmk *dev, struct rgb const *linear, struct cmmk_color_matrix *matrix) +{ + int i; + + for (i = 0; i < CMMK_KEYLIST_SIZE; ++i) { + if (dev->rowmap[i] < 0 || dev->colmap[i] < 0) { + continue; + } + + matrix->data[dev->rowmap[i]][dev->colmap[i]] = linear[i]; + } + + return CMMK_OK; +} + +/* Too bad C doesn't have templates */ +static int transpose_effects(struct cmmk *dev, uint8_t const *linear, struct cmmk_effect_matrix *matrix) +{ + int i; + + for (i = 0; i < CMMK_KEYLIST_SIZE; ++i) { + if (dev->rowmap[i] < 0 || dev->colmap[i] < 0) { + continue; + } + + matrix->data[dev->rowmap[i]][dev->colmap[i]] = linear[i]; + } + + return CMMK_OK; +} + +/* matrix -> linear */ +int transpose_reverse(struct cmmk *dev, struct cmmk_color_matrix const *matrix, struct rgb *linear) +{ + keyboard_layout const *layout = keyboard_layouts[dev->layout]; + + int i; + int j; + + for (i = 0; i < CMMK_ROWS_MAX; ++i) { + for (j = 0; j < CMMK_COLS_MAX; ++j) { + int pos = 0; + + if ((pos = (*layout)[i][j]) < 0 || pos > CMMK_KEYLIST_SIZE) { + continue; + } + + linear[pos] = matrix->data[i][j]; + } + } + + return CMMK_OK; +} + +int transpose_effects_reverse(struct cmmk *dev, struct cmmk_effect_matrix const *matrix, uint8_t *linear) +{ + keyboard_layout const *layout = keyboard_layouts[dev->layout]; + + int i; + int j; + + for (i = 0; i < CMMK_ROWS_MAX; ++i) { + for (j = 0; j < CMMK_COLS_MAX; ++j) { + int pos = 0; + + if ((pos = (*layout)[i][j]) < 0 || pos > CMMK_KEYLIST_SIZE) { + continue; + } + + linear[pos] = matrix->data[i][j]; + } + } + + return CMMK_OK; +} + +#ifdef CMMK_TRACE +static void hexdump(void const *ptr, size_t buflen) +{ + unsigned char *buf = (unsigned char*)ptr; + size_t i; + size_t j; + + printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); + for (i = 0; i < buflen; i += 16) { + printf("%06lx: ", i); + + for (j = 0; j < 16; j++) { + if (i+j < buflen) { + printf("%02x ", buf[i+j]); + } else { + printf(" "); + } + } + + printf(" "); + + for (j = 0; j < 16; j++) { + if (i+j < buflen) { + printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.'); + } + } + + printf("\n"); + } +} +#endif + +static int send_command(hid_device *dev, unsigned char *data, size_t datasiz) +{ +#ifdef CMMK_TRACE + printf(">>\n"); + hexdump(data, datasiz); +#endif + + if (hid_write(dev, data, datasiz) < 0) { + return CMMK_USB_COMM; + } + + if (hid_read(dev, data, datasiz) < 0) { + return CMMK_USB_COMM; + } + +#ifdef CMMK_TRACE + printf("<<\n"); + hexdump(data, datasiz); +#endif + + return CMMK_OK; +} + +int cmmk_find_device(int *product) +{ + static int supported_devices[] = { + CMMK_USB_MASTERKEYS_PRO_L, + CMMK_USB_MASTERKEYS_PRO_S, + CMMK_USB_MASTERKEYS_MK750, + CMMK_USB_MASTERKEYS_PRO_L_WHITE, + CMMK_USB_MASTERKEYS_SK630, + CMMK_USB_MASTERKEYS_SK650, + }; + + struct hid_device_info *list = NULL; + + int res = 1; + + list = hid_enumerate(CMMK_USB_VENDOR, 0); + + for (struct hid_device_info *dev = list; dev != NULL; dev = dev->next) { + for (size_t j = 0; j < (sizeof(supported_devices) / sizeof(supported_devices[0])); ++j) { + if (dev->product_id == supported_devices[j] && dev->interface_number == CMMK_USB_INTERFACE) { + *product = dev->product_id; + + res = 0; + + break; + } + } + } + + hid_free_enumeration(list); + + return res; +} + + +static int cmmk_try_determine_layout(struct cmmk *dev, int product) +{ + char fw[16]; + + enum cmmk_layout_type general_layout = CMMK_LAYOUT_TYPE_ANSI; + enum cmmk_product_type device_model; + + if (cmmk_get_firmware_version(dev, fw, sizeof(fw)) == 0) { + if (fw[0] == '1') { + /* ANSI firmware */ + general_layout = CMMK_LAYOUT_TYPE_ANSI; + } else { + general_layout = CMMK_LAYOUT_TYPE_ISO; + } + } + + switch ((enum cmmk_product) product) { + case CMMK_USB_MASTERKEYS_PRO_L: + case CMMK_USB_MASTERKEYS_PRO_L_WHITE: device_model = CMMK_PRODUCT_MASTERKEYS_PRO_L; break; + case CMMK_USB_MASTERKEYS_PRO_S: device_model = CMMK_PRODUCT_MASTERKEYS_PRO_S; break; + case CMMK_USB_MASTERKEYS_MK750: device_model = CMMK_PRODUCT_MASTERKEYS_MK750; break; + case CMMK_USB_MASTERKEYS_SK630: device_model = CMMK_PRODUCT_MASTERKEYS_SK630; break; + case CMMK_USB_MASTERKEYS_SK650: device_model = CMMK_PRODUCT_MASTERKEYS_SK650; break; + } + + if (general_layout == CMMK_LAYOUT_TYPE_ANSI) { + switch (device_model) { + case CMMK_PRODUCT_MASTERKEYS_PRO_L: return CMMK_LAYOUT_US_L; + case CMMK_PRODUCT_MASTERKEYS_PRO_S: return CMMK_LAYOUT_US_S; + case CMMK_PRODUCT_MASTERKEYS_MK750: return CMMK_LAYOUT_US_MK750; + case CMMK_PRODUCT_MASTERKEYS_SK630: return CMMK_LAYOUT_US_SK630; + case CMMK_PRODUCT_MASTERKEYS_SK650: return CMMK_LAYOUT_US_SK630; + } + } else { + switch (device_model) { + case CMMK_PRODUCT_MASTERKEYS_PRO_L: return CMMK_LAYOUT_EU_L; + case CMMK_PRODUCT_MASTERKEYS_PRO_S: return CMMK_LAYOUT_EU_S; + case CMMK_PRODUCT_MASTERKEYS_MK750: return CMMK_LAYOUT_EU_MK750; + case CMMK_PRODUCT_MASTERKEYS_SK630: return CMMK_LAYOUT_EU_SK630; + case CMMK_PRODUCT_MASTERKEYS_SK650: return CMMK_LAYOUT_EU_SK650; + } + } + + return -1; +} + +/* + * Attach to and detach from USB device + */ +int cmmk_attach(struct cmmk *dev, int product, int layout) +{ + struct hid_device_info *list; + + list = hid_enumerate(CMMK_USB_VENDOR, product); + + dev->product = product; + + for (struct hid_device_info *dev_info = list; dev_info != NULL; dev_info = dev_info->next) { + if (dev_info->interface_number != CMMK_USB_INTERFACE) { + continue; + } + + dev->dev = hid_open_path(dev_info->path); + + if (layout < 0) { + if ((layout = cmmk_try_determine_layout(dev, product)) < 0) { + hid_free_enumeration(list); + cmmk_detach(dev); + + return CMMK_LAYOUT_DETECTION_FAILED; + } + } + + break; + } + + hid_free_enumeration(list); + + if (dev->dev != NULL) { + /* + * Generate lookup map + */ + cmmk_force_layout(dev, layout); + + dev->multilayer_mode = 0; + + return CMMK_OK; + } else { + return 1; + } +} + +int cmmk_attach_path(struct cmmk *dev, char const *path, int product, int layout) +{ + dev->dev = hid_open_path(path); + + if (dev->dev != NULL) { + if (layout < 0) { + layout = cmmk_try_determine_layout(dev, product); + } + + /* + * Generate lookup map + */ + cmmk_force_layout(dev, layout); + + dev->multilayer_mode = 0; + + return CMMK_OK; + } else { + return 1; + } +} + +int cmmk_detach(struct cmmk *dev) +{ + hid_close(dev->dev); + + return CMMK_OK; +} + +int cmmk_force_layout(struct cmmk *dev, int layout) +{ + int i; + int j; + + keyboard_layout const *keyboard_layout; + + dev->layout = layout; + + memset(dev->rowmap, -1, sizeof(dev->rowmap)); + memset(dev->colmap, -1, sizeof(dev->colmap)); + + keyboard_layout = keyboard_layouts[dev->layout]; + + for (i = 0; i < CMMK_ROWS_MAX; ++i) { + for (j = 0; j < CMMK_COLS_MAX; ++j) { + int p = (*keyboard_layout)[i][j]; + + if (p < 0) { + continue; + } + + dev->rowmap[p] = i; + dev->colmap[p] = j; + } + } + + return CMMK_OK; +} + +int cmmk_get_firmware_version(struct cmmk *dev, char *fw, size_t fwsiz) +{ + unsigned char data[65] = { 0x01, 0x02 }; + int r; + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + /* Don't want to read past the response buffer */ + if (fwsiz > 60) { + fwsiz = 60; + } + + strncpy(fw, (char *)data + 4, fwsiz); + + return CMMK_OK; +} + +enum cmmk_product_type cmmk_get_device_model(struct cmmk *dev) +{ + switch (dev->layout) { + case CMMK_LAYOUT_US_S: + case CMMK_LAYOUT_EU_S: + return CMMK_PRODUCT_MASTERKEYS_PRO_S; + + case CMMK_LAYOUT_US_L: + case CMMK_LAYOUT_EU_L: + return CMMK_PRODUCT_MASTERKEYS_PRO_L; + + case CMMK_LAYOUT_US_MK750: + case CMMK_LAYOUT_EU_MK750: + return CMMK_PRODUCT_MASTERKEYS_MK750; + } + + assert(0 && "unreachable"); +} + +enum cmmk_layout_type cmmk_get_device_layout(struct cmmk *dev) +{ + switch (dev->layout) { + case CMMK_LAYOUT_US_S: + case CMMK_LAYOUT_US_L: + case CMMK_LAYOUT_US_MK750: + return CMMK_LAYOUT_TYPE_ANSI; + + case CMMK_LAYOUT_EU_S: + case CMMK_LAYOUT_EU_L: + case CMMK_LAYOUT_EU_MK750: + return CMMK_LAYOUT_TYPE_ISO; + } + + assert(0 && "unreachable"); +} + +const char * cmmk_product_to_str(int product) +{ + switch ((enum cmmk_product) product) { + case CMMK_USB_MASTERKEYS_PRO_S: return "Cooler Master Masterkeys Pro S"; + case CMMK_USB_MASTERKEYS_PRO_L: return "Cooler Master Masterkeys Pro L"; + case CMMK_USB_MASTERKEYS_PRO_L_WHITE: return "Cooler Master Masterkeys Pro L White"; + case CMMK_USB_MASTERKEYS_MK750: return "Cooler Master Masterkeys MK750"; + case CMMK_USB_MASTERKEYS_SK630: return "Cooler Master Masterkeys SK630"; + case CMMK_USB_MASTERKEYS_SK650: return "Cooler Master Masterkeys SK650"; + } + + return "unknown"; +} + +const char * cmmk_layout_to_str(int layout) +{ + switch ((enum cmmk_layout) layout) { + case CMMK_LAYOUT_US_S: + case CMMK_LAYOUT_US_L: + case CMMK_LAYOUT_US_MK750: + case CMMK_LAYOUT_US_SK630: + case CMMK_LAYOUT_US_SK650: + return "US"; + case CMMK_LAYOUT_EU_S: + case CMMK_LAYOUT_EU_L: + case CMMK_LAYOUT_EU_MK750: + case CMMK_LAYOUT_EU_SK630: + case CMMK_LAYOUT_EU_SK650: + return "EU"; + + case CMMK_LAYOUT_INVAL: + return "invalid"; + } + + return "unknown"; +} + +/* + * Enter and leave direct control mode. Any control commands outside of control + * mode are ignored. + */ +int cmmk_set_control_mode(struct cmmk *dev, int mode) +{ + unsigned char data[64] = {0x41, mode}; + + return send_command(dev->dev, data, sizeof(data)); +} + +int cmmk_set_active_profile(struct cmmk *dev, int prof) +{ + unsigned char setprof[64] = {0x51, 0x00, 0x00, 0x00, prof}; + + return send_command(dev->dev, setprof, sizeof(setprof)); +} + +int cmmk_get_active_profile(struct cmmk *dev, int *prof) +{ + int r; + + unsigned char getprof[64] = {0x52, 0x00}; + + if ((r = send_command(dev->dev, getprof, sizeof(getprof))) != 0) + return r; + + *prof = getprof[4]; + + return CMMK_OK; +} + +int cmmk_save_active_profile(struct cmmk *dev) +{ + unsigned char saveprof[64] = {0x50, 0x55}; + + return send_command(dev->dev, saveprof, sizeof(saveprof)); +} + + +static int set_effect1(struct cmmk *dev, int eff) +{ + unsigned char data[64] = {0x51, 0x28, 0x00, 0x00, eff}; + + return send_command(dev->dev, data, sizeof(data)); +} + + +static int set_effect( + struct cmmk *dev, + int eff, + int p1, int p2, int p3, + struct rgb const *col1, + struct rgb const *col2) +{ + unsigned char data[64] = { + 0x51, 0x2c, dev->multilayer_mode, 0x00, eff, p1, p2, p3, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + if (col1 != NULL) { + data[10] = col1->R; + data[11] = col1->G; + data[12] = col1->B; + } + + if (col2 != NULL) { + data[13] = col2->R; + data[14] = col2->G; + data[15] = col2->B; + } + + memset(data + 16, 0xff, 48); + + return send_command(dev->dev, data, sizeof(data)); +} + +static int get_effect( + struct cmmk *dev, + int eff, + int *p1, int *p2, int *p3, + struct rgb *col1, + struct rgb *col2) +{ + int r; + + unsigned char data[64] = { + 0x52, 0x2c, dev->multilayer_mode, 0x00, eff + }; + + memset(data + 5, 0xff, 59); + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + if (p1) { + *p1 = data[5]; + } + + if (p2) { + *p2 = data[6]; + } + + if (p3) { + *p3 = data[7]; + } + + if (col1) { + col1->R = data[10]; + col1->G = data[11]; + col1->B = data[12]; + } + + if (col2) { + col2->R = data[13]; + col2->G = data[14]; + col2->B = data[15]; + } + + return CMMK_OK; +} + +int cmmk_set_active_effect(struct cmmk *dev, enum cmmk_effect_id eff) +{ + if (eff < 0 || (eff > CMMK_EFFECT_CUSTOMIZED + && eff != CMMK_EFFECT_OFF + && eff != CMMK_EFFECT_MULTILAYER)) { + return CMMK_INVAL; + } + + return set_effect1(dev, eff); +} + +int cmmk_get_active_effect(struct cmmk *dev, enum cmmk_effect_id *eff) +{ + unsigned char data[64] = {0x52, 0x28}; + int r; + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + *eff = data[4]; + + return CMMK_OK; +} + +int cmmk_get_effect(struct cmmk *dev, enum cmmk_effect_id id, struct cmmk_generic_effect *eff) +{ + return get_effect(dev, id, &eff->p1, &eff->p2, &eff->p3, &eff->color1, &eff->color2); +} +int cmmk_set_effect(struct cmmk *dev, enum cmmk_effect_id id, struct cmmk_generic_effect const *eff) +{ + return set_effect(dev, id, eff->p1, eff->p2, eff->p3, &eff->color1, &eff->color2); +} + + +int cmmk_get_enabled_effects( + struct cmmk *dev, + enum cmmk_effect_id *effs, + size_t siz, + size_t *n) +{ + unsigned char data[64] = {0x52, 0x29}; + + size_t i; + size_t j = 0; + + int r; + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + for (i = 4; data[i] != 0xff && j < siz; ++i) { + effs[j++] = data[i]; + } + + *n = j; + return CMMK_OK; +} + +int cmmk_set_enabled_effects( + struct cmmk *dev, + enum cmmk_effect_id const *effs, + size_t n) +{ + unsigned char data[64] = {0x51, 0x29}; + + size_t i; + + for (i = 0; i < n; ++i) { + data[4 + i] = effs[i]; + } + + while (i < 18) { + data[4 + i] = 0xff; + + ++i; + } + + return send_command(dev->dev, data, sizeof(data));; +} + +int cmmk_get_effect_fully_lit(struct cmmk *dev, struct cmmk_effect_fully_lit *eff) +{ + return get_effect(dev, CMMK_EFFECT_FULLY_LIT, NULL, NULL, NULL, &eff->color, NULL); +} + +int cmmk_set_effect_fully_lit(struct cmmk *dev, struct cmmk_effect_fully_lit const *eff) +{ + return set_effect(dev, CMMK_EFFECT_FULLY_LIT, 0x00, 0x00, 0xff, &eff->color, NULL); +} + + +int cmmk_get_effect_breathe(struct cmmk *dev, struct cmmk_effect_breathe *eff) +{ + return get_effect(dev, CMMK_EFFECT_BREATHE, &eff->speed, NULL, NULL, &eff->color, NULL); +} + +int cmmk_set_effect_breathe(struct cmmk *dev, struct cmmk_effect_breathe const *eff) +{ + return set_effect(dev, CMMK_EFFECT_BREATHE, eff->speed, 0x00, 0xff, &eff->color, NULL); +} + + +int cmmk_get_effect_cycle(struct cmmk *dev, struct cmmk_effect_cycle *eff) +{ + return get_effect(dev, CMMK_EFFECT_CYCLE, &eff->speed, NULL, NULL, NULL, NULL); +} + +int cmmk_set_effect_cycle(struct cmmk *dev, struct cmmk_effect_cycle const *eff) +{ + return set_effect(dev, CMMK_EFFECT_CYCLE, eff->speed, 0x00, 0xff, NULL, NULL); +} + + +int cmmk_get_effect_single(struct cmmk *dev, struct cmmk_effect_single *eff) +{ + return get_effect(dev, CMMK_EFFECT_SINGLE, &eff->speed, NULL, NULL, &eff->active, &eff->rest); +} + +int cmmk_set_effect_single(struct cmmk *dev, struct cmmk_effect_single const *eff) +{ + return set_effect(dev, CMMK_EFFECT_SINGLE, eff->speed, 0x00, 0xff, &eff->active, &eff->rest); +} + + +int cmmk_get_effect_wave(struct cmmk *dev, struct cmmk_effect_wave *eff) +{ + int r; + int p2; + + if ((r = get_effect(dev, CMMK_EFFECT_WAVE, &eff->speed, &p2, NULL, &eff->start, NULL)) != 0) { + return r; + } + + eff->direction = p2; + return CMMK_OK; +} + +int cmmk_set_effect_wave(struct cmmk *dev, struct cmmk_effect_wave const *eff) +{ + return set_effect(dev, CMMK_EFFECT_WAVE, eff->speed, eff->direction, 0xff, &eff->start, NULL); +} + + +int cmmk_get_effect_ripple(struct cmmk *dev, struct cmmk_effect_ripple *eff) +{ + int r; + int p2; + + if ((r = get_effect(dev, CMMK_EFFECT_RIPPLE, &eff->speed, &p2, NULL, &eff->active, &eff->rest)) != 0) { + return r; + } + + eff->ripple_type = (p2 == 0x80) ? CMMK_RIPPLE_RANDOM_COLOR : CMMK_RIPPLE_GIVEN_COLOR; + + return CMMK_OK; +} + +int cmmk_set_effect_ripple(struct cmmk *dev, struct cmmk_effect_ripple const *eff) +{ + return set_effect(dev, CMMK_EFFECT_RIPPLE, eff->speed, eff->ripple_type ? 0x80 : 0x00, 0xff, &eff->active, &eff->rest); +} + + +int cmmk_get_effect_cross(struct cmmk *dev, struct cmmk_effect_cross *eff) +{ + return get_effect(dev, CMMK_EFFECT_CROSS, &eff->speed, NULL, NULL, &eff->active, &eff->rest); +} + +int cmmk_set_effect_cross(struct cmmk *dev, struct cmmk_effect_cross const *eff) +{ + return set_effect(dev, CMMK_EFFECT_CROSS, eff->speed, 0x00, 0xff, &eff->active, &eff->rest); +} + + +int cmmk_get_effect_raindrops(struct cmmk *dev, struct cmmk_effect_raindrops *eff) +{ + return get_effect(dev, CMMK_EFFECT_RAINDROPS, &eff->speed, NULL, &eff->interval, &eff->active, &eff->rest); +} + +int cmmk_set_effect_raindrops(struct cmmk *dev, struct cmmk_effect_raindrops const *eff) +{ + return set_effect(dev, CMMK_EFFECT_RAINDROPS, eff->speed, 0x00, eff->interval, &eff->active, &eff->rest); +} + + +int cmmk_get_effect_stars(struct cmmk *dev, struct cmmk_effect_stars *eff) +{ + return get_effect(dev, CMMK_EFFECT_STARS, &eff->speed, NULL, &eff->interval, &eff->active, &eff->rest); +} + +int cmmk_set_effect_stars(struct cmmk *dev, struct cmmk_effect_stars const *eff) +{ + return set_effect(dev, CMMK_EFFECT_STARS, eff->speed, 0x00, eff->interval, &eff->active, &eff->rest); +} + +int cmmk_get_effect_snake(struct cmmk *dev, struct cmmk_effect_snake *eff) +{ + return get_effect(dev, CMMK_EFFECT_SNAKE, &eff->speed, NULL, NULL, NULL, NULL); +} + +int cmmk_set_effect_snake(struct cmmk *dev, struct cmmk_effect_snake const *eff) +{ + return set_effect(dev, CMMK_EFFECT_SNAKE, eff->speed, 0x00, 0xff, NULL, NULL); +} + +int cmmk_set_customized_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap) +{ + unsigned char data[64] = {0x51, 0xa8}; + + int i; + int j; + +#ifdef _MSC_VER + struct rgb linear[CMMK_KEYLIST_SIZE] = { 0 }; +#else + struct rgb linear[CMMK_KEYLIST_SIZE] = {}; +#endif + struct rgb *nextcol = linear; + + transpose_reverse(dev, colmap, linear); + + for (i = 0; i < 8; ++i) { + data[2] = i*2; + + for (j = 0; j < 16; ++j) { + int const offset = 4 + (j * 3); + + data[offset] = nextcol->R; + data[offset + 1] = nextcol->G; + data[offset + 2] = nextcol->B; + + ++nextcol; + } + + send_command(dev->dev, data, sizeof(data)); + } + + return CMMK_OK; +} + +int cmmk_get_customized_leds(struct cmmk *dev, struct cmmk_color_matrix *colmap) +{ +#ifdef _MSC_VER + struct rgb linear[CMMK_KEYLIST_SIZE] = { 0 }; +#else + struct rgb linear[CMMK_KEYLIST_SIZE] = {}; +#endif + + unsigned char data[64] = {0x52, 0xa8}; + + int i; + int j; + + struct rgb *ptr = linear; + + for (i = 0; i < 8; ++i) { + data[2] = i * 2; + + send_command(dev->dev, data, sizeof(data)); + + for (j = 0; j < 16; ++j) { + int const offset = 4 + (j * 3); + + ptr->R = data[offset]; + ptr->G = data[offset + 1]; + ptr->B = data[offset + 2]; + + ++ptr; + } + } + + transpose(dev, linear, colmap); + + return CMMK_OK; +} + +int cmmk_switch_multilayer(struct cmmk *dev, int active) +{ + dev->multilayer_mode = active > 0; + + return CMMK_OK; +} + +int cmmk_get_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix *effmap) +{ + int r; + + unsigned char data[64] = {0x52, 0xa0, 0x01, 0x00}; + uint8_t linear[CMMK_KEYLIST_SIZE]; + + /* Call 1 */ + data[4] = 0x00; + data[5] = 0x07; + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + memcpy(linear, data + 8, 56); + + /* Call 2 */ + data[4] = 0x07; + data[5] = 0x07; + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + memcpy(linear + 56, data + 8, 56); + + /* Call 3 */ + data[4] = 0x0e; + data[5] = 0x01; + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + memcpy(linear + 112, data + 8, 8); + + transpose_effects(dev, linear, effmap); + + return CMMK_OK; +} + +int cmmk_set_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix const *effmap) +{ + int r; + + unsigned char data[64] = {0x51, 0xa0, 0x01, 0x00}; + uint8_t linear[CMMK_KEYLIST_SIZE] = {0}; + + transpose_effects_reverse(dev, effmap, linear); + + /* Call 1 */ + data[4] = 0x00; + data[5] = 0x07; + + memcpy(data + 8, linear, 56); + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + /* Call 2 */ + data[4] = 0x07; + data[5] = 0x07; + + memcpy(data + 8, linear + 56, 56); + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + /* Call 3 */ + data[4] = 0x0e; + data[5] = 0x01; + + memcpy(data + 8, linear + 112, 8); + + if ((r = send_command(dev->dev, data, sizeof(data))) != 0) { + return r; + } + + return CMMK_OK; +} + +int cmmk_lookup_key_id(struct cmmk *dev, int row, int col) +{ + keyboard_layout const *layout = keyboard_layouts[dev->layout]; + + return (*layout)[row][col]; +} + +/* + * Set the single key `key' to the given color. + */ +int cmmk_set_single_key_by_id(struct cmmk *dev, int key, struct rgb const *color) +{ + unsigned char data[64] = {0xc0, 0x01, 0x01, 0x00, key, color->R, color->G, color->B}; + + return send_command(dev->dev, data, sizeof(data)); +} + +/* + * Set the single key in row `row` and column `col` to the given color. + */ +int cmmk_set_single_key(struct cmmk *dev, int row, int col, struct rgb const *color) +{ + int key = cmmk_lookup_key_id(dev, row, col); + + return cmmk_set_single_key_by_id(dev, key, color); +} + + +/* + * Set the entire keyboard to the given color. + */ +int cmmk_set_all_single(struct cmmk *dev, struct rgb const *col) +{ + unsigned char data[64] = {0xc0, 0x00, 0x00, 0x00, col->R, col->G, col->B}; + + return send_command(dev->dev, data, sizeof(data)); +} + + +/* + * Set the entire keyboard in one step from the given map. + * + * colmap *must* be at least CMMK_KEYLIST_SIZE entries long. + * Otherwise, segmentation faults ensue. + * + * Keys in the map are indized by their individual mappings, so + * colmap[K_ESC] will address the ESC key, much like + * set_single_key(..., K_ESC, ...) will. + */ +int cmmk_set_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap) +{ + unsigned char data[64]; + + int i; + int j; + +#ifdef _MSC_VER + struct rgb linear[CMMK_KEYLIST_SIZE] = { 0 }; +#else + struct rgb linear[CMMK_KEYLIST_SIZE] = {}; +#endif + struct rgb *nextcol = linear; + + transpose_reverse(dev, colmap, linear); + + for (i = 0; i < 8; ++i) { + data[0] = 0xc0; + data[1] = 0x02; + data[2] = i*2; + data[3] = 0x00; + + for (j = 0; j < 16; ++j) { + int const offset = 4 + (j * 3); + + data[offset] = nextcol->R; + data[offset + 1] = nextcol->G; + data[offset + 2] = nextcol->B; + + ++nextcol; + } + + send_command(dev->dev, data, sizeof(data)); + } + + return CMMK_OK; +} + + +/* + * Unpublished functions (debug, survey, ...) + */ +int cmmk_send_anything(struct cmmk *dev, unsigned char *data, size_t data_siz) +{ + return send_command(dev->dev, data, data_siz); +} diff --git a/dependencies/libcmmk/src/mappings/ansi/mk750.h b/dependencies/libcmmk/src/mappings/ansi/mk750.h new file mode 100644 index 00000000..2809393d --- /dev/null +++ b/dependencies/libcmmk/src/mappings/ansi/mk750.h @@ -0,0 +1,25 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_ansi_mk750 = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; \ No newline at end of file diff --git a/dependencies/libcmmk/src/mappings/ansi/pro_l.h b/dependencies/libcmmk/src/mappings/ansi/pro_l.h new file mode 100644 index 00000000..ca35349a --- /dev/null +++ b/dependencies/libcmmk/src/mappings/ansi/pro_l.h @@ -0,0 +1,44 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_ansi_pro_l = { + /* + ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRN SCL PAU P1 P2 P3 P4 */ + {11, 22, 30, 25, 27, -1, 7, 51, 57, 62, -1, 86, 87, 83, 85, 79, 72, 0, 101, 109, 117, 119}, + + /* + ` 1 2 3 4 5 6 7 8 9 0 - = XXX BCK INS HOM PUP #LCK #/ #* #- */ + {14, 15, 23, 31, 39, 38, 46, 47, 55, 63, 71, 70, 54, -1, 81, 3, 1, 2, 100, 108, 116, 118}, + + /* + TAB Q W E R T Y U I O P [ ] XXX \ DEL END PDN #7 #8 #9 #+ */ + {9, 8, 16, 24, 32, 33, 41, 40, 48, 56, 64, 65, 49, -1, 82, 94, 92, 88, 96, 104, 112, 110}, + + /* + CAP A S D F G H J K L ; ' XXX XXX ENT XXX XXX XXX #4 #5 #6 XXX */ + {17, 10, 18, 26, 34, 35, 43, 42, 50, 58, 66, 67, -1, -1, 84, -1, -1, -1, 97, 105, 113, -1}, + + /* + LSHFT XXX Z X C V B N M , . / XXX XXX RSHFT XXX UP XXX #1 #2 #3 #ENTER */ + {73, -1, 12, 20, 28, 36, 37, 45, 44, 52, 60, 69, -1, -1, 74, -1, 80, -1, 98, 106, 114, 111}, + + /* + LCTRL LWIN LALT XXX XXX XXX SPACE XXX XXX XXX RALT RWIN FN XXX RCTRL LEFT DOWN RIGHT #0 XXX #. XXX */ + {6, 90, 75, -1, -1, -1, 91, -1, -1, -1, 77, 78, 61, -1, 4, 95, 93, 5, 107, -1, 115, -1}, + + /* Bottom row does not exist */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; \ No newline at end of file diff --git a/dependencies/libcmmk/src/mappings/ansi/pro_s.h b/dependencies/libcmmk/src/mappings/ansi/pro_s.h new file mode 100644 index 00000000..b0bba177 --- /dev/null +++ b/dependencies/libcmmk/src/mappings/ansi/pro_s.h @@ -0,0 +1,43 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_ansi_pro_s = { + /* + ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRN SCL PAU XXX XXX XXX XXX */ + {96, 97, 98, 99, 104, -1, 105, 106, 112, 113, -1, 114, 67, 68, 69, 102, 103, 107, -1, -1, -1, -1}, + + /* + ` 1 2 3 4 5 6 7 8 9 0 - = XXX BCK INS HOM PUP XXX XXX XXX XXX */ + {0, 1, 8, 9, 16, 17, 24, 25, 32, 33, 40, 41, 48, -1, 49, 56, 57, 64, -1, -1, -1, -1}, + + /* + TAB Q W E R T Y U I O P [ ] XXX \ DEL END PDN XXX XXX XXX XXX */ + {2, 3, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 50, -1, 51, 58, 59, 66, -1, -1, -1, -1}, + + /* + CAP A S D F G H J K L ; ' XXX XXX ENT XXX XXX XXX XXX XXX XXX XXX */ + {4, 5, 12, 13, 20, 21, 28, 29, 36, 37, 44, 45, -1, -1, 52, -1, -1, -1, -1, -1, -1, -1}, + + /* + LSHFT XXX Z X C V B N M , . / XXX XXX RSHFT XXX UP XXX XXX XXX XXX XXX */ + {6, -1, 7, 14, 15, 22, 23, 30, 31, 38, 39, 46, -1, -1, 47, -1, 61, -1, -1, -1, -1, -1}, // after / was 1 BAD + + /* + LCTRL LWIN LALT XXX XXX XXX SPACE XXX XXX XXX RALT RWIN FN XXX RCTRL LEFT DOWN RIGHT XXX XXX XXX XXX */ + {91, 90, 92, -1, -1, -1, 93, -1, -1, -1, 94, 60, 95, -1, 54, 63, 62, 70, -1, -1, -1, -1}, + + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; \ No newline at end of file diff --git a/dependencies/libcmmk/src/mappings/ansi/sk630.h b/dependencies/libcmmk/src/mappings/ansi/sk630.h new file mode 100644 index 00000000..02454df0 --- /dev/null +++ b/dependencies/libcmmk/src/mappings/ansi/sk630.h @@ -0,0 +1,25 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_ansi_sk630 = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; \ No newline at end of file diff --git a/dependencies/libcmmk/src/mappings/ansi/sk650.h b/dependencies/libcmmk/src/mappings/ansi/sk650.h new file mode 100644 index 00000000..913c0b9c --- /dev/null +++ b/dependencies/libcmmk/src/mappings/ansi/sk650.h @@ -0,0 +1,25 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_ansi_sk650 = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; \ No newline at end of file diff --git a/dependencies/libcmmk/src/mappings/iso/mk750.h b/dependencies/libcmmk/src/mappings/iso/mk750.h new file mode 100644 index 00000000..5cc2ec13 --- /dev/null +++ b/dependencies/libcmmk/src/mappings/iso/mk750.h @@ -0,0 +1,45 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_iso_mk750 = { + /* + ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRN SCL PAU MUT PLA REW FWD */ + {96, 97, 98, 99, 104, -1, 105, 106, 112, 113, -1, 114, 67, 68, 69, 102, 103, 107, 111, 110, 108, 109}, + + /* + ^ 1 2 3 4 5 6 7 8 9 0 ß ´ XXX BCK INS HOM PUP #LCK #/ #* #- */ + {0, 1, 8, 9, 16, 17, 24, 25, 32, 33, 40, 41, 48, -1, 49, 56, 57, 64, 72, 73, 80, 81}, + + /* + TAB Q W E R T Z/Y U I O P Ü/[ +/] XXX ENT DEL END PDN #7 #8 #9 #+ */ + {2, 3, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 50, -1, 52, 58, 59, 66, 74, 75, 82, 83}, + + /* + CAP A S D F G H J K L Ö/; Ä/' #/C42 XXX XXX XXX XXX XXX #4 #5 #6 XXX */ + {4, 5, 12, 13, 20, 21, 28, 29, 36, 37, 44, 45, 119, -1, -1, -1, -1, -1, 76, 77, 84, -1}, + + /* + LSHFT . + */ +static keyboard_layout layout_iso_pro_l = { + /* + ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRN SCL PAU P1 P2 P3 P4 */ + {11, 22, 30, 25, 27, -1, 7, 51, 57, 62, -1, 86, 87, 83, 85, 79, 72, 0, 101, 109, 117, 119}, + + /* + ^ 1 2 3 4 5 6 7 8 9 0 ß ´ XXX BCK INS HOM PUP #LCK #/ #* #- */ + {14, 15, 23, 31, 39, 38, 46, 47, 55, 63, 71, 70, 54, -1, 81, 3, 1, 2, 100, 108, 116, 118}, + + /* + TAB Q W E R T Z/Y U I O P Ü/[ +/] XXX ENT DEL END PDN #7 #8 #9 #+ */ + {9, 8, 16, 24, 32, 33, 41, 40, 48, 56, 64, 65, 49, -1, 84, 94, 92, 88, 96, 104, 112, 110}, + + /* + CAP A S D F G H J K L Ö/; Ä/' #/C42 XXX XXX XXX XXX XXX #4 #5 #6 XXX */ + {17, 10, 18, 26, 34, 35, 43, 42, 50, 58, 66, 67, 68, -1, -1, -1, -1, -1, 97, 105, 113, -1}, + + /* + LSHFT . + */ +static keyboard_layout layout_iso_pro_s = { + /* TODO! */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; \ No newline at end of file diff --git a/dependencies/libcmmk/src/mappings/iso/sk630.h b/dependencies/libcmmk/src/mappings/iso/sk630.h new file mode 100644 index 00000000..972c243d --- /dev/null +++ b/dependencies/libcmmk/src/mappings/iso/sk630.h @@ -0,0 +1,44 @@ +/* + * This file is part of libcmmk. + * + * libcmmk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libcmmk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libcmmk. If not, see . + */ +static keyboard_layout layout_iso_sk630 = { + /* + ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRN SCL PAU MUT PLA REW FWD */ + { 9, 33, 41, 49, 57, -1, 73, 81, 89, 97, -1, 105, 113, 121, 129, 137, 145, 153, -1, -1, -1, -1}, + + /* + ^ 1 2 3 4 5 6 7 8 9 0 ß ´ XXX BCK INS HOM PUP #LCK #/ #* #- */ + {10, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, -1, 130, 138, 146, 154, -1, -1, -1, -1}, + + /* + TAB Q W E R T Z/Y U I O P Ü/[ +/] XXX ENT DEL END PDN #7 #8 #9 #+ */ + {11, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, -1, 132, 139, 147, 155, -1, -1, -1, -1}, + + /* + CAP A S D F G H J K L Ö/; Ä/' #/C42 XXX XXX XXX XXX XXX #4 #5 #6 XXX */ + {12, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + + /* + LSHFT . + */ +static keyboard_layout layout_iso_sk650 = { + /* + ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRN SCL PAU MUT PLA REW FWD */ + { 9, 33, 41, 49, 57, -1, 73, 81, 89, 97, -1, 105, 113, 121, 129, 137, 145, 153, -1, -1, -1, -1}, + + /* + ^ 1 2 3 4 5 6 7 8 9 0 ß ´ XXX BCK INS HOM PUP #LCK #/ #* #- */ + {10, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, -1, 130, 138, 146, 154, 162, 170, 178, 186}, + + /* + TAB Q W E R T Z/Y U I O P Ü/[ +/] XXX ENT DEL END PDN #7 #8 #9 #+ */ + {11, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, -1, 132, 139, 147, 155, 163, 171, 179, 187}, + + /* + CAP A S D F G H J K L Ö/; Ä/' #/C42 XXX XXX XXX XXX XXX #4 #5 #6 XXX */ + {12, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 124, -1, -1, -1, -1, -1, 164, 172, 180, -1}, + + /* + LSHFT