You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.3 KiB

  1. // Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "pointing.h"
  4. static uint16_t mouse_timer = 0;
  5. static uint16_t mouse_debounce_timer = 0;
  6. static uint8_t mouse_keycode_tracker = 0;
  7. bool tap_toggling = false, enable_acceleration = false;
  8. #ifdef TAPPING_TERM_PER_KEY
  9. # define TAP_CHECK get_tapping_term(KC_BTN1, NULL)
  10. #else
  11. # ifndef TAPPING_TERM
  12. # define TAPPING_TERM 200
  13. # endif
  14. # define TAP_CHECK TAPPING_TERM
  15. #endif
  16. __attribute__((weak)) report_mouse_t pointing_device_task_keymap(report_mouse_t mouse_report) {
  17. return mouse_report;
  18. }
  19. report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
  20. int8_t x = mouse_report.x, y = mouse_report.y;
  21. mouse_report.x = 0;
  22. mouse_report.y = 0;
  23. if (x != 0 && y != 0) {
  24. mouse_timer = timer_read();
  25. #ifdef OLED_ENABLE
  26. oled_timer_reset();
  27. #endif
  28. if (timer_elapsed(mouse_debounce_timer) > TAP_CHECK) {
  29. if (enable_acceleration) {
  30. x = (x > 0 ? x * x / 16 + x : -x * x / 16 + x);
  31. y = (y > 0 ? y * y / 16 + y : -y * y / 16 + y);
  32. }
  33. mouse_report.x = x;
  34. mouse_report.y = y;
  35. if (!layer_state_is(_MOUSE)) {
  36. layer_on(_MOUSE);
  37. }
  38. }
  39. } else if (timer_elapsed(mouse_timer) > 650 && layer_state_is(_MOUSE) && !mouse_keycode_tracker && !tap_toggling) {
  40. layer_off(_MOUSE);
  41. } else if (tap_toggling) {
  42. if (!layer_state_is(_MOUSE)) {
  43. layer_on(_MOUSE);
  44. }
  45. }
  46. return pointing_device_task_keymap(mouse_report);
  47. }
  48. bool process_record_pointing(uint16_t keycode, keyrecord_t* record) {
  49. switch (keycode) {
  50. case TT(_MOUSE):
  51. if (record->event.pressed) {
  52. mouse_keycode_tracker++;
  53. } else {
  54. #if TAPPING_TOGGLE != 0
  55. if (record->tap.count == TAPPING_TOGGLE) {
  56. tap_toggling ^= 1;
  57. # if TAPPING_TOGGLE == 1
  58. if (!tap_toggling) mouse_keycode_tracker -= record->tap.count + 1;
  59. # else
  60. if (!tap_toggling) mouse_keycode_tracker -= record->tap.count;
  61. # endif
  62. } else {
  63. mouse_keycode_tracker--;
  64. }
  65. #endif
  66. }
  67. mouse_timer = timer_read();
  68. break;
  69. case TG(_MOUSE):
  70. if (record->event.pressed) {
  71. tap_toggling ^= 1;
  72. }
  73. break;
  74. case MO(_MOUSE):
  75. #if defined(KEYBOARD_ploopy)
  76. case DPI_CONFIG:
  77. #elif (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && !defined(NO_CHARYBDIS_KEYCODES)
  78. case SAFE_RANGE ... (CHARYBDIS_SAFE_RANGE-1):
  79. #endif
  80. case KC_MS_UP ... KC_MS_WH_RIGHT:
  81. record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
  82. mouse_timer = timer_read();
  83. break;
  84. case KC_ACCEL:
  85. enable_acceleration = record->event.pressed;
  86. record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
  87. mouse_timer = timer_read();
  88. break;
  89. #if 0
  90. case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
  91. break;
  92. #endif
  93. case QK_MOD_TAP ... QK_MOD_TAP_MAX:
  94. if (record->event.pressed || !record->tap.count) {
  95. break;
  96. }
  97. default:
  98. if (IS_NOEVENT(record->event)) break;
  99. if ((keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) && (((keycode >> 0x8) & 0xF) == _MOUSE)) {
  100. record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
  101. mouse_timer = timer_read();
  102. break;
  103. }
  104. if (layer_state_is(_MOUSE) && !mouse_keycode_tracker && !tap_toggling) {
  105. layer_off(_MOUSE);
  106. }
  107. mouse_keycode_tracker = 0;
  108. mouse_debounce_timer = timer_read();
  109. break;
  110. }
  111. return true;
  112. }
  113. layer_state_t layer_state_set_pointing(layer_state_t state) {
  114. if (layer_state_cmp(state, _GAMEPAD) || layer_state_cmp(state, _DIABLO) || layer_state_cmp(state, _DIABLOII)) {
  115. state |= ((layer_state_t)1 << _MOUSE);
  116. }
  117. return state;
  118. }