pointing_device.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. /* Copyright 2017 Joshua Broekhuijsen <snipeye+qmk@gmail.com>
  2. * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
  3. * Copyright 2021 Dasky (@daskygit)
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "pointing_device.h"
  19. #include <string.h>
  20. #include "timer.h"
  21. #include "gpio.h"
  22. #ifdef MOUSEKEY_ENABLE
  23. # include "mousekey.h"
  24. #endif
  25. #ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
  26. # include "usb_descriptor_common.h"
  27. #endif
  28. #if (defined(POINTING_DEVICE_ROTATION_90) + defined(POINTING_DEVICE_ROTATION_180) + defined(POINTING_DEVICE_ROTATION_270)) > 1
  29. # error More than one rotation selected. This is not supported.
  30. #endif
  31. #if defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_COMBINED)
  32. # ifndef SPLIT_POINTING_ENABLE
  33. # error "Using POINTING_DEVICE_LEFT or POINTING_DEVICE_RIGHT or POINTING_DEVICE_COMBINED, then SPLIT_POINTING_ENABLE is required but has not been defined"
  34. # endif
  35. #endif
  36. #if defined(SPLIT_POINTING_ENABLE)
  37. # include "transactions.h"
  38. # include "keyboard.h"
  39. report_mouse_t shared_mouse_report = {};
  40. uint16_t shared_cpi = 0;
  41. /**
  42. * @brief Sets the shared mouse report used be pointing device task
  43. *
  44. * NOTE : Only available when using SPLIT_POINTING_ENABLE
  45. *
  46. * @param[in] new_mouse_report report_mouse_t
  47. */
  48. void pointing_device_set_shared_report(report_mouse_t new_mouse_report) {
  49. shared_mouse_report = new_mouse_report;
  50. }
  51. /**
  52. * @brief Gets current pointing device CPI if supported
  53. *
  54. * Gets current cpi of the shared report and returns it as uint16_t
  55. *
  56. * NOTE : Only available when using SPLIT_POINTING_ENABLE
  57. *
  58. * @return cpi value as uint16_t
  59. */
  60. uint16_t pointing_device_get_shared_cpi(void) {
  61. return shared_cpi;
  62. }
  63. # if defined(POINTING_DEVICE_LEFT)
  64. # define POINTING_DEVICE_THIS_SIDE is_keyboard_left()
  65. # elif defined(POINTING_DEVICE_RIGHT)
  66. # define POINTING_DEVICE_THIS_SIDE !is_keyboard_left()
  67. # elif defined(POINTING_DEVICE_COMBINED)
  68. # define POINTING_DEVICE_THIS_SIDE true
  69. # endif
  70. #endif // defined(SPLIT_POINTING_ENABLE)
  71. static report_mouse_t local_mouse_report = {};
  72. static bool pointing_device_force_send = false;
  73. static pointing_device_status_t pointing_device_status = POINTING_DEVICE_STATUS_UNKNOWN;
  74. #ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
  75. static uint16_t hires_scroll_resolution;
  76. #endif
  77. #define POINTING_DEVICE_DRIVER_CONCAT(name) name##_pointing_device_driver
  78. #define POINTING_DEVICE_DRIVER(name) POINTING_DEVICE_DRIVER_CONCAT(name)
  79. #ifdef POINTING_DEVICE_DRIVER_custom
  80. __attribute__((weak)) bool pointing_device_driver_init(void) {
  81. return false;
  82. }
  83. __attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
  84. return mouse_report;
  85. }
  86. __attribute__((weak)) uint16_t pointing_device_driver_get_cpi(void) {
  87. return 0;
  88. }
  89. __attribute__((weak)) void pointing_device_driver_set_cpi(uint16_t cpi) {}
  90. const pointing_device_driver_t custom_pointing_device_driver = {
  91. .init = pointing_device_driver_init,
  92. .get_report = pointing_device_driver_get_report,
  93. .get_cpi = pointing_device_driver_get_cpi,
  94. .set_cpi = pointing_device_driver_set_cpi,
  95. };
  96. #endif
  97. const pointing_device_driver_t *pointing_device_driver = &POINTING_DEVICE_DRIVER(POINTING_DEVICE_DRIVER_NAME);
  98. __attribute__((weak)) void pointing_device_init_modules(void) {}
  99. __attribute__((weak)) report_mouse_t pointing_device_task_modules(report_mouse_t mouse_report) {
  100. return mouse_report;
  101. }
  102. /**
  103. * @brief Keyboard level code pointing device initialisation
  104. *
  105. */
  106. __attribute__((weak)) void pointing_device_init_kb(void) {}
  107. /**
  108. * @brief User level code pointing device initialisation
  109. *
  110. */
  111. __attribute__((weak)) void pointing_device_init_user(void) {}
  112. /**
  113. * @brief Weak function allowing for keyboard level mouse report modification
  114. *
  115. * Takes report_mouse_t struct allowing modification at keyboard level then returns report_mouse_t.
  116. *
  117. * @param[in] mouse_report report_mouse_t
  118. * @return report_mouse_t
  119. */
  120. __attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
  121. return pointing_device_task_user(mouse_report);
  122. }
  123. /**
  124. * @brief Weak function allowing for user level mouse report modification
  125. *
  126. * Takes report_mouse_t struct allowing modification at user level then returns report_mouse_t.
  127. *
  128. * @param[in] mouse_report report_mouse_t
  129. * @return report_mouse_t
  130. */
  131. __attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
  132. return mouse_report;
  133. }
  134. /**
  135. * @brief Handles pointing device buttons
  136. *
  137. * Returns modified button bitmask using bool pressed and selected pointing_device_buttons_t button in uint8_t buttons bitmask.
  138. *
  139. * @param buttons[in] uint8_t bitmask
  140. * @param pressed[in] bool
  141. * @param button[in] pointing_device_buttons_t value
  142. * @return Modified uint8_t bitmask buttons
  143. */
  144. __attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button) {
  145. if (pressed) {
  146. buttons |= 1 << (button);
  147. } else {
  148. buttons &= ~(1 << (button));
  149. }
  150. return buttons;
  151. }
  152. /**
  153. * @brief Initialises pointing device
  154. *
  155. * Initialises pointing device, perform driver init and optional keyboard/user level code.
  156. */
  157. __attribute__((weak)) void pointing_device_init(void) {
  158. #if defined(SPLIT_POINTING_ENABLE)
  159. if ((POINTING_DEVICE_THIS_SIDE))
  160. #endif
  161. {
  162. if (pointing_device_driver->init()) {
  163. pointing_device_status = POINTING_DEVICE_STATUS_SUCCESS;
  164. } else {
  165. pointing_device_status = POINTING_DEVICE_STATUS_INIT_FAILED;
  166. }
  167. #ifdef POINTING_DEVICE_MOTION_PIN
  168. # ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW
  169. gpio_set_pin_input_high(POINTING_DEVICE_MOTION_PIN);
  170. # else
  171. gpio_set_pin_input(POINTING_DEVICE_MOTION_PIN);
  172. # endif
  173. #endif
  174. }
  175. #ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
  176. hires_scroll_resolution = POINTING_DEVICE_HIRES_SCROLL_MULTIPLIER;
  177. for (int i = 0; i < POINTING_DEVICE_HIRES_SCROLL_EXPONENT; i++) {
  178. hires_scroll_resolution *= 10;
  179. }
  180. #endif
  181. pointing_device_init_modules();
  182. pointing_device_init_kb();
  183. pointing_device_init_user();
  184. }
  185. /**
  186. * @brief Gets status of pointing device
  187. *
  188. * Returns current pointing device status
  189. * @return pointing_device_status_t
  190. */
  191. __attribute__((weak)) pointing_device_status_t pointing_device_get_status(void) {
  192. #ifdef SPLIT_POINTING_ENABLE
  193. // Assume target side is always good, split transaction checksum should stop additional reports being generated.
  194. return POINTING_DEVICE_THIS_SIDE ? pointing_device_status : POINTING_DEVICE_STATUS_SUCCESS;
  195. #else
  196. return pointing_device_status;
  197. #endif
  198. }
  199. /**
  200. * @brief Sets status of pointing device
  201. */
  202. void pointing_device_set_status(pointing_device_status_t status) {
  203. pointing_device_status = status;
  204. }
  205. /**
  206. * @brief Sends processed mouse report to host
  207. *
  208. * This sends the mouse report generated by pointing_device_task if changed since the last report. Once send zeros mouse report except buttons.
  209. *
  210. */
  211. __attribute__((weak)) bool pointing_device_send(void) {
  212. static report_mouse_t old_report = {};
  213. bool should_send_report = has_mouse_report_changed(&local_mouse_report, &old_report);
  214. if (should_send_report) {
  215. host_mouse_send(&local_mouse_report);
  216. }
  217. // send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device
  218. uint8_t buttons = local_mouse_report.buttons;
  219. memset(&local_mouse_report, 0, sizeof(local_mouse_report));
  220. local_mouse_report.buttons = buttons;
  221. memcpy(&old_report, &local_mouse_report, sizeof(local_mouse_report));
  222. return should_send_report || buttons;
  223. }
  224. /**
  225. * @brief Adjust mouse report by any optional common pointing configuration defines
  226. *
  227. * This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines.
  228. *
  229. * @param mouse_report[in] takes a report_mouse_t to be adjusted
  230. * @return report_mouse_t with adjusted values
  231. */
  232. report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report) {
  233. // Support rotation of the sensor data
  234. #if defined(POINTING_DEVICE_ROTATION_90) || defined(POINTING_DEVICE_ROTATION_180) || defined(POINTING_DEVICE_ROTATION_270)
  235. mouse_xy_report_t x = mouse_report.x;
  236. mouse_xy_report_t y = mouse_report.y;
  237. # if defined(POINTING_DEVICE_ROTATION_90)
  238. mouse_report.x = y;
  239. mouse_report.y = -x;
  240. # elif defined(POINTING_DEVICE_ROTATION_180)
  241. mouse_report.x = -x;
  242. mouse_report.y = -y;
  243. # elif defined(POINTING_DEVICE_ROTATION_270)
  244. mouse_report.x = -y;
  245. mouse_report.y = x;
  246. # else
  247. # error "How the heck did you get here?!"
  248. # endif
  249. #endif
  250. // Support Inverting the X and Y Axises
  251. #if defined(POINTING_DEVICE_INVERT_X)
  252. mouse_report.x = -mouse_report.x;
  253. #endif
  254. #if defined(POINTING_DEVICE_INVERT_Y)
  255. mouse_report.y = -mouse_report.y;
  256. #endif
  257. return mouse_report;
  258. }
  259. /**
  260. * @brief Retrieves and processes pointing device data.
  261. *
  262. * This function is part of the keyboard loop and retrieves the mouse report from the pointing device driver.
  263. * It applies any optional configuration e.g. rotation or axis inversion and then initiates a send.
  264. *
  265. */
  266. __attribute__((weak)) bool pointing_device_task(void) {
  267. #if defined(SPLIT_POINTING_ENABLE)
  268. // Don't poll the target side pointing device.
  269. if (!is_keyboard_master()) {
  270. return false;
  271. };
  272. #endif
  273. #if (POINTING_DEVICE_TASK_THROTTLE_MS > 0)
  274. static uint32_t last_exec = 0;
  275. if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) {
  276. return false;
  277. }
  278. last_exec = timer_read32();
  279. #endif
  280. if (pointing_device_get_status() != POINTING_DEVICE_STATUS_SUCCESS) {
  281. return false;
  282. }
  283. // Gather report info
  284. #ifdef POINTING_DEVICE_MOTION_PIN
  285. # if defined(SPLIT_POINTING_ENABLE)
  286. # error POINTING_DEVICE_MOTION_PIN not supported when sharing the pointing device report between sides.
  287. # endif
  288. # ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW
  289. if (!gpio_read_pin(POINTING_DEVICE_MOTION_PIN))
  290. # else
  291. if (gpio_read_pin(POINTING_DEVICE_MOTION_PIN))
  292. # endif
  293. {
  294. #endif
  295. #if defined(SPLIT_POINTING_ENABLE)
  296. # if defined(POINTING_DEVICE_COMBINED)
  297. static uint8_t old_buttons = 0;
  298. local_mouse_report.buttons = old_buttons;
  299. local_mouse_report = pointing_device_driver->get_report(local_mouse_report);
  300. old_buttons = local_mouse_report.buttons;
  301. # elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
  302. local_mouse_report = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver->get_report(local_mouse_report) : shared_mouse_report;
  303. # else
  304. # error "You need to define the side(s) the pointing device is on. POINTING_DEVICE_COMBINED / POINTING_DEVICE_LEFT / POINTING_DEVICE_RIGHT"
  305. # endif
  306. #else
  307. local_mouse_report = pointing_device_driver->get_report(local_mouse_report);
  308. #endif // defined(SPLIT_POINTING_ENABLE)
  309. #ifdef POINTING_DEVICE_MOTION_PIN
  310. }
  311. #endif
  312. // allow kb to intercept and modify report
  313. #if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)
  314. if (is_keyboard_left()) {
  315. local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report);
  316. shared_mouse_report = pointing_device_adjust_by_defines_right(shared_mouse_report);
  317. } else {
  318. local_mouse_report = pointing_device_adjust_by_defines_right(local_mouse_report);
  319. shared_mouse_report = pointing_device_adjust_by_defines(shared_mouse_report);
  320. }
  321. local_mouse_report = is_keyboard_left() ? pointing_device_task_combined_kb(local_mouse_report, shared_mouse_report) : pointing_device_task_combined_kb(shared_mouse_report, local_mouse_report);
  322. #else
  323. local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report);
  324. #endif
  325. local_mouse_report = pointing_device_task_modules(local_mouse_report);
  326. local_mouse_report = pointing_device_task_kb(local_mouse_report);
  327. // automatic mouse layer function
  328. #ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
  329. pointing_device_task_auto_mouse(local_mouse_report);
  330. #endif
  331. // combine with mouse report to ensure that the combined is sent correctly
  332. #ifdef MOUSEKEY_ENABLE
  333. report_mouse_t mousekey_report = mousekey_get_report();
  334. local_mouse_report.buttons = local_mouse_report.buttons | mousekey_report.buttons;
  335. #endif
  336. const bool send_report = pointing_device_send() || pointing_device_force_send;
  337. pointing_device_force_send = false;
  338. return send_report;
  339. }
  340. /**
  341. * @brief Gets current mouse report used by pointing device task
  342. *
  343. * @return report_mouse_t
  344. */
  345. report_mouse_t pointing_device_get_report(void) {
  346. return local_mouse_report;
  347. }
  348. /**
  349. * @brief Sets mouse report used be pointing device task
  350. *
  351. * @param[in] mouse_report
  352. */
  353. void pointing_device_set_report(report_mouse_t mouse_report) {
  354. pointing_device_force_send = has_mouse_report_changed(&local_mouse_report, &mouse_report);
  355. memcpy(&local_mouse_report, &mouse_report, sizeof(local_mouse_report));
  356. }
  357. /**
  358. * @brief Gets current pointing device CPI if supported
  359. *
  360. * Gets current cpi from pointing device driver if supported and returns it as uint16_t
  361. *
  362. * @return cpi value as uint16_t
  363. */
  364. uint16_t pointing_device_get_cpi(void) {
  365. #if defined(SPLIT_POINTING_ENABLE)
  366. return POINTING_DEVICE_THIS_SIDE ? pointing_device_driver->get_cpi() : shared_cpi;
  367. #else
  368. return pointing_device_driver->get_cpi();
  369. #endif
  370. }
  371. /**
  372. * @brief Set pointing device CPI if supported
  373. *
  374. * Takes a uint16_t value to set pointing device cpi if supported by driver.
  375. *
  376. * @param[in] cpi uint16_t value.
  377. */
  378. void pointing_device_set_cpi(uint16_t cpi) {
  379. #if defined(SPLIT_POINTING_ENABLE)
  380. if (POINTING_DEVICE_THIS_SIDE) {
  381. pointing_device_driver->set_cpi(cpi);
  382. } else {
  383. shared_cpi = cpi;
  384. }
  385. #else
  386. pointing_device_driver->set_cpi(cpi);
  387. #endif
  388. }
  389. #if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)
  390. /**
  391. * @brief Set pointing device CPI if supported
  392. *
  393. * Takes a bool and uint16_t and allows setting cpi for a single side when using 2 pointing devices with a split keyboard.
  394. *
  395. * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
  396. *
  397. * @param[in] left true = left, false = right.
  398. * @param[in] cpi uint16_t value.
  399. */
  400. void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) {
  401. bool local = (is_keyboard_left() == left);
  402. if (local) {
  403. pointing_device_driver->set_cpi(cpi);
  404. } else {
  405. shared_cpi = cpi;
  406. }
  407. }
  408. /**
  409. * @brief clamps int16_t to int8_t, or int32_t to int16_t
  410. *
  411. * @param[in] hv_clamp_range_t value
  412. * @return mouse_hv_report_t clamped value
  413. */
  414. static inline mouse_hv_report_t pointing_device_hv_clamp(hv_clamp_range_t value) {
  415. if (value < MOUSE_REPORT_HV_MIN) {
  416. return MOUSE_REPORT_HV_MIN;
  417. } else if (value > MOUSE_REPORT_HV_MAX) {
  418. return MOUSE_REPORT_HV_MAX;
  419. } else {
  420. return value;
  421. }
  422. }
  423. /**
  424. * @brief clamps int16_t to int8_t, or int32_t to int16_t
  425. *
  426. * @param[in] xy_clamp_range_t value
  427. * @return mouse_xy_report_t clamped value
  428. */
  429. static inline mouse_xy_report_t pointing_device_xy_clamp(xy_clamp_range_t value) {
  430. if (value < MOUSE_REPORT_XY_MIN) {
  431. return MOUSE_REPORT_XY_MIN;
  432. } else if (value > MOUSE_REPORT_XY_MAX) {
  433. return MOUSE_REPORT_XY_MAX;
  434. } else {
  435. return value;
  436. }
  437. }
  438. /**
  439. * @brief combines 2 mouse reports and returns 2
  440. *
  441. * Combines 2 report_mouse_t structs, clamping movement values to int8_t and ignores report_id then returns the resulting report_mouse_t struct.
  442. *
  443. * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
  444. *
  445. * @param[in] left_report left report_mouse_t
  446. * @param[in] right_report right report_mouse_t
  447. * @return combined report_mouse_t of left_report and right_report
  448. */
  449. report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report) {
  450. left_report.x = pointing_device_xy_clamp((xy_clamp_range_t)left_report.x + right_report.x);
  451. left_report.y = pointing_device_xy_clamp((xy_clamp_range_t)left_report.y + right_report.y);
  452. left_report.h = pointing_device_hv_clamp((hv_clamp_range_t)left_report.h + right_report.h);
  453. left_report.v = pointing_device_hv_clamp((hv_clamp_range_t)left_report.v + right_report.v);
  454. left_report.buttons |= right_report.buttons;
  455. return left_report;
  456. }
  457. /**
  458. * @brief Adjust mouse report by any optional right pointing configuration defines
  459. *
  460. * This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines.
  461. *
  462. * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
  463. *
  464. * @param[in] mouse_report report_mouse_t to be adjusted
  465. * @return report_mouse_t with adjusted values
  466. */
  467. report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report) {
  468. // Support rotation of the sensor data
  469. # if defined(POINTING_DEVICE_ROTATION_90_RIGHT) || defined(POINTING_DEVICE_ROTATION_180_RIGHT) || defined(POINTING_DEVICE_ROTATION_270_RIGHT)
  470. mouse_xy_report_t x = mouse_report.x;
  471. mouse_xy_report_t y = mouse_report.y;
  472. # if defined(POINTING_DEVICE_ROTATION_90_RIGHT)
  473. mouse_report.x = y;
  474. mouse_report.y = -x;
  475. # elif defined(POINTING_DEVICE_ROTATION_180_RIGHT)
  476. mouse_report.x = -x;
  477. mouse_report.y = -y;
  478. # elif defined(POINTING_DEVICE_ROTATION_270_RIGHT)
  479. mouse_report.x = -y;
  480. mouse_report.y = x;
  481. # else
  482. # error "How the heck did you get here?!"
  483. # endif
  484. # endif
  485. // Support Inverting the X and Y Axises
  486. # if defined(POINTING_DEVICE_INVERT_X_RIGHT)
  487. mouse_report.x = -mouse_report.x;
  488. # endif
  489. # if defined(POINTING_DEVICE_INVERT_Y_RIGHT)
  490. mouse_report.y = -mouse_report.y;
  491. # endif
  492. return mouse_report;
  493. }
  494. /**
  495. * @brief Weak function allowing for keyboard level mouse report modification
  496. *
  497. * Takes 2 report_mouse_t structs allowing individual modification of sides at keyboard level then returns pointing_device_task_combined_user.
  498. *
  499. * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
  500. *
  501. * @param[in] left_report report_mouse_t
  502. * @param[in] right_report report_mouse_t
  503. * @return pointing_device_task_combined_user(left_report, right_report) by default
  504. */
  505. __attribute__((weak)) report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report) {
  506. return pointing_device_task_combined_user(left_report, right_report);
  507. }
  508. /**
  509. * @brief Weak function allowing for user level mouse report modification
  510. *
  511. * Takes 2 report_mouse_t structs allowing individual modification of sides at user level then returns pointing_device_combine_reports.
  512. *
  513. * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
  514. *
  515. * @param[in] left_report report_mouse_t
  516. * @param[in] right_report report_mouse_t
  517. * @return pointing_device_combine_reports(left_report, right_report) by default
  518. */
  519. __attribute__((weak)) report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) {
  520. return pointing_device_combine_reports(left_report, right_report);
  521. }
  522. #endif
  523. __attribute__((weak)) void pointing_device_keycode_handler(uint16_t keycode, bool pressed) {
  524. if IS_MOUSEKEY_BUTTON (keycode) {
  525. local_mouse_report.buttons = pointing_device_handle_buttons(local_mouse_report.buttons, pressed, keycode - QK_MOUSE_BUTTON_1);
  526. pointing_device_send();
  527. }
  528. }
  529. #ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
  530. uint16_t pointing_device_get_hires_scroll_resolution(void) {
  531. return hires_scroll_resolution;
  532. }
  533. #endif