Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core] Split support for pointing devices. #15304

Merged
merged 25 commits into from
Dec 27, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
doxygen comments
  • Loading branch information
daskygit committed Dec 26, 2021
commit 445208390af12ba5dff82bfa944f93e6e72c9ab7
245 changes: 205 additions & 40 deletions quantum/pointing_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,24 @@
report_mouse_t sharedReport = {};
uint16_t sharedCpi = 0;

void pointing_device_set_shared_report(report_mouse_t report) { sharedReport = report; }
/**
* @brief Sets the shared mouse report used be pointing device task
*
* NOTE : Only available when using SPLIT_POINTING_ENABLE
*
* @param[in] report report_mouse_t
*/
void pointing_device_set_shared_report(report_mouse_t report) { sharedReport = report; }

/**
* @brief Gets current pointing device CPI if supported
*
* Gets current cpi of the shared report and returns it as uint16_t
*
* NOTE : Only available when using SPLIT_POINTING_ENABLE
*
* @return cpi value as uint16_t
*/
uint16_t pointing_device_get_shared_cpi(void) { return sharedCpi; }

# if defined(POINTING_DEVICE_LEFT)
Expand All @@ -49,13 +66,57 @@ static report_mouse_t mouseReport = {};

extern const pointing_device_driver_t pointing_device_driver;

/**
* @brief Compares 2 mouse reports for difference and returns result
*
* @param[in] new report_mouse_t
* @param[in] old report_mouse_t
* @return bool result
*/
__attribute__((weak)) bool has_mouse_report_changed(report_mouse_t new, report_mouse_t old) { return memcmp(&new, &old, sizeof(new)); }

__attribute__((weak)) void pointing_device_init_kb(void) {}
__attribute__((weak)) void pointing_device_init_user(void) {}
/**
* @brief Keyboard level code pointing device initialisation
*
*/
__attribute__((weak)) void pointing_device_init_kb(void) {}

/**
* @brief User level code pointing device initialisation
*
*/
__attribute__((weak)) void pointing_device_init_user(void) {}

/**
* @brief Weak function allowing for keyboard level mouse report modification
*
* Takes report_mouse_t struct allowing modification at keyboard level then returns report_mouse_t.
*
* @param[in] mouse_report report_mouse_t
* @return report_mouse_t
*/
__attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { return pointing_device_task_user(mouse_report); }

/**
* @brief Weak function allowing for user level mouse report modification
*
* Takes report_mouse_t struct allowing modification at user level then returns report_mouse_t.
*
* @param[in] mouse_report report_mouse_t
* @return report_mouse_t
*/
__attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { return mouse_report; }

/**
* @brief Handles pointing device buttons
*
* Returns modified button bitmask using bool pressed and selected pointing_device_buttons_t button in uint8_t buttons bitmask.
*
* @param buttons[in] uint8_t bitmask
* @param pressed[in] bool
* @param button[in] pointing_device_buttons_t value
* @return Modified uint8_t bitmask buttons
*/
__attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button) {
if (pressed) {
buttons |= 1 << (button);
Expand All @@ -65,6 +126,11 @@ __attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bo
return buttons;
}

/**
* @brief Initialises pointing device
*
* Initialises pointing device, perform driver init and optional keyboard/user level code.
*/
__attribute__((weak)) void pointing_device_init(void) {
pointing_device_driver.init();
#ifdef POINTING_DEVICE_MOTION_PIN
Expand All @@ -74,6 +140,12 @@ __attribute__((weak)) void pointing_device_init(void) {
pointing_device_init_user();
}

/**
* @brief Sends processed mouse report to host
*
* This sends the mouse report generated by pointing_device_task if changed since the last report. Once send zeros mouse report except buttons.
*
*/
__attribute__((weak)) void pointing_device_send(void) {
static report_mouse_t old_report = {};

Expand All @@ -90,33 +162,48 @@ __attribute__((weak)) void pointing_device_send(void) {
memcpy(&old_report, &mouseReport, sizeof(mouseReport));
}

/**
* @brief Adjust mouse report by any optional common pointing configuration defines
*
* This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines.
*
* @param mouse_report[in] takes a report_mouse_t to be adjusted
* @return report_mouse_t with adjusted values
*/
report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report) {
// Support rotation of the sensor data
// Support rotation of the sensor data
#if defined(POINTING_DEVICE_ROTATION_90) || defined(POINTING_DEVICE_ROTATION_180) || defined(POINTING_DEVICE_ROTATION_270)
int8_t x = mouse_report.x, y = mouse_report.y;
int8_t x = mouse_report.x, y = mouse_report.y;
# if defined(POINTING_DEVICE_ROTATION_90)
mouse_report.x = y;
mouse_report.y = -x;
mouse_report.x = y;
mouse_report.y = -x;
# elif defined(POINTING_DEVICE_ROTATION_180)
mouse_report.x = -x;
mouse_report.y = -y;
mouse_report.x = -x;
mouse_report.y = -y;
# elif defined(POINTING_DEVICE_ROTATION_270)
mouse_report.x = -y;
mouse_report.y = x;
mouse_report.x = -y;
mouse_report.y = x;
# else
# error "How the heck did you get here?!"
# endif
#endif
// Support Inverting the X and Y Axises
// Support Inverting the X and Y Axises
#if defined(POINTING_DEVICE_INVERT_X)
mouse_report.x = -mouse_report.x;
mouse_report.x = -mouse_report.x;
#endif
#if defined(POINTING_DEVICE_INVERT_Y)
mouse_report.y = -mouse_report.y;
mouse_report.y = -mouse_report.y;
#endif
return mouse_report;
}

/**
* @brief Retrieves and processes pointing device data.
*
* This function is part of the keyboard loop and retrieves the mouse report from the pointing device driver.
* It applies any optional configuration e.g. rotation or axis inversion and then initiates a send.
*
*/
__attribute__((weak)) void pointing_device_task(void) {
#if defined(SPLIT_POINTING_ENABLE)
// Don't poll the target side pointing device.
Expand Down Expand Up @@ -151,8 +238,8 @@ __attribute__((weak)) void pointing_device_task(void) {
mouseReport.buttons = oldButtons;
mouseReport = pointing_device_driver.get_report(mouseReport);
oldButtons = mouseReport.buttons;
# elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
mouseReport = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_report(mouseReport) : sharedReport;
# elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
mouseReport = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_report(mouseReport) : sharedReport;
# else
# error "You need to define the side(s) the pointing device is on. POINTING_DEVICE_COMBINED / POINTING_DEVICE_LEFT / POINTING_DEVICE_RIGHT"
# endif
Expand All @@ -169,9 +256,9 @@ __attribute__((weak)) void pointing_device_task(void) {
mouseReport = pointing_device_adjust_by_defines_right(mouseReport);
sharedReport = pointing_device_adjust_by_defines(sharedReport);
}
mouseReport = is_keyboard_left() ? pointing_device_task_combined_kb(mouseReport, sharedReport) : pointing_device_task_combined_kb(sharedReport, mouseReport);
mouseReport = is_keyboard_left() ? pointing_device_task_combined_kb(mouseReport, sharedReport) : pointing_device_task_combined_kb(sharedReport, mouseReport);
#else
mouseReport = pointing_device_adjust_by_defines(mouseReport);
mouseReport = pointing_device_adjust_by_defines(mouseReport);
mouseReport = pointing_device_task_kb(mouseReport);
#endif
// combine with mouse report to ensure that the combined is sent correctly
Expand All @@ -182,10 +269,27 @@ __attribute__((weak)) void pointing_device_task(void) {
pointing_device_send();
}

/**
* @brief Gets current mouse report used by pointing device task
*
* @return report_mouse_t
*/
report_mouse_t pointing_device_get_report(void) { return mouseReport; }

/**
* @brief Sets mouse report used be pointing device task
*
* @param[in] newMouseReport
*/
void pointing_device_set_report(report_mouse_t newMouseReport) { mouseReport = newMouseReport; }

/**
* @brief Gets current pointing device CPI if supported
*
* Gets current cpi from pointing device driver if supported and returns it as uint16_t
*
* @return cpi value as uint16_t
*/
uint16_t pointing_device_get_cpi(void) {
#if defined(SPLIT_POINTING_ENABLE)
return POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_cpi() : sharedCpi;
Expand All @@ -194,6 +298,13 @@ uint16_t pointing_device_get_cpi(void) {
#endif
}

/**
* @brief Set pointing device CPI if supported
*
* Takes a uint16_t value to set pointing device cpi if supported by driver.
*
* @param[in] cpi uint16_t value.
*/
void pointing_device_set_cpi(uint16_t cpi) {
#if defined(SPLIT_POINTING_ENABLE)
if (POINTING_DEVICE_THIS_SIDE) {
Expand All @@ -207,6 +318,16 @@ void pointing_device_set_cpi(uint16_t cpi) {
}

#if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)
/**
* @brief Set pointing device CPI if supported
*
* Takes a bool and uint16_t and allows setting cpi for a single side when using 2 pointing devices with a split keyboard.
*
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
*
* @param[in] left true = left, false = right.
* @param[in] cpi uint16_t value.
*/
void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) {
bool local = (is_keyboard_left() & left) ? true : false;
if (local) {
Expand All @@ -216,6 +337,17 @@ void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) {
}
}

/**
* @brief combines 2 mouse reports and returns 2
*
* Takes 2 report_mouse_t structs, performs an inclusive or ignoring report_id then returns the resulting report_mouse_t struct.
*
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
*
* @param[in] left_report left report_mouse_t
* @param[in] right_report right report_mouse_t
* @return combined report_mouse_t of left_report and right_report
*/
report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report) {
left_report.x |= right_report.x;
left_report.y |= right_report.y;
Expand All @@ -225,33 +357,66 @@ report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, repor
return left_report;
}

/**
* @brief Adjust mouse report by any optional right pointing configuration defines
*
* This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines.
*
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
*
* @param[in] mouse_report report_mouse_t to be adjusted
* @return report_mouse_t with adjusted values
*/
report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report) {
// Support rotation of the sensor data
#if defined(POINTING_DEVICE_ROTATION_90_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT)
int8_t x = mouse_report.x, y = mouse_report.y;
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT)
mouse_report.x = y;
mouse_report.y = -x;
# elif defined(POINTING_DEVICE_ROTATION_180_RIGHT)
mouse_report.x = -x;
mouse_report.y = -y;
# elif defined(POINTING_DEVICE_ROTATION_270_RIGHT)
mouse_report.x = -y;
mouse_report.y = x;
# else
# error "How the heck did you get here?!"
// Support rotation of the sensor data
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT)
int8_t x = mouse_report.x, y = mouse_report.y;
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT)
mouse_report.x = y;
mouse_report.y = -x;
# elif defined(POINTING_DEVICE_ROTATION_180_RIGHT)
mouse_report.x = -x;
mouse_report.y = -y;
# elif defined(POINTING_DEVICE_ROTATION_270_RIGHT)
mouse_report.x = -y;
mouse_report.y = x;
# else
# error "How the heck did you get here?!"
# endif
# endif
// Support Inverting the X and Y Axises
# if defined(POINTING_DEVICE_INVERT_X_RIGHT)
mouse_report.x = -mouse_report.x;
# endif
# if defined(POINTING_DEVICE_INVERT_Y_RIGHT)
mouse_report.y = -mouse_report.y;
# endif
#endif
// Support Inverting the X and Y Axises
#if defined(POINTING_DEVICE_INVERT_X_RIGHT)
mouse_report.x = -mouse_report.x;
#endif
#if defined(POINTING_DEVICE_INVERT_Y_RIGHT)
mouse_report.y = -mouse_report.y;
#endif
return mouse_report;
}

/**
* @brief Weak function allowing for keyboard level mouse report modification
*
* Takes 2 report_mouse_t structs allowing individual modification of sides at keyboard level then returns pointing_device_task_combined_user.
*
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
*
* @param[in] left_report report_mouse_t
* @param[in] right_report report_mouse_t
* @return pointing_device_task_combined_user(left_report, right_report) by default
*/
__attribute__((weak)) report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report) { return pointing_device_task_combined_user(left_report, right_report); }

/**
* @brief Weak function allowing for user level mouse report modification
*
* Takes 2 report_mouse_t structs allowing individual modification of sides at user level then returns pointing_device_combine_reports.
*
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
*
* @param[in] left_report report_mouse_t
* @param[in] right_report report_mouse_t
* @return pointing_device_combine_reports(left_report, right_report) by default
*/
__attribute__((weak)) report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) { return pointing_device_combine_reports(left_report, right_report); }
#endif