Media keys working again
This commit is contained in:
@@ -14,6 +14,14 @@ namespace gkeymapper::daemon {
|
||||
// A raw HID report from the vendor interface.
|
||||
using Report = std::vector<uint8_t>;
|
||||
|
||||
// One media key: the bit it has in the media report and the Linux input code it
|
||||
// is replayed as.
|
||||
struct MediaKey {
|
||||
uint8_t bit = 0;
|
||||
uint16_t key = 0; // Linux KEY_* code
|
||||
const char* name = ""; // for the log line
|
||||
};
|
||||
|
||||
struct DeviceProfile {
|
||||
const char* name = "";
|
||||
uint16_t vendor = 0;
|
||||
@@ -22,9 +30,18 @@ struct DeviceProfile {
|
||||
int interfaceNumber = 1;
|
||||
int altSetting = 0;
|
||||
|
||||
// gKeyReports[i] is the press report for G(i+1).
|
||||
// Media keys (mute / volume / play) arrive as a short report: this prefix
|
||||
// byte followed by one bit per key, 0 when they are all released. 0 means
|
||||
// the model reports none. This is the only path the keyboard offers for
|
||||
// those keys, so while the daemon holds the interface the kernel does not see
|
||||
// them at all — the daemon replays them through its virtual keyboard.
|
||||
uint8_t mediaPrefix = 0;
|
||||
std::vector<MediaKey> mediaKeys;
|
||||
|
||||
// gKeyReports[i] is the report that has the bit of G(i+1) set. Both the
|
||||
// shared header bytes and the bit of each key are derived from these, so a
|
||||
// new model only needs its table (see decode_gkey_state).
|
||||
std::vector<Report> gKeyReports;
|
||||
Report releaseReport;
|
||||
|
||||
// Some models must be told to stop mapping G-keys to F-keys first.
|
||||
bool disableBinding = false;
|
||||
@@ -36,11 +53,24 @@ const std::vector<DeviceProfile>& profiles();
|
||||
// Matching profile for vendor/product, or nullptr.
|
||||
const DeviceProfile* find_profile(uint16_t vendor, uint16_t product);
|
||||
|
||||
// Index of the G key (0..N-1) for a report, or -1 if it is not a known press.
|
||||
int match_gkey(const DeviceProfile& profile, const uint8_t* data, int length);
|
||||
// Decodes a macro-key report into the keys it reports as pressed: bit 0 = G1 ..
|
||||
// bit 8 = G9. Returns false for every other report — the media keys have their
|
||||
// own decoder below, and memory keys, LED and command acknowledgements are
|
||||
// ignored on purpose.
|
||||
//
|
||||
// The report carries the state of all G keys, not a single key: one report with
|
||||
// several bits set means a chord, and "no bit set" is the release. The caller
|
||||
// compares consecutive states, which makes a held key (repeating report) fire
|
||||
// once and a chord fire every key it contains.
|
||||
bool decode_gkey_state(const DeviceProfile& profile, const uint8_t* data, int length,
|
||||
uint32_t& pressed);
|
||||
|
||||
// True if the report is the "all macro keys released" report.
|
||||
bool is_release_report(const DeviceProfile& profile, const uint8_t* data, int length);
|
||||
// Decodes a media-key report into its bits (bit set = key held), using the bit
|
||||
// table of the profile. `bits` is 0 for the release report, which is a valid
|
||||
// media report. Returns false for every other report, in particular for the
|
||||
// macro-key reports.
|
||||
bool decode_media_key(const DeviceProfile& profile, const uint8_t* data, int length,
|
||||
uint32_t& bits);
|
||||
|
||||
} // namespace gkeymapper::daemon
|
||||
|
||||
|
||||
Reference in New Issue
Block a user