Merge pull request #1120 from gedankenexperimenter/testing/mouse-reports

Add verification of mouse reports to testing infrastructure
pull/1122/head
Jesse Vincent 3 years ago committed by GitHub
commit d898725725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,65 @@
/* -*- mode: c++ -*-
* Copyright (C) 2022 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "testing/ExpectedMouseReport.h"
namespace kaleidoscope {
namespace testing {
ExpectedMouseReport::ExpectedMouseReport(uint32_t timestamp,
uint8_t buttons,
int8_t x, int8_t y,
int8_t v, int8_t h,
std::string message) {
timestamp_ = timestamp;
report_data_.buttons = buttons;
report_data_.xAxis = x;
report_data_.yAxis = y;
report_data_.vWheel = v;
report_data_.hWheel = h;
failure_message_ = message;
}
uint32_t ExpectedMouseReport::Timestamp() const {
return timestamp_;
}
const std::string & ExpectedMouseReport::Message() const {
return failure_message_;
}
uint8_t ExpectedMouseReport::Buttons() const {
return report_data_.buttons;
}
int8_t ExpectedMouseReport::XAxis() const {
return report_data_.xAxis;
}
int8_t ExpectedMouseReport::YAxis() const {
return report_data_.yAxis;
}
int8_t ExpectedMouseReport::VWheel() const {
return report_data_.vWheel;
}
int8_t ExpectedMouseReport::HWheel() const {
return report_data_.hWheel;
}
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,52 @@
/* -*- mode: c++ -*-
* Copyright (C) 2022 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
#include <vector>
#include <set>
#include <string>
#include "MouseReport.h"
namespace kaleidoscope {
namespace testing {
class ExpectedMouseReport {
public:
ExpectedMouseReport(uint32_t timestamp,
uint8_t buttons, int8_t x, int8_t y, int8_t v, int8_t h,
std::string message = "");
uint8_t Buttons() const;
int8_t XAxis() const;
int8_t YAxis() const;
int8_t VWheel() const;
int8_t HWheel() const;
uint32_t Timestamp() const;
const std::string & Message() const;
private:
uint32_t timestamp_;
MouseReport::ReportData report_data_;
std::string failure_message_;
};
} // namespace testing
} // namespace kaleidoscope

@ -51,6 +51,14 @@ const KeyboardReport& HIDState::Keyboard(size_t i) const {
return keyboard_reports_.at(i);
}
const std::vector<MouseReport>& HIDState::Mouse() const {
return mouse_reports_;
}
const MouseReport& HIDState::Mouse(size_t i) const {
return mouse_reports_.at(i);
}
const std::vector<SystemControlReport>& HIDState::SystemControl() const {
return system_control_reports_;
}
@ -65,10 +73,6 @@ namespace internal {
void HIDStateBuilder::ProcessHidReport(
uint8_t id, const void* data, int len, int result) {
switch (id) {
case HID_REPORTID_MOUSE: {
LOG(ERROR) << "Dropped MouseReport: unimplemented";
break;
}
case HID_REPORTID_KEYBOARD: {
LOG(ERROR) << "Dropped BootKeyboardReport: unimplemented";
break;
@ -85,6 +89,10 @@ void HIDStateBuilder::ProcessHidReport(
ProcessSystemControlReport(SystemControlReport{data});
break;
}
case HID_REPORTID_MOUSE: {
ProcessMouseReport(MouseReport{data});
break;
}
case HID_REPORTID_MOUSE_ABSOLUTE: {
ProcessAbsoluteMouseReport(AbsoluteMouseReport{data});
break;
@ -107,6 +115,7 @@ std::unique_ptr<HIDState> HIDStateBuilder::Snapshot() {
hid_state->absolute_mouse_reports_ = std::move(absolute_mouse_reports_);
hid_state->consumer_control_reports_ = std::move(consumer_control_reports_);
hid_state->keyboard_reports_ = std::move(keyboard_reports_);
hid_state->mouse_reports_ = std::move(mouse_reports_);
hid_state->system_control_reports_ = std::move(system_control_reports_);
Clear(); // Clear global state.
@ -118,6 +127,7 @@ void HIDStateBuilder::Clear() {
absolute_mouse_reports_.clear();
consumer_control_reports_.clear();
keyboard_reports_.clear();
mouse_reports_.clear();
system_control_reports_.clear();
}
@ -136,6 +146,11 @@ void HIDStateBuilder::ProcessKeyboardReport(const KeyboardReport& report) {
keyboard_reports_.push_back(report);
}
// static
void HIDStateBuilder::ProcessMouseReport(const MouseReport& report) {
mouse_reports_.push_back(report);
}
// static
void HIDStateBuilder::ProcessSystemControlReport(const SystemControlReport& report) {
system_control_reports_.push_back(report);
@ -148,6 +163,8 @@ std::vector<ConsumerControlReport> HIDStateBuilder::consumer_control_reports_;
// static
std::vector<KeyboardReport> HIDStateBuilder::keyboard_reports_;
// static
std::vector<MouseReport> HIDStateBuilder::mouse_reports_;
// static
std::vector<SystemControlReport> HIDStateBuilder::system_control_reports_;
} // namesapce internal

@ -19,6 +19,7 @@
#include "testing/AbsoluteMouseReport.h"
#include "testing/ConsumerControlReport.h"
#include "testing/KeyboardReport.h"
#include "testing/MouseReport.h"
#include "testing/SystemControlReport.h"
// Out of order due to macro conflicts.
@ -42,6 +43,9 @@ class HIDState {
const std::vector<KeyboardReport>& Keyboard() const;
const KeyboardReport& Keyboard(size_t i) const;
const std::vector<MouseReport>& Mouse() const;
const MouseReport& Mouse(size_t i) const;
const std::vector<SystemControlReport>& SystemControl() const;
const SystemControlReport& SystemControl(size_t i) const;
@ -51,6 +55,7 @@ class HIDState {
std::vector<AbsoluteMouseReport> absolute_mouse_reports_;
std::vector<ConsumerControlReport> consumer_control_reports_;
std::vector<KeyboardReport> keyboard_reports_;
std::vector<MouseReport> mouse_reports_;
std::vector<SystemControlReport> system_control_reports_;
};
@ -68,11 +73,13 @@ class HIDStateBuilder {
static void ProcessAbsoluteMouseReport(const AbsoluteMouseReport& report);
static void ProcessConsumerControlReport(const ConsumerControlReport& report);
static void ProcessKeyboardReport(const KeyboardReport& report);
static void ProcessMouseReport(const MouseReport& report);
static void ProcessSystemControlReport(const SystemControlReport& report);
static std::vector<AbsoluteMouseReport> absolute_mouse_reports_;
static std::vector<ConsumerControlReport> consumer_control_reports_;
static std::vector<KeyboardReport> keyboard_reports_;
static std::vector<MouseReport> mouse_reports_;
static std::vector<SystemControlReport> system_control_reports_;
};

@ -0,0 +1,61 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Eric Paniagua (epaniagua@google.com)
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "testing/MouseReport.h"
#include "Kaleidoscope.h"
#include "testing/fix-macros.h"
#include <cstring>
#include "MouseButtons.h"
namespace kaleidoscope {
namespace testing {
MouseReport::MouseReport(const void* data) {
const ReportData& report_data =
*static_cast<const ReportData*>(data);
memcpy(&report_data_, &report_data, sizeof(report_data_));
timestamp_ = Runtime.millisAtCycleStart();
}
uint32_t MouseReport::Timestamp() const {
return timestamp_;
}
uint8_t MouseReport::Buttons() const {
return report_data_.buttons;
}
int8_t MouseReport::XAxis() const {
return report_data_.xAxis;
}
int8_t MouseReport::YAxis() const {
return report_data_.yAxis;
}
int8_t MouseReport::VWheel() const {
return report_data_.vWheel;
}
int8_t MouseReport::HWheel() const {
return report_data_.hWheel;
}
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,56 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Eric Paniagua (epaniagua@google.com)
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
#include <vector>
#include "HID-Settings.h"
#include "MultiReport/Mouse.h"
namespace kaleidoscope {
namespace testing {
class MouseReport {
public:
typedef HID_MouseReport_Data_t ReportData;
static constexpr uint8_t kHidReportType = HID_REPORTID_MOUSE;
MouseReport(const void* data);
static constexpr uint8_t kButtonLeft = MOUSE_LEFT;
static constexpr uint8_t kButtonRight = MOUSE_RIGHT;
static constexpr uint8_t kButtonMiddle = MOUSE_MIDDLE;
static constexpr uint8_t kButtonPrev = MOUSE_PREV;
static constexpr uint8_t kButtonNext = MOUSE_NEXT;
uint32_t Timestamp() const;
uint8_t Buttons() const;
int8_t XAxis() const;
int8_t YAxis() const;
int8_t VWheel() const;
int8_t HWheel() const;
private:
uint32_t timestamp_;
ReportData report_data_;
};
} // namespace testing
} // namespce kaleidoscope

@ -19,6 +19,8 @@
#include "HIDReportObserver.h"
#include "testing/HIDState.h"
#include <bitset>
namespace kaleidoscope {
namespace testing {
@ -39,7 +41,8 @@ void VirtualDeviceTest::LoadState() {
void VirtualDeviceTest::ClearState() {
output_state_ = nullptr;
input_timestamps_.clear();
expected_reports_.clear();
expected_keyboard_reports_.clear();
expected_mouse_reports_.clear();
}
const HIDState* VirtualDeviceTest::HIDReports() const {
@ -69,77 +72,96 @@ void VirtualDeviceTest::ReleaseKey(KeyAddr addr) {
// =============================================================================
void VirtualDeviceTest::ExpectReport(Keycodes keys,
void VirtualDeviceTest::ExpectKeyboardReport(Keycodes keys,
std::string description) {
size_t report_timestamp{Runtime.millisAtCycleStart()};
ClearReport();
ClearKeyboardReport();
for (Key key : keys) {
AddToReport(key);
AddToKeyboardReport(key);
}
ExpectedKeyboardReport new_report(report_timestamp,
current_keyboard_keycodes_,
description);
expected_reports_.push_back(new_report);
expected_keyboard_reports_.push_back(new_report);
}
// =============================================================================
void VirtualDeviceTest::ExpectReport(AddKeycodes added_keys,
void VirtualDeviceTest::ExpectKeyboardReport(AddKeycodes added_keys,
RemoveKeycodes removed_keys,
std::string description) {
uint32_t report_timestamp = Runtime.millisAtCycleStart();
for (Key key : added_keys) {
AddToReport(key);
AddToKeyboardReport(key);
}
for (Key key : removed_keys) {
RemoveFromReport(key);
RemoveFromKeyboardReport(key);
}
ExpectedKeyboardReport new_report(report_timestamp,
current_keyboard_keycodes_,
description);
expected_reports_.push_back(new_report);
expected_keyboard_reports_.push_back(new_report);
}
// -----------------------------------------------------------------------------
void VirtualDeviceTest::ExpectReport(AddKeycodes added_keys,
void VirtualDeviceTest::ExpectKeyboardReport(AddKeycodes added_keys,
std::string description) {
ExpectReport(added_keys, RemoveKeycodes{}, description);
ExpectKeyboardReport(added_keys, RemoveKeycodes{}, description);
}
void VirtualDeviceTest::ExpectReport(RemoveKeycodes removed_keys,
void VirtualDeviceTest::ExpectKeyboardReport(RemoveKeycodes removed_keys,
std::string description) {
ExpectReport(AddKeycodes{}, removed_keys, description);
ExpectKeyboardReport(AddKeycodes{}, removed_keys, description);
}
// =============================================================================
void VirtualDeviceTest::ClearReport() {
void VirtualDeviceTest::ClearKeyboardReport() {
current_keyboard_keycodes_.clear();
}
void VirtualDeviceTest::AddToReport(Key key) {
void VirtualDeviceTest::AddToKeyboardReport(Key key) {
current_keyboard_keycodes_.insert(key.getKeyCode());
}
void VirtualDeviceTest::RemoveFromReport(Key key) {
void VirtualDeviceTest::RemoveFromKeyboardReport(Key key) {
current_keyboard_keycodes_.erase(key.getKeyCode());
}
// =============================================================================
void VirtualDeviceTest::ExpectMouseReport(uint8_t buttons,
int8_t x, int8_t y,
int8_t v, int8_t h,
std::string description) {
uint32_t report_timestamp = Runtime.millisAtCycleStart();
ExpectedMouseReport new_report(report_timestamp,
buttons, x, y, v, h,
description);
expected_mouse_reports_.push_back(new_report);
}
// =============================================================================
void VirtualDeviceTest::CheckReports() const {
int observed_report_count = HIDReports()->Keyboard().size();
int expected_report_count = expected_reports_.size();
CheckKeyboardReports();
CheckMouseReports();
}
EXPECT_EQ(observed_report_count, expected_report_count);
void VirtualDeviceTest::CheckKeyboardReports() const {
int observed_keyboard_report_count = HIDReports()->Keyboard().size();
int expected_keyboard_report_count = expected_keyboard_reports_.size();
int max_count = std::max(observed_report_count, expected_report_count);
EXPECT_EQ(observed_keyboard_report_count, expected_keyboard_report_count);
for (int i = 0; i < observed_report_count; ++i) {
int max_count = std::max(observed_keyboard_report_count,
expected_keyboard_report_count);
for (int i = 0; i < observed_keyboard_report_count; ++i) {
auto observed_report = HIDReports()->Keyboard(i);
auto observed_keycodes = observed_report.ActiveKeycodes();
if (i < expected_report_count) {
auto expected_report = expected_reports_[i];
if (i < expected_keyboard_report_count) {
auto expected_report = expected_keyboard_reports_[i];
auto expected_keycodes = expected_report.Keycodes();
EXPECT_THAT(observed_keycodes,
::testing::ElementsAreArray(expected_keycodes))
<< expected_reports_[i].Message() << " (i=" << i << ")";
<< expected_keyboard_reports_[i].Message() << " (i=" << i << ")";
EXPECT_EQ(observed_report.Timestamp(), expected_report.Timestamp())
<< "Report timestamps don't match (i=" << i << ")";
@ -155,5 +177,47 @@ void VirtualDeviceTest::CheckReports() const {
}
}
void VirtualDeviceTest::CheckMouseReports() const {
int observed_mouse_report_count = HIDReports()->Mouse().size();
int expected_mouse_report_count = expected_mouse_reports_.size();
EXPECT_EQ(observed_mouse_report_count, expected_mouse_report_count);
int max_count = std::max(observed_mouse_report_count,
expected_mouse_report_count);
for (int i = 0; i < observed_mouse_report_count; ++i) {
auto observed_report = HIDReports()->Mouse(i);
if (i < expected_mouse_report_count) {
auto expected_report = expected_mouse_reports_[i];
EXPECT_EQ(observed_report.Buttons(), expected_report.Buttons())
<< expected_mouse_reports_[i].Message() << " (i=" << i << ")";
EXPECT_EQ(observed_report.XAxis(), expected_report.XAxis())
<< expected_mouse_reports_[i].Message() << " (i=" << i << ")";
EXPECT_EQ(observed_report.YAxis(), expected_report.YAxis())
<< expected_mouse_reports_[i].Message() << " (i=" << i << ")";
EXPECT_EQ(observed_report.VWheel(), expected_report.VWheel())
<< expected_mouse_reports_[i].Message() << " (i=" << i << ")";
EXPECT_EQ(observed_report.HWheel(), expected_report.HWheel())
<< expected_mouse_reports_[i].Message() << " (i=" << i << ")";
EXPECT_EQ(observed_report.Timestamp(), expected_report.Timestamp())
<< "Report timestamps don't match (i=" << i << ")";
} else {
std::bitset<8> observed_buttons{observed_report.Buttons()};
std::cerr << "Unexpected mouse report at "
<< observed_report.Timestamp() << "ms: {"
<< " buttons: " << observed_buttons
<< " x: " << int(observed_report.XAxis())
<< " y: " << int(observed_report.YAxis())
<< " v: " << int(observed_report.VWheel())
<< " h: " << int(observed_report.HWheel())
<< " }" << std::endl;
}
}
}
} // namespace testing
} // namespace kaleidoscope

@ -19,6 +19,7 @@
#include <cstddef>
#include "testing/ExpectedKeyboardReport.h"
#include "testing/ExpectedMouseReport.h"
#include "testing/SimHarness.h"
#include "testing/State.h"
@ -103,27 +104,34 @@ class VirtualDeviceTest : public ::testing::Test {
// keycode changes in a single report; others only a single keycode. Some run
// the simulator for a specified number of milliseconds or cycles first. These
// expected-value reports are all stored in a vector:
std::vector<ExpectedKeyboardReport> expected_reports_ = {};
std::vector<ExpectedKeyboardReport> expected_keyboard_reports_ = {};
void ExpectReport(AddKeycodes added_keys,
void ExpectKeyboardReport(AddKeycodes added_keys,
RemoveKeycodes removed_keys,
std::string description);
void ExpectReport(Keycodes added_keys, std::string description);
void ExpectReport(AddKeycodes added_keys, std::string description);
void ExpectReport(RemoveKeycodes removed_keys, std::string description);
void ExpectKeyboardReport(Keycodes added_keys, std::string description);
void ExpectKeyboardReport(AddKeycodes added_keys, std::string description);
void ExpectKeyboardReport(RemoveKeycodes removed_keys, std::string description);
std::vector<ExpectedMouseReport> expected_mouse_reports_ = {};
void ExpectMouseReport(uint8_t buttons, int8_t x, int8_t y,
int8_t v, int8_t h, std::string description);
// ---------------------------------------------------------------------------
std::set<uint8_t> current_keyboard_keycodes_ = {};
// Manage the set of keycodes expected in the next report
void ClearReport();
void AddToReport(Key key);
void RemoveFromReport(Key key);
void ClearKeyboardReport();
void AddToKeyboardReport(Key key);
void RemoveFromKeyboardReport(Key key);
// ---------------------------------------------------------------------------
// Compare accumulated observed and expected reports, matching both timestamps
// and keycodes.
void CheckReports() const;
void CheckKeyboardReports() const;
void CheckMouseReports() const;
};

@ -138,6 +138,76 @@ sub load_from_text {
keys => [@keys]
};
}
if ( $content =~ /^no mouse-report/ ) {
return {
report_type => 'mouse',
count => 0
};
}
if ( $content =~ /^mouse-report\s+(.*)$/ ) {
my $report_data = $1;
my @args = split( /,?\s+/, lc $report_data );
my $mouse_report_data = {};
$mouse_report_data->{buttons} = [];
$mouse_report_data->{x} = "0";
$mouse_report_data->{y} = "0";
$mouse_report_data->{v} = "0";
$mouse_report_data->{h} = "0";
if ( scalar(@args) == 1 && $args[0] =~ /^empty$/i ) {
@args = ();
}
for my $arg (@args) {
if ( $arg =~ /(\w+)=([\w\d\-\+]+)/ ) {
my $field = $1;
my $value = $2;
if ( $field =~ /button/ ) {
if ( $value =~ /^l/ ) {
$value = 'MouseReport::kButtonLeft';
}
elsif ( $value =~ /^r/ ) {
$value = 'MouseReport::kButtonRight';
}
elsif ( $value =~ /^m/ ) {
$value = 'MouseReport::kButtonMiddle';
}
elsif ( $value =~ /^n/ ) {
$value = 'MouseReport::kButtonNext';
}
elsif ( $value =~ /^p/ ) {
$value = 'MouseReport::kButtonPrev';
}
else {
die
"Couldn't parse mouse button value from $content at line $line_num";
}
push @{ $mouse_report_data->{buttons} }, $value;
}
elsif ( $field =~ /x/ ) {
$mouse_report_data->{x} = $value;
}
elsif ( $field =~ /y/ ) {
$mouse_report_data->{y} = $value;
}
elsif ( $field =~ /v/ ) {
$mouse_report_data->{v} = $value;
}
elsif ( $field =~ /h/ ) {
$mouse_report_data->{h} = $value;
}
else {
die "Don't know how parse $content at line $line_num";
}
}
else {
die "Don't know how parse $content at line $line_num";
}
}
return {
count => 1, # We expect one report here
report_type => 'mouse',
data => $mouse_report_data,
}
}
else {
die "Don't know how parse $content at line $line_num";
}
@ -394,15 +464,22 @@ sub generate_release {
sub generate_expect_report {
my $report = shift;
if ( !$report->{data}->{report_type}
|| $report->{data}->{report_type} ne 'keyboard' )
{
if ( $report->{data}->{report_type} eq 'keyboard' ) {
generate_expect_keyboard_report($report);
}
elsif ( $report->{data}->{report_type} eq 'mouse' ) {
generate_expect_mouse_report($report);
}
else {
die
"Don't know how to work with expectaions of reports other than 'keyboard' reports at line #"
"Don't know how to handle expectaions of report types other than 'keyboard' and 'mouse' at line #"
. $report->{line_num} . "\n";
}
$reports_expected++;
}
sub generate_expect_keyboard_report {
my $report = shift;
if ( $report->{data}->{count} == 0 ) {
if ( $report->{comment} ) {
@ -422,7 +499,38 @@ sub generate_expect_report {
: ( $report->{data}->{keys} )
)
);
cxx( "ExpectReport(Keycodes{$codes}, \""
cxx( "ExpectKeyboardReport(Keycodes{$codes}, \""
. ( $report->{comment} || 'No explanatory comment specified' )
. "\");" );
cxx("");
}
sub generate_expect_mouse_report {
my $report = shift;
if ( $report->{data}->{count} == 0 ) {
if ( $report->{comment} ) {
cxx_comment( $report->{comment} );
}
cxx_comment(
"We don't expect any report here, and have told the tests to check that"
);
return;
}
my $buttons_code = "0";
my @buttons = ( ref( $report->{data}->{data}{buttons} )
? @{ $report->{data}->{data}{buttons} }
: ( $report->{data}->{data}{buttons} ) );
for my $button_value (@buttons) {
$buttons_code .= " | $button_value";
}
cxx("ExpectMouseReport($buttons_code, "
. $report->{data}{data}{x} . ", "
. $report->{data}{data}{y} . ", "
. $report->{data}{data}{v} . ", "
. $report->{data}{data}{h} . ", "
. "\""
. ( $report->{comment} || 'No explanatory comment specified' )
. "\");" );
cxx("");

@ -0,0 +1,49 @@
/* -*- mode: c++ -*-
* Copyright (C) 2022 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-MouseKeys.h>
// *INDENT-OFF*
KEYMAPS(
[0] = KEYMAP_STACKED
(
Key_mouseUp, Key_mouseDn, Key_mouseL, Key_mouseR, ___, ___, ___,
Key_mouseScrollUp, Key_mouseScrollDn, Key_mouseScrollL, Key_mouseScrollR, ___, ___, ___,
Key_mouseBtnL, Key_mouseBtnM, Key_mouseBtnR, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___
),
)
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(MouseKeys);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,6 @@
{
"cpu": {
"fqbn": "keyboardio:virtual:model01",
"port": ""
}
}

@ -0,0 +1,72 @@
VERSION 1
KEYSWITCH MOVE_UP 0 0
KEYSWITCH MOVE_DOWN 0 1
KEYSWITCH MOVE_LEFT 0 2
KEYSWITCH MOVE_RIGHT 0 3
KEYSWITCH SCROLL_UP 1 0
KEYSWITCH SCROLL_DOWN 1 1
KEYSWITCH SCROLL_LEFT 1 2
KEYSWITCH SCROLL_RIGHT 1 3
KEYSWITCH BUTTON_L 2 0
KEYSWITCH BUTTON_M 2 1
KEYSWITCH BUTTON_R 2 2
# ==============================================================================
NAME MouseKeys move up
RUN 3 ms
PRESS MOVE_UP
RUN 1 cycle
RUN 15 ms
EXPECT mouse-report y=-1
RUN 1 cycle
EXPECT mouse-report empty
RUN 15 ms
EXPECT mouse-report y=-1
RUN 1 cycle
EXPECT mouse-report empty
RUN 5 ms
RELEASE MOVE_UP
RUN 1 cycle
EXPECT no mouse-report
RUN 5 ms
# ==============================================================================
NAME MouseKeys button left
RUN 4 ms
PRESS BUTTON_L
RUN 1 cycle
EXPECT mouse-report button=L
RUN 20 ms
RELEASE BUTTON_L
RUN 1 cycle
EXPECT mouse-report empty
RUN 5 ms
# ==============================================================================
NAME MouseKeys scroll down
RUN 4 ms
PRESS SCROLL_UP
RUN 1 cycle
EXPECT mouse-report v=1
RUN 50 ms
EXPECT mouse-report v=1
RUN 10 ms
RELEASE SCROLL_UP
RUN 1 cycle
EXPECT no mouse-report
RUN 5 ms
Loading…
Cancel
Save