qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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 }