| |
| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/ui/lib/input_reader/keyboard.h" |
| |
| #include <stdint.h> |
| #include <stdio.h> |
| |
| #include <set> |
| #include <vector> |
| |
| #include <hid-parser/parser.h> |
| #include <hid-parser/report.h> |
| #include <hid-parser/units.h> |
| #include <hid-parser/usages.h> |
| #include <hid/usages.h> |
| |
| #include "src/lib/fxl/logging.h" |
| #include "src/ui/lib/input_reader/device.h" |
| |
| namespace ui_input { |
| |
| bool Keyboard::ParseReportDescriptor(const hid::ReportDescriptor& report_descriptor, |
| Descriptor* device_descriptor) { |
| std::set<uint32_t> key_values; |
| |
| auto keyboard = fuchsia::ui::input::KeyboardDescriptor::New(); |
| for (size_t i = 0; i < report_descriptor.input_count; i++) { |
| const hid::ReportField& field = report_descriptor.input_fields[i]; |
| |
| if (field.attr.usage.page == hid::usage::Page::kKeyboardKeypad) { |
| if (field.flags & hid::FieldTypeFlags::kArray) { |
| for (uint8_t key = static_cast<uint8_t>(field.attr.logc_mm.min); |
| key < static_cast<uint8_t>(field.attr.logc_mm.max); key++) { |
| key_values.insert(key); |
| } |
| } else { |
| key_values.insert(field.attr.usage.usage); |
| } |
| key_fields_.push_back(field); |
| } |
| } |
| |
| keyboard->keys = std::vector<uint32_t>(key_values.begin(), key_values.end()); |
| device_descriptor->has_keyboard = true; |
| device_descriptor->keyboard_descriptor = std::move(keyboard); |
| return true; |
| } |
| |
| bool Keyboard::ParseReport(const uint8_t* data, size_t len, |
| fuchsia::ui::input::InputReport* report) { |
| FXL_CHECK(report); |
| FXL_CHECK(report->keyboard); |
| |
| report->keyboard->pressed_keys.resize(0); |
| |
| for (size_t i = 0; i < key_fields_.size(); i++) { |
| hid::ReportField& field = key_fields_[i]; |
| |
| double val_out_double; |
| if (!ExtractAsUnitType(data, len, field.attr, &val_out_double)) { |
| return false; |
| } |
| |
| uint32_t val_out = static_cast<uint32_t>(val_out_double); |
| if (val_out == 0) { |
| continue; |
| } |
| |
| if (field.flags & hid::FieldTypeFlags::kArray) { |
| if (val_out == HID_USAGE_KEY_ERROR_ROLLOVER) { |
| FXL_VLOG(2) << "hid: input_report: keyboard rollover error"; |
| return false; |
| } |
| report->keyboard->pressed_keys.push_back(val_out); |
| } else { |
| report->keyboard->pressed_keys.push_back(field.attr.usage.usage); |
| } |
| } |
| |
| return true; |
| } |
| |
| } // namespace ui_input |