/* Copyright 2023 Alabastard (@Alabastard-64) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include "quantum.h" #include "pointing_device.h" // default settings #ifndef POINTING_TAP_DELAY # define POINTING_TAP_DELAY TAP_CODE_DELAY #endif #ifndef POINTING_MODE_DEFAULT # define POINTING_MODE_DEFAULT PM_NONE #endif #if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) # ifndef POINTING_MODES_NUM_DEVICES # define POINTING_MODES_NUM_DEVICES 2 # endif #else # ifndef POINTING_MODES_NUM_DEVICES # define POINTING_MODES_NUM_DEVICES 1 # endif #endif #ifdef POINTING_MODES_SINGLE_CONTROL # define POINTING_MODES_DEVICE_CONTROL_COUNT 1 #else # define POINTING_MODES_DEVICE_CONTROL_COUNT POINTING_MODES_NUM_DEVICES #endif #ifndef POINTING_MODES_DEFAULT_DEVICE # define POINTING_MODES_DEFAULT_DEVICE 0 #endif #ifdef POINTING_NUM_DIRECTIONS # undefine POINTING_NUM_DIRECTIONS #endif #define POINTING_NUM_DIRECTIONS 4 // default divisors #ifndef POINTING_DEFAULT_DIVISOR # define POINTING_DEFAULT_DIVISOR 64 #endif #ifndef POINTING_HISTORY_DIVISOR # define POINTING_HISTORY_DIVISOR 64 #endif #ifndef POINTING_VOLUME_DIVISOR # define POINTING_VOLUME_DIVISOR 64 #endif #ifndef POINTING_CARET_DIVISOR # define POINTING_CARET_DIVISOR 32 #endif #ifndef POINTING_CARET_DIVISOR_H # define POINTING_CARET_DIVISOR_H POINTING_CARET_DIVISOR #endif #ifndef POINTING_CARET_DIVISOR_V # define POINTING_CARET_DIVISOR_V POINTING_CARET_DIVISOR #endif #ifndef POINTING_PRECISION_DIVISOR # define POINTING_PRECISION_DIVISOR 2 #endif #ifndef POINTING_DRAG_DIVISOR # define POINTING_DRAG_DIVISOR 4 #endif // error checking #if POINTING_DEFAULT_DIVISOR < 1 # pragma message "DEFAULT_DIVISOR must be 1 or greater" # error DEFAULT_DIVISOR less than 1 #endif #if POINTING_MODES_NUM_DEVICES < 2 && ((defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)) || defined(POINTING_MODES_SINGLE_CONTROL)) # pragma message "POINTING_MODE_NUM_DEVICES should be at least 2 with SPLIT_POINTING_ENABLE & POINTING_DEVICE_COMBINED or POINTING_MODES_SINGLE_CONTROL defined" # error POINTING_MODE_NUM_DEVICES set too low #endif /* enums */ enum pointing_device_directions { PD_DOWN = 0, // default value PD_UP = 1, PD_LEFT = 2, PD_RIGHT = 3 }; enum pointing_devide_mode_devices { #ifdef MASTER_RIGHT PM_RIGHT_DEVICE = 0, PM_LEFT_DEVICE #else PM_LEFT_DEVICE = 0, PM_RIGHT_DEVICE #endif }; /* local data structures */ typedef struct { uint8_t id; int16_t x; int16_t y; } pointing_mode_t; /* ----------Controlling pointing device modes-------------------------------------------------------------------- */ void set_pointing_mode_id(uint8_t mode_id); // set current pointing_mode.id to mode_id void toggle_pointing_mode_id(uint8_t mode_id); // toggle pointing mode uint8_t get_pointing_mode_id(void); // return current pointing_mode.id uint8_t get_toggled_pointing_mode_id(void); // return current tg_mode_id void pointing_mode_reset(void); // reset pointing mode to current toggle mode /* ----------Controlling pointing device data conversion---------------------------------------------------------- */ report_mouse_t pointing_modes_axes_conv(pointing_mode_t pointing_mode, report_mouse_t mouse_report); // converts x & y axes to local h & v /* ----------Crontrolling pointing mode data---------------------------------------------------------------------- */ void set_pointing_mode(pointing_mode_t pointing_mode); // overwrite local pointing_mode status void pointing_mode_update(void); // update direction & divisor from current mode id, x, y mouse_xy_report_t apply_divisor_xy(int16_t value); // divide value by current divisor and clamp to x/y range int8_t apply_divisor_hv(int16_t value); // divide value by current divisor and clamps to h/v range int16_t multiply_divisor_xy(mouse_xy_report_t value); // multiply mouse x/y value by current divisor int16_t multiply_divisor_hv(int8_t value); // multiply mousen h/v value by current divisor void pointing_mode_divisor_override(uint8_t divisor); // override current divisor uint8_t current_pointing_mode_divisor(void); // return current divisor uint8_t current_pointing_mode_direction(void); // return current direction /* ----------For Custom modes without maps---------------------------------------------------------------------- */ void pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint16_t kc_right); // pointing_mode x/y to keycode taps /* ----------Callbacks for modifying and adding pointing modes---------------------------------------------------- */ bool process_pointing_mode_kb(pointing_mode_t pointing_mode, report_mouse_t* mouse_report); // keyboard level bool process_pointing_mode_user(pointing_mode_t pointing_mode, report_mouse_t* mouse_report); // user/keymap level /* ----------Callbacks for adding/modifying pointing device mode divisors----------------------------------------- */ uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint8_t direction); // adding new divisors at keyboard level uint8_t get_pointing_mode_divisor_user(uint8_t mode_id, uint8_t direction); // adding new divisors at user/keymap level bool pointing_mode_divisor_postprocess_kb(uint8_t* divisor); // keyboard level modifying of divisors after get_pointing_mode_divisor_* stack bool pointing_mode_divisor_postprocess_user(uint8_t* divisor); // user/keymap level modifying of divisors after get_pointing_mode_divisor_* stack /* ----------Core functions (only used in custom pointing devices or key processing)------------------------------ */ report_mouse_t pointing_device_modes_task(report_mouse_t mouse_report); // intercepts mouse_report (in pointing_device_task_* stack) /* ----------Pointing Device mode Mapping------------------------------------------------------------------------- */ #ifdef POINTING_MODE_MAP_ENABLE # define POINTING_MODE_LAYOUT(Y_POS, X_NEG, X_POS, Y_NEG) \ { Y_NEG, Y_POS, X_NEG, X_POS } # ifndef POINTING_MODE_MAP_START # define POINTING_MODE_MAP_START PM_SAFE_RANGE # endif extern const uint16_t PROGMEM pointing_mode_maps[][POINTING_NUM_DIRECTIONS]; #endif // POINTING_MODE_MAP_ENABLE /* ----------For multiple pointing devices------------------------------------------------------------------------ */ uint8_t get_pointing_mode_device(void); // get current active device for pointing modes void set_pointing_mode_device(uint8_t device); // set current active pointing mode side (PM_LEFT_SIDE, PM_RIGHT_SIDE, etc.)