diff options
Diffstat (limited to 'quantum/pointing_device')
| -rw-r--r-- | quantum/pointing_device/pointing_device.c | 28 | ||||
| -rw-r--r-- | quantum/pointing_device/pointing_device.h | 11 | ||||
| -rw-r--r-- | quantum/pointing_device/pointing_device_auto_mouse.c | 384 | ||||
| -rw-r--r-- | quantum/pointing_device/pointing_device_auto_mouse.h | 87 | ||||
| -rw-r--r-- | quantum/pointing_device/pointing_device_drivers.c | 38 | 
5 files changed, 528 insertions, 20 deletions
diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c index 505a7a6ffd..75bb5f81fc 100644 --- a/quantum/pointing_device/pointing_device.c +++ b/quantum/pointing_device/pointing_device.c @@ -22,6 +22,7 @@  #ifdef MOUSEKEY_ENABLE  #    include "mousekey.h"  #endif +  #if (defined(POINTING_DEVICE_ROTATION_90) + defined(POINTING_DEVICE_ROTATION_180) + defined(POINTING_DEVICE_ROTATION_270)) > 1  #    error More than one rotation selected.  This is not supported.  #endif @@ -144,7 +145,11 @@ __attribute__((weak)) void pointing_device_init(void) {      {          pointing_device_driver.init();  #ifdef POINTING_DEVICE_MOTION_PIN +#    ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW          setPinInputHigh(POINTING_DEVICE_MOTION_PIN); +#    else +        setPinInput(POINTING_DEVICE_MOTION_PIN); +#    endif  #endif      } @@ -166,11 +171,9 @@ __attribute__((weak)) void pointing_device_send(void) {          host_mouse_send(&local_mouse_report);      }      // send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device -    local_mouse_report.x = 0; -    local_mouse_report.y = 0; -    local_mouse_report.v = 0; -    local_mouse_report.h = 0; - +    uint8_t buttons = local_mouse_report.buttons; +    memset(&local_mouse_report, 0, sizeof(local_mouse_report)); +    local_mouse_report.buttons = buttons;      memcpy(&old_report, &local_mouse_report, sizeof(local_mouse_report));  } @@ -238,7 +241,11 @@ __attribute__((weak)) void pointing_device_task(void) {  #    if defined(SPLIT_POINTING_ENABLE)  #        error POINTING_DEVICE_MOTION_PIN not supported when sharing the pointing device report between sides.  #    endif +#    ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW      if (!readPin(POINTING_DEVICE_MOTION_PIN)) +#    else +    if (readPin(POINTING_DEVICE_MOTION_PIN)) +#    endif  #endif  #if defined(SPLIT_POINTING_ENABLE) @@ -270,6 +277,10 @@ __attribute__((weak)) void pointing_device_task(void) {      local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report);      local_mouse_report = pointing_device_task_kb(local_mouse_report);  #endif +    // automatic mouse layer function +#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE +    pointing_device_task_auto_mouse(local_mouse_report); +#endif      // combine with mouse report to ensure that the combined is sent correctly  #ifdef MOUSEKEY_ENABLE      report_mouse_t mousekey_report = mousekey_get_report(); @@ -469,3 +480,10 @@ __attribute__((weak)) report_mouse_t pointing_device_task_combined_user(report_m      return pointing_device_combine_reports(left_report, right_report);  }  #endif + +__attribute__((weak)) void pointing_device_keycode_handler(uint16_t keycode, bool pressed) { +    if IS_MOUSEKEY_BUTTON (keycode) { +        local_mouse_report.buttons = pointing_device_handle_buttons(local_mouse_report.buttons, pressed, keycode - KC_MS_BTN1); +        pointing_device_send(); +    } +} diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h index 77db5471ea..d430e6cfa4 100644 --- a/quantum/pointing_device/pointing_device.h +++ b/quantum/pointing_device/pointing_device.h @@ -21,20 +21,28 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "host.h"  #include "report.h" +#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE +#    include "pointing_device_auto_mouse.h" +#endif +  #if defined(POINTING_DEVICE_DRIVER_adns5050)  #    include "drivers/sensors/adns5050.h" +#    define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW  #elif defined(POINTING_DEVICE_DRIVER_adns9800)  #    include "spi_master.h"  #    include "drivers/sensors/adns9800.h" +#    define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW  #elif defined(POINTING_DEVICE_DRIVER_analog_joystick)  #    include "analog.h"  #    include "drivers/sensors/analog_joystick.h" +#    define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW  #elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)  #    include "drivers/sensors/cirque_pinnacle.h"  #    include "drivers/sensors/cirque_pinnacle_gestures.h"  #    include "pointing_device_gestures.h"  #elif defined(POINTING_DEVICE_DRIVER_paw3204)  #    include "drivers/sensors/paw3204.h" +#    define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW  #elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)  #    include "i2c_master.h"  #    include "drivers/sensors/pimoroni_trackball.h" @@ -48,9 +56,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #    ifdef PIMORONI_TRACKBALL_ROTATE  #        define POINTING_DEVICE_ROTATION_90  #    endif +#    define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW  #elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389)  #    include "spi_master.h"  #    include "drivers/sensors/pmw33xx_common.h" +#    define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW  #else  void           pointing_device_driver_init(void);  report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report); @@ -100,6 +110,7 @@ report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report);  report_mouse_t pointing_device_task_user(report_mouse_t mouse_report);  uint8_t        pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button);  report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report); +void           pointing_device_keycode_handler(uint16_t keycode, bool pressed);  #if defined(SPLIT_POINTING_ENABLE)  void     pointing_device_set_shared_report(report_mouse_t report); diff --git a/quantum/pointing_device/pointing_device_auto_mouse.c b/quantum/pointing_device/pointing_device_auto_mouse.c new file mode 100644 index 0000000000..edffd44787 --- /dev/null +++ b/quantum/pointing_device/pointing_device_auto_mouse.c @@ -0,0 +1,384 @@ +/* Copyright 2021 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com> + * Copyright 2022 Alabastard + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE + +#    include "pointing_device_auto_mouse.h" + +/* local data structure for tracking auto mouse */ +static auto_mouse_context_t auto_mouse_context = {.config.layer = (uint8_t)AUTO_MOUSE_DEFAULT_LAYER}; + +/* local functions */ +static bool is_mouse_record(uint16_t keycode, keyrecord_t* record); +static void auto_mouse_reset(void); + +/* check for target layer deactivation overrides */ +static inline bool layer_hold_check(void) { +    return get_auto_mouse_toggle() || +#    ifndef NO_ACTION_ONESHOT +           get_oneshot_layer() == (AUTO_MOUSE_TARGET_LAYER) || +#    endif +           false; +} + +/* check all layer activation criteria */ +static inline bool is_auto_mouse_active(void) { +    return auto_mouse_context.status.is_activated || auto_mouse_context.status.mouse_key_tracker || layer_hold_check(); +} + +/** + * @brief Get auto mouse enable state + * + * Return is_enabled value + * + * @return bool true: auto mouse enabled false: auto mouse disabled + */ +bool get_auto_mouse_enable(void) { +    return auto_mouse_context.config.is_enabled; +} + +/** + * @brief get current target layer index + * + * NOTE: (AUTO_MOUSE_TARGET_LAYER) is an alias for this function + * + * @return uint8_t target layer index + */ +uint8_t get_auto_mouse_layer(void) { +    return auto_mouse_context.config.layer; +} + +/** + * @brief get layer_toggled value + * + * @return bool of current layer_toggled state + */ +bool get_auto_mouse_toggle(void) { +    return auto_mouse_context.status.is_toggled; +} + +/** + * @brief Reset auto mouse context + * + * Clear timers and status + * + * NOTE: this will set is_toggled to false so careful when using it + */ +static void auto_mouse_reset(void) { +    memset(&auto_mouse_context.status, 0, sizeof(auto_mouse_context.status)); +    memset(&auto_mouse_context.timer, 0, sizeof(auto_mouse_context.timer)); +} + +/** + * @brief Set auto mouse enable state + * + * Set local auto mouse enabled state + * + * @param[in] state bool + */ +void set_auto_mouse_enable(bool enable) { +    // skip if unchanged +    if (auto_mouse_context.config.is_enabled == enable) return; +    auto_mouse_context.config.is_enabled = enable; +    auto_mouse_reset(); +} + +/** + * @brief Change target layer for auto mouse + * + * Sets input as the new target layer if different from current and resets auto mouse + * + * NOTE: remove_auto_mouse_layer(state, false) or auto_mouse_layer_off should be called + *       before this function to avoid issues with layers getting stuck + * + * @param[in] layer uint8_t + */ +void set_auto_mouse_layer(uint8_t layer) { +    // skip if unchanged +    if (auto_mouse_context.config.layer == layer) return; +    auto_mouse_context.config.layer = layer; +    auto_mouse_reset(); +} + +/** + * @brief toggle mouse layer setting + * + * Change state of local layer_toggled bool meant to track when the mouse layer is toggled on by other means + * + * NOTE: While is_toggled is true it will prevent deactiving target layer (but not activation) + */ +void auto_mouse_toggle(void) { +    auto_mouse_context.status.is_toggled ^= 1; +    auto_mouse_context.timer.delay = 0; +} + +/** + * @brief Remove current auto mouse target layer from layer state + * + * Will remove auto mouse target layer from given layer state if appropriate. + * + * NOTE: Removal can be forced, ignoring appropriate critera + * + * @params state[in] layer_state_t original layer state + * @params force[in] bool force removal + * + * @return layer_state_t modified layer state + */ +layer_state_t remove_auto_mouse_layer(layer_state_t state, bool force) { +    if (force || ((AUTO_MOUSE_ENABLED) && !layer_hold_check())) { +        state &= ~((layer_state_t)1 << (AUTO_MOUSE_TARGET_LAYER)); +    } +    return state; +} + +/** + * @brief Disable target layer + * + * Will disable target layer if appropriate. + * NOTE: NOT TO BE USED in layer_state_set stack!!! + */ +void auto_mouse_layer_off(void) { +    if (layer_state_is((AUTO_MOUSE_TARGET_LAYER)) && (AUTO_MOUSE_ENABLED) && !layer_hold_check()) { +        layer_off((AUTO_MOUSE_TARGET_LAYER)); +    } +} + +/** + * @brief Weak function to handel testing if pointing_device is active + * + * Will trigger target layer activation(if delay timer has expired) and prevent deactivation when true. + * May be replaced by bool in report_mouse_t in future + * + * NOTE: defined weakly to allow for changing and adding conditions for specific hardware/customization + * + * @param[in] mouse_report report_mouse_t + * @return bool of pointing_device activation + */ +__attribute__((weak)) bool auto_mouse_activation(report_mouse_t mouse_report) { +    return mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons; +} + +/** + * @brief Update the auto mouse based on mouse_report + * + * Handel activation/deactivation of target layer based on auto_mouse_activation and state timers and local key/layer tracking data + * + * @param[in] mouse_report report_mouse_t + */ +void pointing_device_task_auto_mouse(report_mouse_t mouse_report) { +    // skip if disabled, delay timer running, or debounce +    if (!(AUTO_MOUSE_ENABLED) || timer_elapsed(auto_mouse_context.timer.active) <= AUTO_MOUSE_DEBOUNCE || timer_elapsed(auto_mouse_context.timer.delay) <= AUTO_MOUSE_DELAY) { +        return; +    } +    // update activation and reset debounce +    auto_mouse_context.status.is_activated = auto_mouse_activation(mouse_report); +    if (is_auto_mouse_active()) { +        auto_mouse_context.timer.active = timer_read(); +        auto_mouse_context.timer.delay  = 0; +        if (!layer_state_is((AUTO_MOUSE_TARGET_LAYER))) { +            layer_on((AUTO_MOUSE_TARGET_LAYER)); +        } +    } else if (layer_state_is((AUTO_MOUSE_TARGET_LAYER)) && timer_elapsed(auto_mouse_context.timer.active) > AUTO_MOUSE_TIME) { +        layer_off((AUTO_MOUSE_TARGET_LAYER)); +        auto_mouse_context.timer.active = 0; +    } +} + +/** + * @brief Handle mouskey event + * + * Increments/decrements mouse_key_tracker and restart active timer + * + * @param[in] pressed bool + */ +void auto_mouse_keyevent(bool pressed) { +    if (pressed) { +        auto_mouse_context.status.mouse_key_tracker++; +    } else { +        auto_mouse_context.status.mouse_key_tracker--; +    } +    auto_mouse_context.timer.delay = 0; +} + +/** + * @brief Handle auto mouse non mousekey reset + * + * Start/restart delay timer and reset auto mouse on keydown as well as turn the + * target layer off if on and reset toggle status + * + * NOTE: NOT TO BE USED in layer_state_set stack!!! + * + * @param[in] pressed bool + */ +void auto_mouse_reset_trigger(bool pressed) { +    if (pressed) { +        if (layer_state_is((AUTO_MOUSE_TARGET_LAYER))) { +            layer_off((AUTO_MOUSE_TARGET_LAYER)); +        }; +        auto_mouse_reset(); +    } +    auto_mouse_context.timer.delay = timer_read(); +} + +/** + * @brief handle key events processing for auto mouse + * + * Will process keys differently depending on if key is defined as mousekey or not. + * Some keys have built in behaviour(not overwritable): + * mouse buttons        : auto_mouse_keyevent() + * non-mouse keys       : auto_mouse_reset_trigger() + * mod keys             : skip auto mouse key processing + * mod tap              : skip on hold (mod keys) + * QK mods e.g. LCTL(kc): default to non-mouse key, add at kb/user level as needed + * non target layer keys: skip auto mouse key processing (same as mod keys) + * MO(target layer)     : auto_mouse_keyevent() + * target layer toggles : auto_mouse_toggle() (on both key up and keydown) + * target layer tap     : default processing on tap mouse key on hold + * all other keycodes   : default to non-mouse key, add at kb/user level as needed + * + * Will deactivate target layer once a non mouse key is pressed if nothing is holding the layer active + * such as held mousekey, toggled current target layer, or auto_mouse_activation is true + * + * @params keycode[in] uint16_t + * @params record[in] keyrecord_t pointer + */ +bool process_auto_mouse(uint16_t keycode, keyrecord_t* record) { +    // skip if not enabled or mouse_layer not set +    if (!(AUTO_MOUSE_ENABLED)) return true; + +    switch (keycode) { +        // Skip Mod keys to avoid layer reset +        case KC_LEFT_CTRL ... KC_RIGHT_GUI: +        case QK_MODS ... QK_MODS_MAX: +            break; +        // TO((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------- +        case QK_TO ... QK_TO_MAX: // same proccessing as next +        // TG((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------- +        case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: +            if ((keycode & 0xff) == (AUTO_MOUSE_TARGET_LAYER)) { +                if (!(record->event.pressed)) auto_mouse_toggle(); +            } +            break; +        // MO((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------- +        case QK_MOMENTARY ... QK_MOMENTARY_MAX: +            if ((keycode & 0xff) == (AUTO_MOUSE_TARGET_LAYER)) { +                auto_mouse_keyevent(record->event.pressed); +            } +        // DF --------------------------------------------------------------------------------------------------------- +        case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: +#    ifndef NO_ACTION_ONESHOT +        // OSL((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------ +        case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: +        case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: +#    endif +            break; +        // LM((AUTO_MOUSE_TARGET_LAYER), mod)-------------------------------------------------------------------------- +        case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: +            if (((keycode >> 8) & 0x0f) == (AUTO_MOUSE_TARGET_LAYER)) { +                auto_mouse_keyevent(record->event.pressed); +            } +            break; +            // TT((AUTO_MOUSE_TARGET_LAYER))--------------------------------------------------------------------------- +#    ifndef NO_ACTION_TAPPING +        case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: +            if ((keycode & 0xff) == (AUTO_MOUSE_TARGET_LAYER)) { +                auto_mouse_keyevent(record->event.pressed); +#        if TAPPING_TOGGLE != 0 +                if (record->tap.count == TAPPING_TOGGLE) { +                    if (record->event.pressed) { +                        auto_mouse_context.status.mouse_key_tracker--; +                    } else { +                        auto_mouse_toggle(); +                        auto_mouse_context.status.mouse_key_tracker++; +                    } +                } +#        endif +            } +            break; +        // LT((AUTO_MOUSE_TARGET_LAYER), kc)--------------------------------------------------------------------------- +        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: +            if (!record->tap.count) { +                if (((keycode >> 8) & 0x0f) == (AUTO_MOUSE_TARGET_LAYER)) { +                    auto_mouse_keyevent(record->event.pressed); +                } +                break; +            } +        // MT(kc) only skip on hold +        case QK_MOD_TAP ... QK_MOD_TAP_MAX: +            if (!record->tap.count) break; +#    endif +        // QK_MODS goes to default +        default: +            // skip on no event +            if (IS_NOEVENT(record->event)) break; +            // check if keyrecord is mousekey +            if (is_mouse_record(keycode, record)) { +                auto_mouse_keyevent(record->event.pressed); +            } else if (!is_auto_mouse_active()) { +                // all non-mousekey presses restart delay timer and reset status +                auto_mouse_reset_trigger(record->event.pressed); +            } +    } +    if (auto_mouse_context.status.mouse_key_tracker < 0) { +        auto_mouse_context.status.mouse_key_tracker = 0; +        dprintf("key tracker error (<0) \n"); +    } +    return true; +} + +/** + * @brief Local function to handle checking if a keycode is a mouse button + * + * Starts code stack for checking keyrecord if defined as mousekey + * + * @params keycode[in] uint16_t + * @params record[in]  keyrecord_t pointer + * @return bool true: keyrecord is mousekey false: keyrecord is not mousekey + */ +static bool is_mouse_record(uint16_t keycode, keyrecord_t* record) { +    // allow for keyboard to hook in and override if need be +    if (is_mouse_record_kb(keycode, record) || IS_MOUSEKEY(keycode)) return true; +    return false; +} + +/** + * @brief Weakly defined keyboard level callback for adding keyrecords as mouse keys + * + * Meant for redefinition at keyboard level and should return is_mouse_record_user by default at end of function + * + * @params keycode[in] uint16_t + * @params record[in] keyrecord_t pointer + * @return bool true: keyrecord is defined as mouse key false: keyrecord is not defined as mouse key + */ +__attribute__((weak)) bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record) { +    return is_mouse_record_user(keycode, record); +} + +/** + * @brief Weakly defined keymap/user level callback for adding keyrecords as mouse keys + * + * Meant for redefinition at keymap/user level and should return false by default at end of function + * + * @params keycode[in] uint16_t + * @params record[in] keyrecord_t pointer + * @return bool true: keyrecord is defined as mouse key false: keyrecord is not defined as mouse key + */ +__attribute__((weak)) bool is_mouse_record_user(uint16_t keycode, keyrecord_t* record) { +    return false; +} + +#endif // POINTING_DEVICE_AUTO_MOUSE_ENABLE diff --git a/quantum/pointing_device/pointing_device_auto_mouse.h b/quantum/pointing_device/pointing_device_auto_mouse.h new file mode 100644 index 0000000000..0f26af79e6 --- /dev/null +++ b/quantum/pointing_device/pointing_device_auto_mouse.h @@ -0,0 +1,87 @@ +/* Copyright 2022 Alabastard + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <string.h> + +#include "quantum.h" +#include "pointing_device.h" +#include "print.h" + +/* check settings and set defaults */ +#ifndef POINTING_DEVICE_AUTO_MOUSE_ENABLE +#    error "POINTING_DEVICE_AUTO_MOUSE_ENABLE not defined! check config settings" +#endif + +#ifndef AUTO_MOUSE_DEFAULT_LAYER +#    define AUTO_MOUSE_DEFAULT_LAYER 1 +#endif +#ifndef AUTO_MOUSE_TIME +#    define AUTO_MOUSE_TIME 650 +#endif +#ifndef AUTO_MOUSE_DELAY +#    define AUTO_MOUSE_DELAY GET_TAPPING_TERM(KC_MS_BTN1, &(keyrecord_t){}) +#endif +#ifndef AUTO_MOUSE_DEBOUNCE +#    define AUTO_MOUSE_DEBOUNCE 25 +#endif + +/* data structure */ +typedef struct { +    struct { +        bool    is_enabled; +        uint8_t layer; +    } config; +    struct { +        uint16_t active; +        uint16_t delay; +    } timer; +    struct { +        bool   is_activated; +        bool   is_toggled; +        int8_t mouse_key_tracker; +    } status; +} auto_mouse_context_t; + +/* ----------Set up and control------------------------------------------------------------------------------ */ +void          set_auto_mouse_enable(bool enable);                       // enable/disable auto mouse feature +bool          get_auto_mouse_enable(void);                              // get auto_mouse_enable +void          set_auto_mouse_layer(uint8_t layer);                      // set target layer by index +uint8_t       get_auto_mouse_layer(void);                               // get target layer index +void          auto_mouse_layer_off(void);                               // disable target layer if appropriate (DO NOT USE in layer_state_set stack!!) +layer_state_t remove_auto_mouse_layer(layer_state_t state, bool force); // remove auto mouse target layer from state if appropriate (can be forced) + +/* ----------For custom pointing device activation----------------------------------------------------------- */ +bool auto_mouse_activation(report_mouse_t mouse_report); // handles pointing device trigger conditions for target layer activation (overwritable) + +/* ----------Handling keyevents------------------------------------------------------------------------------ */ +void auto_mouse_keyevent(bool pressed);      // trigger auto mouse keyevent: mouse_keytracker increment/decrement on press/release +void auto_mouse_reset_trigger(bool pressed); // trigger non mouse keyevent: reset and start delay timer (DO NOT USE in layer_state_set stack!!) +void auto_mouse_toggle(void);                // toggle mouse layer flag disables mouse layer deactivation while on (meant for tap toggle or toggle of target) +bool get_auto_mouse_toggle(void);            // get toggle mouse layer flag value + +/* ----------Callbacks for adding keycodes to mouse record checking------------------------------------------ */ +bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record); +bool is_mouse_record_user(uint16_t keycode, keyrecord_t* record); + +/* ----------Core functions (only used in custom pointing devices or key processing)------------------------- */ +void pointing_device_task_auto_mouse(report_mouse_t mouse_report); // add to pointing_device_task_* +bool process_auto_mouse(uint16_t keycode, keyrecord_t* record);    // add to process_record_* + +/* ----------Macros/Aliases---------------------------------------------------------------------------------- */ +#define AUTO_MOUSE_TARGET_LAYER get_auto_mouse_layer() +#define AUTO_MOUSE_ENABLED get_auto_mouse_enable() diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index b96f8ff4b3..172c9f36d7 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -17,6 +17,7 @@   */  #include "pointing_device.h" +#include "pointing_device_internal.h"  #include "debug.h"  #include "wait.h"  #include "timer.h" @@ -32,10 +33,7 @@ report_mouse_t adns5050_get_report(report_mouse_t mouse_report) {      report_adns5050_t data = adns5050_read_burst();      if (data.dx != 0 || data.dy != 0) { -#    ifdef CONSOLE_ENABLE -        if (debug_mouse) dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy); -#    endif - +        pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);          mouse_report.x = (mouse_xy_report_t)data.dx;          mouse_report.y = (mouse_xy_report_t)data.dy;      } @@ -76,9 +74,7 @@ const pointing_device_driver_t pointing_device_driver = {  report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) {      report_analog_joystick_t data = analog_joystick_read(); -#    ifdef CONSOLE_ENABLE -    if (debug_mouse) dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y); -#    endif +    pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y);      mouse_report.x = data.x;      mouse_report.y = data.y; @@ -117,12 +113,24 @@ void cirque_pinnacle_configure_cursor_glide(float trigger_px) {  #    endif  #    if CIRQUE_PINNACLE_POSITION_MODE + +#        ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE +static bool is_touch_down; + +bool auto_mouse_activation(report_mouse_t mouse_report) { +    return is_touch_down || mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons; +} +#        endif +  report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {      pinnacle_data_t   touchData = cirque_pinnacle_read_data();      mouse_xy_report_t report_x = 0, report_y = 0;      static uint16_t   x = 0, y = 0; +#        if defined(CIRQUE_PINNACLE_TAP_ENABLE) +    mouse_report.buttons        = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); +#        endif  #        ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE -    cursor_glide_t    glide_report = {0}; +    cursor_glide_t glide_report = {0};      if (cursor_glide_enable) {          glide_report = cursor_glide_check(&glide); @@ -140,10 +148,12 @@ report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {          return mouse_report;      } -#        if CONSOLE_ENABLE -    if (debug_mouse && touchData.touchDown) { -        dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue); +    if (touchData.touchDown) { +        pd_dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue);      } + +#        ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE +    is_touch_down = touchData.touchDown;  #        endif      // Scale coordinates to arbitrary X, Y resolution @@ -227,9 +237,7 @@ const pointing_device_driver_t pointing_device_driver = {  report_mouse_t paw3204_get_report(report_mouse_t mouse_report) {      report_paw3204_t data = paw3204_read();      if (data.isMotion) { -#    ifdef CONSOLE_ENABLE -        dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y); -#    endif +        pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y);          mouse_report.x = data.x;          mouse_report.y = data.y; @@ -329,7 +337,7 @@ report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report) {      if (!in_motion) {          in_motion = true; -        dprintf("PWM3360 (0): starting motion\n"); +        pd_dprintf("PWM3360 (0): starting motion\n");      }      mouse_report.x = CONSTRAIN_HID_XY(report.delta_x);  | 
