oddball.c (3863B)
1 /* Copyright 2020 Alexander Tulloh 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "oddball.h" 18 #include "pointing_device.h" 19 extern const pointing_device_driver_t pointing_device_driver; 20 21 static bool scroll_pressed; 22 static bool mouse_buttons_dirty; 23 static int8_t scroll_h; 24 static int8_t scroll_v; 25 26 void pointing_device_init_kb(void){ 27 if(!is_keyboard_master()) 28 return; 29 30 // read config from EEPROM and update if needed 31 32 config_oddball_t kb_config; 33 kb_config.raw = eeconfig_read_kb(); 34 35 if(!kb_config.cpi) { 36 kb_config.cpi = CPI_2; 37 eeconfig_update_kb(kb_config.raw); 38 } 39 40 pointing_device_set_cpi(kb_config.cpi); 41 } 42 43 report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { 44 if (!is_keyboard_master()) return mouse_report; 45 46 int8_t clamped_x = mouse_report.x, clamped_y = mouse_report.y; 47 mouse_report.x = 0; 48 mouse_report.y = 0; 49 50 if (scroll_pressed) { 51 // accumulate scroll 52 scroll_h += clamped_x; 53 scroll_v += clamped_y; 54 55 int8_t scaled_scroll_h = scroll_h / SCROLL_DIVIDER; 56 int8_t scaled_scroll_v = scroll_v / SCROLL_DIVIDER; 57 58 // clear accumulated scroll on assignment 59 60 if (scaled_scroll_h != 0) { 61 mouse_report.h = -scaled_scroll_h; 62 scroll_h = 0; 63 } 64 65 if (scaled_scroll_v != 0) { 66 mouse_report.v = -scaled_scroll_v; 67 scroll_v = 0; 68 } 69 } else { 70 mouse_report.x = -clamped_x; 71 mouse_report.y = clamped_y; 72 } 73 74 return mouse_report; 75 } 76 77 static void on_cpi_button(uint16_t cpi, keyrecord_t *record) { 78 79 if(!record->event.pressed) 80 return; 81 82 pointing_device_set_cpi(cpi); 83 84 config_oddball_t kb_config; 85 kb_config.cpi = cpi; 86 eeconfig_update_kb(kb_config.raw); 87 } 88 89 static void on_mouse_button(uint8_t mouse_button, keyrecord_t *record) { 90 91 report_mouse_t report = pointing_device_get_report(); 92 93 if(record->event.pressed) 94 report.buttons |= mouse_button; 95 else 96 report.buttons &= ~mouse_button; 97 98 pointing_device_set_report(report); 99 mouse_buttons_dirty = true; 100 } 101 102 bool process_record_kb(uint16_t keycode, keyrecord_t *record) { 103 104 if(!process_record_user(keycode, record)) 105 return false; 106 107 // handle mouse drag and scroll 108 109 switch (keycode) { 110 case MS_BTN1: 111 on_mouse_button(MOUSE_BTN1, record); 112 return false; 113 114 case MS_BTN2: 115 on_mouse_button(MOUSE_BTN2, record); 116 return false; 117 118 case MS_BTN3: 119 on_mouse_button(MOUSE_BTN3, record); 120 return false; 121 122 case MS_BTN4: 123 on_mouse_button(MOUSE_BTN4, record); 124 return false; 125 126 case MS_BTN5: 127 on_mouse_button(MOUSE_BTN5, record); 128 return false; 129 130 case KC_SCROLL: 131 scroll_pressed = record->event.pressed; 132 return false; 133 134 case KC_CPI_1: 135 on_cpi_button(CPI_1, record); 136 return false; 137 138 case KC_CPI_2: 139 on_cpi_button(CPI_2, record); 140 return false; 141 142 case KC_CPI_3: 143 on_cpi_button(CPI_3, record); 144 return false; 145 146 default: 147 return true; 148 } 149 }