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.

243 lines
8.2 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. /* Copyright 2020 Christopher Courtney <drashna@live.com> (@drashna)
  2. * Copyright 2021 Quentin LEBASTARD <qlebastard@gmail.com>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Publicw License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "charybdis.h"
  18. #include "drivers/sensors/pmw3360.h"
  19. #ifndef CHARYBDIS_DPI_OPTIONS
  20. # define CHARYBDIS_DPI_OPTIONS \
  21. { 600, 800, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800 }
  22. #endif
  23. #ifndef CHARYBDIS_DPI_DEFAULT
  24. # define CHARYBDIS_DPI_DEFAULT 0
  25. #endif
  26. #ifndef CHARYBDIS_SNIPER_OPTIONS
  27. #define CHARYBDIS_SNIPER_OPTIONS \
  28. { 100, 200, 300, 400 }
  29. #endif
  30. #ifndef CHARYBDIS_SNIPER_DEFAULT
  31. # define CHARYBDIS_SNIPER_DEFAULT 0
  32. #endif
  33. #ifndef CHARYBDIS_AUTO_SNIPER_LAYER
  34. # define CHARYBDIS_AUTO_SNIPER_LAYER 4
  35. #endif
  36. #ifndef CHARYBDIS_DRAGSCROLL_DPI
  37. # define CHARYBDIS_DRAGSCROLL_DPI 100 // Fixed-DPI Drag Scroll
  38. #endif
  39. #ifndef CHARYBDIS_DRAGSCROLL_MULTIPLIER
  40. # define CHARYBDIS_DRAGSCROLL_MULTIPLIER 0.2 // Variable-DPI Drag Scroll
  41. #endif
  42. #ifndef CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X
  43. # define CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X 30
  44. #endif
  45. #ifndef CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y
  46. # define CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y 12
  47. #endif
  48. keyboard_config_t keyboard_config;
  49. uint16_t dpi_array[] = CHARYBDIS_DPI_OPTIONS;
  50. #define DPI_OPTION_SIZE (sizeof(dpi_array) / sizeof(uint16_t))
  51. uint16_t sniper_array[] = CHARYBDIS_SNIPER_OPTIONS;
  52. #define SNIPER_OPTION_SIZE (sizeof(sniper_array) / sizeof(uint16_t))
  53. bool is_drag_scroll = false;
  54. bool is_sniper_on = false;
  55. scroll_inertia_t scroll_inertia; // Scroll value storage to make scrolling slower
  56. keyboard_config_t keyboard_config;
  57. __attribute__((weak)) void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y) {
  58. mouse_report->x = x;
  59. mouse_report->y = y;
  60. }
  61. __attribute__((weak)) void process_mouse(report_mouse_t* mouse_report) {
  62. report_pmw_t data = pmw_read_burst();
  63. if (data.isOnSurface && data.isMotion) {
  64. // Wrap to HID size
  65. data.dx = constrain(data.dx, -127, 127);
  66. data.dy = constrain(data.dy, -127, 127);
  67. process_mouse_user(mouse_report, -data.dx, data.dy);
  68. }
  69. }
  70. void trigger_sniper(void){
  71. if (is_sniper_on) {
  72. pmw_set_cpi(sniper_array[keyboard_config.sniper_config]);
  73. } else {
  74. pmw_set_cpi(dpi_array[keyboard_config.dpi_config]);
  75. }
  76. }
  77. // on layer change, no matter where the change was initiated
  78. // Then runs keymap's layer change check
  79. layer_state_t layer_state_set_kb(layer_state_t state) {
  80. state = layer_state_set_user(state);
  81. if (layer_state_cmp(state, CHARYBDIS_AUTO_SNIPER_LAYER) != is_sniper_on) {
  82. is_sniper_on ^= 1;
  83. trigger_sniper();
  84. }
  85. return state;
  86. }
  87. bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
  88. if (!process_record_user(keycode, record)) { return false; }
  89. switch(keycode){
  90. case SNIPER_CONFIG:
  91. if(record->event.pressed){
  92. if ((get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT) {
  93. keyboard_config.sniper_config = keyboard_config.sniper_config - 1;
  94. } else {
  95. keyboard_config.sniper_config = keyboard_config.sniper_config + 1;
  96. }
  97. keyboard_config.sniper_config = constrain(keyboard_config.sniper_config, 0, SNIPER_OPTION_SIZE - 1);
  98. eeconfig_update_kb(keyboard_config.raw);
  99. trigger_sniper();
  100. }
  101. break;
  102. case DPI_CONFIG:
  103. if(record->event.pressed){
  104. if ((get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT) {
  105. keyboard_config.dpi_config = keyboard_config.dpi_config - 1;
  106. } else {
  107. keyboard_config.dpi_config = keyboard_config.dpi_config + 1;
  108. }
  109. keyboard_config.dpi_config = constrain(keyboard_config.dpi_config, 0, DPI_OPTION_SIZE - 1);
  110. eeconfig_update_kb(keyboard_config.raw);
  111. pmw_set_cpi(dpi_array[keyboard_config.dpi_config]);
  112. }
  113. break;
  114. case SNIPING:
  115. is_sniper_on ^= 1;
  116. trigger_sniper();
  117. break;
  118. case DRAG_SCROLL:
  119. #ifdef CHARYBDIS_DRAGSCROLL_TOGGLE
  120. if (record->event.pressed)
  121. #endif
  122. {
  123. is_drag_scroll ^= 1;
  124. }
  125. #ifndef CHARYBDIS_DRAGSCROLL_VARIABLE
  126. pmw_set_cpi(is_drag_scroll ? CHARYBDIS_DRAGSCROLL_DPI : dpi_array[keyboard_config.dpi_config]);
  127. #else
  128. pmw_set_cpi(is_drag_scroll ? (dpi_array[keyboard_config.dpi_config] * CHARYBDIS_DRAGSCROLL_MULTIPLIER) : dpi_array[keyboard_config.dpi_config]);
  129. #endif
  130. break;
  131. }
  132. /* If Mousekeys is disabled, then use handle the mouse button
  133. * keycodes. This makes things simpler, and allows usage of
  134. * the keycodes in a consistent manner. But only do this if
  135. * Mousekeys is not enable, so it's not handled twice.
  136. */
  137. #ifndef MOUSEKEY_ENABLE
  138. if (IS_MOUSEKEY_BUTTON(keycode)) {
  139. report_mouse_t currentReport = pointing_device_get_report();
  140. if (record->event.pressed) {
  141. currentReport.buttons |= 1 << (keycode - KC_MS_BTN1);
  142. } else {
  143. currentReport.buttons &= ~(1 << (keycode - KC_MS_BTN1));
  144. }
  145. pointing_device_set_report(currentReport);
  146. pointing_device_send();
  147. }
  148. #endif
  149. return true;
  150. }
  151. // Hardware Setup
  152. void keyboard_pre_init_kb(void) {
  153. scroll_inertia.x = 0;
  154. scroll_inertia.y = 0;
  155. keyboard_pre_init_user();
  156. }
  157. void pointing_device_init(void) {
  158. pmw_spi_init();
  159. pmw_set_cpi(dpi_array[keyboard_config.dpi_config]);
  160. }
  161. void pointing_device_task(void) {
  162. report_mouse_t mouse_report = pointing_device_get_report();
  163. process_mouse(&mouse_report);
  164. if (is_drag_scroll) {
  165. #ifdef CHARYBDIS_DRAGSCROLL_INVERT_X
  166. scroll_inertia.x -= mouse_report.x;
  167. #else
  168. scroll_inertia.x += mouse_report.x;
  169. #endif
  170. #ifdef CHARYBDIS_DRAGSCROLL_INVERT_Y
  171. // Invert vertical scroll direction
  172. scroll_inertia.y -= mouse_report.y;
  173. #else
  174. scroll_inertia.y += mouse_report.y;
  175. #endif
  176. // we only want to trigger scrolling once in 12 scrolls, for slower scroll
  177. if(scroll_inertia.y > CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y || scroll_inertia.y < -CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y){
  178. mouse_report.v = constrain(scroll_inertia.y / CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y * 2,
  179. -CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y/2, CHARYBDIS_TRACKBALL_SPEED_DIVIDER_Y/2);
  180. scroll_inertia.y = 0;
  181. }
  182. if(scroll_inertia.x > CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X || scroll_inertia.x < -CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X){
  183. mouse_report.h = constrain(scroll_inertia.x / CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X * 2,
  184. -CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X/2, CHARYBDIS_TRACKBALL_SPEED_DIVIDER_X/2);
  185. scroll_inertia.x = 0;
  186. }
  187. mouse_report.x = 0;
  188. mouse_report.y = 0;
  189. }
  190. pointing_device_set_report(mouse_report);
  191. pointing_device_send();
  192. }
  193. void eeconfig_init_kb(void) {
  194. keyboard_config.raw = 0;
  195. keyboard_config.dpi_config = CHARYBDIS_DPI_DEFAULT;
  196. keyboard_config.sniper_config = CHARYBDIS_SNIPER_DEFAULT;
  197. pmw_set_cpi(dpi_array[keyboard_config.dpi_config]);
  198. eeconfig_update_kb(keyboard_config.raw);
  199. eeconfig_init_user();
  200. }
  201. void matrix_init_kb(void) {
  202. // is safe to just read DPI setting since matrix init
  203. // comes before pointing device init.
  204. keyboard_config.raw = eeconfig_read_kb();
  205. if (keyboard_config.dpi_config >= DPI_OPTION_SIZE ||
  206. keyboard_config.sniper_config >= SNIPER_OPTION_SIZE) {
  207. eeconfig_init_kb();
  208. }
  209. matrix_init_user();
  210. }