diff --git a/changelog.rtf b/changelog.rtf index 0e43d5b..c2b3a77 100644 --- a/changelog.rtf +++ b/changelog.rtf @@ -1,9 +1,11 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200 +{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf400 {\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} -{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid1\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid2\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li1440\lin1440 }{\listname ;}\listid1}} -{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} +{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid1\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} +{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid101\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2} +{\list\listtemplateid3\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid201\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid202\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li1440\lin1440 }{\listname ;}\listid3}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}} \paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc\partightenfactor0 @@ -11,13 +13,27 @@ \fs24 \ul \ulc0 \ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\fs20 \cf0 \ulnone Version 2019.05.08\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls1\ilvl0 +\f1\b0 \cf0 {\listtext \uc0\u8259 }CK530 model was reported (by @cscheib) to be compatible with this SW, so it was enabled in this release.\ +{\listtext \uc0\u8259 }Tested with a CK550 keyboard FW 1.06.03. +\f0\b\fs24 \ul \ulc0 \ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls2\ilvl0 +\f1\b0\fs20 \cf0 \ulnone {\listtext \uc0\u8259 }Internal components were updated. +\f0\b\fs24 \ul \ulc0 \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ \fs20 \ulnone Version 2019.01.27\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \f1\b0 \cf0 \ \pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 -\ls1\ilvl0\cf0 {\listtext \uc0\u8259 }Detected keyboard and its FW version is shown in a status bar menu.\ +\ls3\ilvl0\cf0 {\listtext \uc0\u8259 }Detected keyboard and its FW version is shown in a status bar menu.\ {\listtext \uc0\u8259 }Original keyboard settings are restored once the application is to be terminated or by selecting any keyboard profile.\ {\listtext \uc0\u8259 }LEDs are turned off when computer goes to sleep by default.\ {\listtext \uc0\u8259 }LEDs are turned on and the last selected effect applied when computer goes to wake up by default.\ @@ -25,7 +41,7 @@ {\listtext \uc0\u8259 }All effects are configurable and their settings are auto-preserved.\ {\listtext \uc0\u8259 }Following effects are supported:\ \pard\tx940\tx1440\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li1440\fi-1440\pardirnatural\partightenfactor0 -\ls1\ilvl1\cf0 {\listtext \uc0\u8259 }Static,\ +\ls3\ilvl1\cf0 {\listtext \uc0\u8259 }Static,\ {\listtext \uc0\u8259 }Wave,\ {\listtext \uc0\u8259 }Cross Mode,\ {\listtext \uc0\u8259 }Single Key,\ @@ -43,7 +59,7 @@ {\listtext \uc0\u8259 }Water Ripple,\ {\listtext \uc0\u8259 }Off.\ \pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 -\ls1\ilvl0\cf0 {\listtext \uc0\u8259 }Selected effect is not stored permanently in a keyboard, therefore the internal keyboard flash is not worn out in time anyhow.\ +\ls3\ilvl0\cf0 {\listtext \uc0\u8259 }Selected effect is not stored permanently in a keyboard, therefore the internal keyboard flash is not worn out in time anyhow.\ {\listtext \uc0\u8259 }Tested with a keyboard FW 1.06.02.\ {\listtext \uc0\u8259 }CoolerMaster CK550 \f0\b US Layout only diff --git a/src/Constants.swift b/src/Constants.swift new file mode 100644 index 0000000..943cf5d --- /dev/null +++ b/src/Constants.swift @@ -0,0 +1,34 @@ +/* + + Licensed under the MIT license: + + Copyright (c) 2019 Michal Duda + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +import Foundation + +let keyboardVID: Int = 0x2516 + +enum KeyboardPIDs: Int, CaseIterable { + case CK550 = 0x007f; // Works - @vookimedlo - this is the only keyboard I have, any contribution for other models is welcome!!! + case CK530 = 0x009f; // Works - @cscheib - suggested & reported - Thanks!!! +} diff --git a/src/HIDEnumerator.swift b/src/HIDEnumerator.swift index 0689cd8..34f54ed 100644 --- a/src/HIDEnumerator.swift +++ b/src/HIDEnumerator.swift @@ -95,11 +95,21 @@ class HIDEnumerator { /// - Parameters: /// - vid: The USB Vendor ID. /// - pid: The USB Product ID. - /// - Returns: True when monitring has started. False otherwise. + /// - Returns: True when monitoring has started. False otherwise. func monitorEnumeration(vid: Int, pid: Int) -> Bool { return monitorEnumeration(vid: vid, pid: pid, usagePage: 0, usage: 0) } + /// Starts a HID enumeration monitoring and filters enumerated results by provided USB IDs. + /// + /// - Parameters: + /// - vid: The USB Vendor ID. + /// - pids: The USB Product IDs. + /// - Returns: True when monitoring has started. False otherwise. + func monitorEnumeration(vid: Int, pids: [Int]) -> Bool { + return monitorEnumeration(vid: vid, pids: pids, usagePage: 0, usage: 0) + } + /// Starts a HID enumeration monitoring and filters enumerated results by provided USB IDs. /// /// - Parameters: @@ -107,9 +117,28 @@ class HIDEnumerator { /// - pid: The USB Product ID. /// - usagePage: The USB HID Usage Page ID. /// - usage: The USB HID Usage ID. - /// - Returns: True when monitring has started. False otherwise. + /// - Returns: True when monitoring has started. False otherwise. func monitorEnumeration(vid: Int, pid: Int, usagePage: UInt32, usage: UInt32) -> Bool { - let deviceMatch = [kIOHIDProductIDKey: pid, kIOHIDVendorIDKey: vid] + return monitorEnumeration(vid: vid, pids: [pid], usagePage: 0, usage: 0) + } + + /// Starts a HID enumeration monitoring and filters enumerated results by provided USB IDs. + /// + /// - Parameters: + /// - vid: The USB Vendor ID. + /// - pids: The USB Product IDs. + /// - usagePage: The USB HID Usage Page ID. + /// - usage: The USB HID Usage ID. + /// - Returns: True when monitoring has started. False otherwise. + func monitorEnumeration(vid: Int, pids: [Int], usagePage: UInt32, usage: UInt32) -> Bool { + guard !pids.isEmpty else { + return false + } + + var deviceMatchMultiple: [[String: Int]] = [] + for pid in pids { + deviceMatchMultiple.append([kIOHIDProductIDKey: pid, kIOHIDVendorIDKey: vid]) + } self.usagePage = usagePage self.usage = usage @@ -127,7 +156,7 @@ class HIDEnumerator { IOHIDManagerRegisterDeviceMatchingCallback(manager, matchingCallback, this) IOHIDManagerRegisterDeviceRemovalCallback(manager, removalCallback, this) - IOHIDManagerSetDeviceMatching(manager, deviceMatch as CFDictionary?) + IOHIDManagerSetDeviceMatchingMultiple(manager, deviceMatchMultiple as CFArray?) IOHIDManagerScheduleWithRunLoop(manager, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode.rawValue) return kIOReturnSuccess == IOHIDManagerOpen(manager, 0) diff --git a/src/ck550.xcodeproj/project.pbxproj b/src/ck550.xcodeproj/project.pbxproj index 878e50d..4cd8f88 100644 --- a/src/ck550.xcodeproj/project.pbxproj +++ b/src/ck550.xcodeproj/project.pbxproj @@ -12,6 +12,8 @@ 8D04E32A21DBFC5B00707E63 /* EffectCustomizationPreferenceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D04E32921DBFC5B00707E63 /* EffectCustomizationPreferenceViewController.swift */; }; 8D04E32C21DD5C1D00707E63 /* FileLoadNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D04E32B21DD5C1D00707E63 /* FileLoadNotification.swift */; }; 8D04E32E21DEA58C00707E63 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D04E32D21DEA58C00707E63 /* Utils.swift */; }; + 8D06A13F228341A30042E928 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D06A13E228341A30042E928 /* Constants.swift */; }; + 8D06A140228341A30042E928 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D06A13E228341A30042E928 /* Constants.swift */; }; 8D109A3821BC80D9007F2C30 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D109A2821BC7794007F2C30 /* SwiftyJSON.framework */; }; 8D109A3921BC80D9007F2C30 /* SwiftyJSON.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8D109A2821BC7794007F2C30 /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8D20654A21BC7394000FF8E4 /* CK550CommandBreathing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D49DCA521B5BD1500BAC6F8 /* CK550CommandBreathing.swift */; }; @@ -323,6 +325,7 @@ 8D04E32921DBFC5B00707E63 /* EffectCustomizationPreferenceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectCustomizationPreferenceViewController.swift; sourceTree = ""; }; 8D04E32B21DD5C1D00707E63 /* FileLoadNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileLoadNotification.swift; sourceTree = ""; }; 8D04E32D21DEA58C00707E63 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; + 8D06A13E228341A30042E928 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 8D109A2821BC7794007F2C30 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = ../Carthage/Build/Mac/SwiftyJSON.framework; sourceTree = ""; }; 8D20653321BC72CF000FF8E4 /* ck550-cli.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ck550-cli.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 8D20654221BC7359000FF8E4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = cli/Info.plist; sourceTree = ""; }; @@ -452,7 +455,6 @@ 8D966E4721C035C8009AF6E6 /* PrettyColors.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PrettyColors.framework; path = ../Carthage/Build/Mac/PrettyColors.framework; sourceTree = ""; }; 8D966E4921C0375F009AF6E6 /* Terminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Terminal.swift; path = cli/Terminal.swift; sourceTree = ""; }; 8D966E4B21C18425009AF6E6 /* Commandant.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Commandant.framework; path = ../Carthage/Build/Mac/Commandant.framework; sourceTree = ""; }; - 8D966E4F21C1859C009AF6E6 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Result.framework; path = ../Carthage/Build/Mac/Result.framework; sourceTree = ""; }; 8D966E5321C186A3009AF6E6 /* VersionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VersionCommand.swift; path = cli/VersionCommand.swift; sourceTree = ""; }; 8D966E5521C18B79009AF6E6 /* MonitorCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MonitorCommand.swift; path = cli/MonitorCommand.swift; sourceTree = ""; }; 8D966E5721C19993009AF6E6 /* Curry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Curry.framework; path = ../Carthage/Build/Mac/Curry.framework; sourceTree = ""; }; @@ -571,7 +573,6 @@ 8D966E4B21C18425009AF6E6 /* Commandant.framework */, 8D966E5721C19993009AF6E6 /* Curry.framework */, 8D966E4721C035C8009AF6E6 /* PrettyColors.framework */, - 8D966E4F21C1859C009AF6E6 /* Result.framework */, 8D82DDC121F792DF0043F516 /* Sparkle.framework */, 8D109A2821BC7794007F2C30 /* SwiftyJSON.framework */, ); @@ -909,6 +910,7 @@ 8D966E3F21BF0B8A009AF6E6 /* AssembleCommandStatic.swift */, 8D75FACF21C598C300574CF1 /* AssembleCommandWaterRipple.swift */, 8D966E3721BF0667009AF6E6 /* AssembleCommandWave.swift */, + 8D06A13E228341A30042E928 /* Constants.swift */, ); name = shared; sourceTree = ""; @@ -1157,6 +1159,7 @@ 8D75FACA21C597DA00574CF1 /* AssembleCommandFireball.swift in Sources */, 8DFD0D0621BDB105009905CD /* AssembleCommandCustomization.swift in Sources */, 8D7281A821C4269000963B1D /* AssembleCommandReactiveTornado.swift in Sources */, + 8D06A13F228341A30042E928 /* Constants.swift in Sources */, 8D75FAD021C598C300574CF1 /* AssembleCommandWaterRipple.swift in Sources */, 8D20654A21BC7394000FF8E4 /* CK550CommandBreathing.swift in Sources */, 8D20654B21BC7394000FF8E4 /* CK550CommandCircleSpectrum.swift in Sources */, @@ -1307,6 +1310,7 @@ 8D73C65A21D2C45D0021FA4B /* RGBColorExtension.swift in Sources */, 8D73C64D21CFED820021FA4B /* EffectPreferenceViewController.swift in Sources */, 8D84AAE021C994FE00087947 /* Logging.swift in Sources */, + 8D06A140228341A30042E928 /* Constants.swift in Sources */, 8D73C66821D6BBDB0021FA4B /* AppPreferences.swift in Sources */, 8D6FB4DC21CBD79C00C25DA6 /* NSViewExtension.swift in Sources */, 8D6FB4DE21CC142D00C25DA6 /* EffectToggledNotification.swift in Sources */, diff --git a/src/cli/CLI.swift b/src/cli/CLI.swift index fe54033..b47354c 100644 --- a/src/cli/CLI.swift +++ b/src/cli/CLI.swift @@ -42,7 +42,10 @@ class CLI: NSObject, HIDDeviceEnumeratedHandler { } func startHIDMonitoring() -> Bool { - return hid.monitorEnumeration(vid: 0x2516, pid: 0x007f, usagePage: 0xFF00, usage: 0x00) + return hid.monitorEnumeration(vid: keyboardVID, + pids: KeyboardPIDs.allCases.map { $0.rawValue }, + usagePage: 0xFF00, + usage: 0x00) } func deviceEnumerated(notification: Notification) { diff --git a/src/cli/Info.plist b/src/cli/Info.plist index 43dadf6..db8fbd6 100644 --- a/src/cli/Info.plist +++ b/src/cli/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2019.05.07-dev + 2019.05.08-dev CFBundleVersion - 20190507 + 20190508 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright diff --git a/src/gui/Info.plist b/src/gui/Info.plist index 59503c0..7a24869 100644 --- a/src/gui/Info.plist +++ b/src/gui/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2019.05.07-dev + 2019.05.08-dev CFBundleVersion - 20190507 + 20190508 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/src/gui/KeyboardGUIHandler.swift b/src/gui/KeyboardGUIHandler.swift index 45cd17a..d03d612 100644 --- a/src/gui/KeyboardGUIHandler.swift +++ b/src/gui/KeyboardGUIHandler.swift @@ -296,7 +296,10 @@ class KeyboardGUIHandler: NSObject, HIDDeviceEnumeratedHandler, MenuToggledHandl } func startHIDMonitoring() -> Bool { - return hid.monitorEnumeration(vid: 0x2516, pid: 0x007f, usagePage: 0xFF00, usage: 0x00) + return hid.monitorEnumeration(vid: keyboardVID, + pids: KeyboardPIDs.allCases.map { $0.rawValue }, + usagePage: 0xFF00, + usage: 0x00) } func deviceEnumerated(notification: Notification) {