pointing.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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 = timer_read32();
  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. case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
  90. break;
  91. case QK_MOD_TAP ... QK_MOD_TAP_MAX:
  92. if (record->event.pressed || !record->tap.count) {
  93. break;
  94. }
  95. default:
  96. if (IS_NOEVENT(record->event)) break;
  97. if ((keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) && (((keycode >> 0x8) & 0xF) == _MOUSE)) {
  98. record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
  99. mouse_timer = timer_read();
  100. break;
  101. }
  102. if (layer_state_is(_MOUSE) && !mouse_keycode_tracker && !tap_toggling) {
  103. layer_off(_MOUSE);
  104. }
  105. mouse_keycode_tracker = 0;
  106. mouse_debounce_timer = timer_read();
  107. break;
  108. }
  109. return true;
  110. }
  111. layer_state_t layer_state_set_pointing(layer_state_t state) {
  112. if (layer_state_cmp(state, _GAMEPAD) || layer_state_cmp(state, _DIABLO) || layer_state_cmp(state, _DIABLOII)) {
  113. state |= ((layer_state_t)1 << _MOUSE);
  114. }
  115. return state;
  116. }