diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index b1f6dcc84f5e..8b30ff234e82 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -791,22 +791,23 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ``` ### Settings -| Define | Description | Range | Units | Default | -| ------------------------------ | ----------------------------------------------------------------------------------------- | :-----: | :-----------: | -----------------------: | -| `POINTING_DEVICE_MODES_ENABLE` | Enables pointing device pointing device modes feature | `NA` | `None` | _Not defined_ | -| `POINTING_DEVICE_INVERT_V` | Inverts stored v axis accumulation (affects all modes) | `NA` | `None` | _Not defined_ | -| `POINTING_DEVICE_INVERT_H` | Inverts stored h axis accumulation (affects all modes) | `NA` | `None` | _Not defined_ | -| `POINTING_MODE_DEFAULT` | Default pointing device mode | `0-255` | `None` | `PM_NONE` | -| `POINTING_TAP_DELAY` | Delay between key presses in `pointing_tap_codes` in ms | `0-255` | `ms` | `0` | -| `POINTING_MODE_MAP_COUNT` | Number of modes defined in `pointing_device_mode_maps` | `0-255` | `None` | `0` | -| `POINTING_DEFAULT_DIVISOR` | Default divisor for all modes that do not have a defined divisor | `1-255` | `Varies` | `64` | -| `POINTING_HISTORY_DIVISOR` | Accumulated stored h/v per key tap in `PM_HISTORY` mode | `1-255` | `(h\|v)/tap` | `64` | -| `POINTING_VOLUME_DIVISOR` | Accumulated stored h/v per key tap in `PM_VOLUME` mode | `1-255` | `(h\|v)/tap` | `64` | -| `POINTING_CARET_DIVISOR` | Accumulated stored h/v per key tap in `PM_CARET` mode | `1-255` | `(h\|v)/tap` | `32` | -| `POINTING_CARET_DIVISOR_V` | Stored v per tap in `PM_CARET` (_overrides_ `POINTING_CARET_DIVISOR` _Recommended:_ `32`) | `1-255` | `(v)/tap` | `POINTING_CARET_DIVISOR` | -| `POINTING_CARET_DIVISOR_H` | Stored h per tap in `PM_CARET` (_overrides_ `POINTING_CARET_DIVISOR` _Recommended:_ `16`) | `1-255` | `(h)/tap` | `POINTING_CARET_DIVISOR` | -| `POINTING_PRECISION_DIVISOR` | Pointing device x/y movement per output x/y in `PM_PRECISION` mode | `1-255` | `(x\|y)/dot` | `2` | -| `POINTING_DRAG_DIVISOR` | Pointing device x/y movement per h/v axis tick in `PM_DRAG` mode | `1-255` | `(x\|y)/dot` | `4` | +| Define | Description | Range | Units | Default | +| -------------------------------- | ---------------------------------------------------------------------------------------------------- | :-----: | :-----------: | -----------------------: | +| `POINTING_DEVICE_MODES_ENABLE` | Enables pointing device pointing device modes feature | `NA` | `None` | _Not defined_ | +| `POINTING_DEVICE_MODES_INVERT_X` | Inverts stored y axis accumulation (affects all modes) | `NA` | `None` | _Not defined_ | +| `POINTING_DEVICE_MODES_INVERT_Y` | Inverts stored x axis accumulation (affects all modes) | `NA` | `None` | _Not defined_ | +| `POINTING_MODE_DEFAULT` | Default pointing device mode | `0-255` | `None` | `PM_NONE` | +| `POINTING_TAP_DELAY` | Delay between key presses in `pointing_tap_codes` in ms | `0-255` | `ms` | `0` | +| `POINTING_MODE_MAP_COUNT` | Number of modes defined in `pointing_device_mode_maps` | `0-255` | `None` | `0` | +| `POINTING_MODE_MAP_START` | Starting MODE ID of pointing mode maps | `0-255` | `None` | `PM_SAFE_RANGE` | +| `POINTING_DEFAULT_DIVISOR` | Default divisor for all modes that do not have a defined divisor | `1-255` | `Varies` | `64` | +| `POINTING_HISTORY_DIVISOR` | Accumulated stored x/y per key tap in `PM_HISTORY` mode | `1-255` | `(x\|y)/tap` | `64` | +| `POINTING_VOLUME_DIVISOR` | Accumulated stored x/y per key tap in `PM_VOLUME` mode | `1-255` | `(x\|y)/tap` | `64` | +| `POINTING_CARET_DIVISOR` | Accumulated stored x/y per key tap in `PM_CARET` mode | `1-255` | `(x\|y)/tap` | `32` | +| `POINTING_CARET_DIVISOR_V` | Stored x per horizontal tap in `PM_CARET` (_overrides_ `POINTING_CARET_DIVISOR` _Recommended:_ `32`) | `1-255` | `(y)/tap` | `POINTING_CARET_DIVISOR` | +| `POINTING_CARET_DIVISOR_H` | Stored y per vertical tap in `PM_CARET` (_overrides_ `POINTING_CARET_DIVISOR` _Recommended:_ `16`) | `1-255` | `(x)/tap` | `POINTING_CARET_DIVISOR` | +| `POINTING_PRECISION_DIVISOR` | Pointing device x/y movement per output x/y in `PM_PRECISION` mode | `1-255` | `(x\|y)/dot` | `2` | +| `POINTING_DRAG_DIVISOR` | Pointing device x/y movement per h/v axis tick in `PM_DRAG` mode | `1-255` | `(x\|y)/dot` | `4` | ***Notes:*** 1. it is recommended that generally powers of 2 are used for divisors **(e.g. 1, 2, 4, 8, 16, 32, 64, 128*)** as they should optimize better (_less code space and faster to compute_), but **any positive integer of 255 or less** will work. diff --git a/quantum/keycodes.h b/quantum/keycodes.h index b5f0a32500e5..ce62cc68134c 100644 --- a/quantum/keycodes.h +++ b/quantum/keycodes.h @@ -52,6 +52,8 @@ enum qk_keycode_ranges { QK_ONE_SHOT_MOD_MAX = 0x52BF, QK_LAYER_TAP_TOGGLE = 0x52C0, QK_LAYER_TAP_TOGGLE_MAX = 0x52DF, + QK_POINTING_MODE = 0x52E0, + QK_POINTING_MODE_MAX = 0x52FF, QK_SWAP_HANDS = 0x5600, QK_SWAP_HANDS_MAX = 0x56FF, QK_TAP_DANCE = 0x5700, @@ -1286,6 +1288,7 @@ enum qk_keycode_defines { #define IS_QK_ONE_SHOT_LAYER(code) ((code) >= QK_ONE_SHOT_LAYER && (code) <= QK_ONE_SHOT_LAYER_MAX) #define IS_QK_ONE_SHOT_MOD(code) ((code) >= QK_ONE_SHOT_MOD && (code) <= QK_ONE_SHOT_MOD_MAX) #define IS_QK_LAYER_TAP_TOGGLE(code) ((code) >= QK_LAYER_TAP_TOGGLE && (code) <= QK_LAYER_TAP_TOGGLE_MAX) +#define IS_QK_POINTING_MODE(code) ((code) >= QK_POINTING_MODE && (code) <= QK_POINTING_MODE_MAX) #define IS_QK_SWAP_HANDS(code) ((code) >= QK_SWAP_HANDS && (code) <= QK_SWAP_HANDS_MAX) #define IS_QK_TAP_DANCE(code) ((code) >= QK_TAP_DANCE && (code) <= QK_TAP_DANCE_MAX) #define IS_QK_MAGIC(code) ((code) >= QK_MAGIC && (code) <= QK_MAGIC_MAX) diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c index 0b70ab10c321..bfca0b6aa381 100644 --- a/quantum/pointing_device/pointing_device.c +++ b/quantum/pointing_device/pointing_device.c @@ -171,10 +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)); } @@ -507,6 +506,7 @@ __attribute__((weak)) report_mouse_t pointing_device_task_combined_kb(report_mou __attribute__((weak)) report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) { return pointing_device_combine_reports(left_report, right_report); } +#endif // defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) __attribute__((weak)) void pointing_device_keycode_handler(uint16_t keycode, bool pressed) { if IS_MOUSEKEY_BUTTON (keycode) { @@ -514,5 +514,3 @@ __attribute__((weak)) void pointing_device_keycode_handler(uint16_t keycode, boo pointing_device_send(); } } - -#endif // defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) diff --git a/quantum/pointing_device/pointing_device_modes.c b/quantum/pointing_device/pointing_device_modes.c index 676614db0d0e..ca4c072494fa 100644 --- a/quantum/pointing_device/pointing_device_modes.c +++ b/quantum/pointing_device/pointing_device_modes.c @@ -149,15 +149,15 @@ uint8_t get_toggled_pointing_mode_id(void) { * @return updated mouse_report report_mouse_t */ __attribute__((weak)) report_mouse_t pointing_modes_axes_conv(pointing_mode_t pointing_mode, report_mouse_t mouse_report) { -# ifdef POINTING_DEVICE_INVERT_H - pointing_mode.h -= mouse_report.x; +# ifdef POINTING_DEVICE_MODES_INVERT_X + pointing_mode.x -= mouse_report.x; # else - pointing_mode.h += mouse_report.x; + pointing_mode.x += mouse_report.x; # endif -# ifdef POINTING_DEVICE_INVERT_V - pointing_mode.v -= mouse_report.y; +# ifdef POINTING_DEVICE_MODES_INVERT_Y + pointing_mode.y -= mouse_report.y; # else - pointing_mode.v += mouse_report.y; + pointing_mode.y += mouse_report.y; # endif set_pointing_mode(pointing_mode); mouse_report.x = 0; @@ -175,14 +175,14 @@ __attribute__((weak)) report_mouse_t pointing_modes_axes_conv(pointing_mode_t po * @return direction uint8_t */ static uint8_t get_pointing_device_direction(void) { - if (abs(pointing_mode_context.mode.h) > abs(pointing_mode_context.mode.v)) { - if (pointing_mode_context.mode.h > 0) { + if (abs(pointing_mode_context.mode.x) > abs(pointing_mode_context.mode.y)) { + if (pointing_mode_context.mode.x > 0) { return PD_RIGHT; } else { return PD_LEFT; } } else { - if (pointing_mode_context.mode.v > 0) { + if (pointing_mode_context.mode.y > 0) { return PD_UP; } else { return PD_DOWN; @@ -284,16 +284,16 @@ void pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint switch (pointing_mode_context.mode.direction) { case PD_DOWN ... PD_UP: - count = pointing_mode_context.mode.v / (int16_t)pointing_mode_context.mode.divisor; + count = pointing_mode_context.mode.y / (int16_t)pointing_mode_context.mode.divisor; if (!count) return; - pointing_mode_context.mode.v -= count * (int16_t)pointing_mode_context.mode.divisor; - pointing_mode_context.mode.h = 0; + pointing_mode_context.mode.y -= count * (int16_t)pointing_mode_context.mode.divisor; + pointing_mode_context.mode.x = 0; break; case PD_LEFT ... PD_RIGHT: - count = pointing_mode_context.mode.h / (int16_t)pointing_mode_context.mode.divisor; + count = pointing_mode_context.mode.x / (int16_t)pointing_mode_context.mode.divisor; if (!count) return; - pointing_mode_context.mode.h -= count * (int16_t)pointing_mode_context.mode.divisor; - pointing_mode_context.mode.v = 0; + pointing_mode_context.mode.x -= count * (int16_t)pointing_mode_context.mode.divisor; + pointing_mode_context.mode.y = 0; break; } // skip if no key (but allow for axes update) @@ -339,54 +339,55 @@ static report_mouse_t process_pointing_mode(pointing_mode_t pointing_mode, repor return mouse_report; } # if (POINTING_MODE_MAP_COUNT > 0) - if (pointing_mode.id <= (POINTING_MODE_MAP_COUNT - 1)) { + if (pointing_mode.id <= (POINTING_MODE_MAP_COUNT - 1 + POINTING_MODE_MAP_START)) { pointing_tap_codes(POINTING_MODE_MAP(pointing_mode.id)); return mouse_report; } # endif switch (pointing_mode.id) { - // history scroll mode (will scroll through undo/redo history) - case PM_HISTORY: - pointing_tap_codes(C(KC_Z), KC_NO, KC_NO, C(KC_Y)); - break; -# ifdef EXTRAKEY_ENABLE - // volume scroll mode (adjusts audio volume) - case PM_VOLUME: - pointing_tap_codes(KC_NO, KC_VOLD, KC_VOLU, KC_NO); - break; -# endif - // caret mode (uses arrow keys to move cursor) - case PM_CARET: - pointing_tap_codes(KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT); + // drag scroll mode (sets mouse axes to mouse_report h & v with divisor) + case PM_DRAG: + mouse_report.h = pointing_mode.x / (int16_t)pointing_mode.divisor; + mouse_report.v = pointing_mode.y / (int16_t)pointing_mode.divisor; + pointing_mode.x -= mouse_report.h * (int16_t)pointing_mode.divisor; + pointing_mode.y -= mouse_report.v * (int16_t)pointing_mode.divisor; + set_pointing_mode(pointing_mode); break; // precision mode (reduce x y sensitivity temporarily) case PM_PRECISION: -# ifdef POINTING_DEVICE_INVERT_H - mouse_report.x -= pointing_mode.h / (int16_t)pointing_mode.divisor; - pointing_mode.h += mouse_report.x * (int16_t)pointing_mode.divisor; +# ifdef POINTING_DEVICE_MODES_INVERT_X + mouse_report.x -= pointing_mode.x / (int16_t)pointing_mode.divisor; + pointing_mode.x += mouse_report.x * (int16_t)pointing_mode.divisor; # else - mouse_report.x += pointing_mode.h / (int16_t)pointing_mode.divisor; - pointing_mode.h -= mouse_report.x * (int16_t)pointing_mode.divisor; + mouse_report.x += pointing_mode.x / (int16_t)pointing_mode.divisor; + pointing_mode.x -= mouse_report.x * (int16_t)pointing_mode.divisor; # endif -# ifdef POINTING_DEVICE_INVERT_V - mouse_report.y -= pointing_mode.v / (int16_t)pointing_mode.divisor; - pointing_mode.v += mouse_report.y * (int16_t)pointing_mode.divisor; +# ifdef POINTING_DEVICE_MODES_INVERT_Y + mouse_report.y -= pointing_mode.y / (int16_t)pointing_mode.divisor; + pointing_mode.y += mouse_report.y * (int16_t)pointing_mode.divisor; # else - mouse_report.y += pointing_mode.v / (int16_t)pointing_mode.divisor; - pointing_mode.v -= mouse_report.y * (int16_t)pointing_mode.divisor; + mouse_report.y += pointing_mode.y / (int16_t)pointing_mode.divisor; + pointing_mode.y -= mouse_report.y * (int16_t)pointing_mode.divisor; # endif set_pointing_mode(pointing_mode); break; + // caret mode (uses arrow keys to move cursor) + case PM_CARET: + pointing_tap_codes(KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT); + break; - // drag scroll mode (sets mouse axes to mouse_report h & v with divisor) - case PM_DRAG: - mouse_report.h = pointing_mode.h / (int16_t)pointing_mode.divisor; - mouse_report.v = pointing_mode.v / (int16_t)pointing_mode.divisor; - pointing_mode.h -= mouse_report.h * (int16_t)pointing_mode.divisor; - pointing_mode.v -= mouse_report.v * (int16_t)pointing_mode.divisor; - set_pointing_mode(pointing_mode); + // history scroll mode (will scroll through undo/redo history) + case PM_HISTORY: + pointing_tap_codes(C(KC_Z), KC_NO, KC_NO, C(KC_Y)); + break; + +# ifdef EXTRAKEY_ENABLE + // volume scroll mode (adjusts audio volume) + case PM_VOLUME: + pointing_tap_codes(KC_NO, KC_VOLD, KC_VOLU, KC_NO); break; +# endif } return mouse_report; } diff --git a/quantum/pointing_device/pointing_device_modes.h b/quantum/pointing_device/pointing_device_modes.h index 6f0bfdffe91e..1a48cce596cb 100644 --- a/quantum/pointing_device/pointing_device_modes.h +++ b/quantum/pointing_device/pointing_device_modes.h @@ -68,11 +68,13 @@ /* error checking */ #if (POINTING_DEFAULT_DIVISOR == 0) -# error "ERROR: DEFAULT DIVISOR is set to zero! set to non zero value" +# pragma message "DEFAULT_DIVISOR must be non zero value" +# error DEFAULT_DIVISOR set to zero #endif /* check valid keycode range */ #if (!((POINTING_MODE_COUNT - 1) & (~POINTING_MODE_COUNT))) -# error "!!ERROR: number of keycodes for QK_POINTING_MODE incorrect, must be a power of 2!!" +# pragma message "Total number of keycodes in QK_POINTING_MODE range must be a power of 2" +# error QK_POINTING_MODE keycode range is not a power of two #endif /* keycode setup */ @@ -81,27 +83,6 @@ #define POINTING_MODE_TG (POINTING_MODE_MO_MAX + 1) #define POINTING_MODE_TG_MAX QK_POINTING_MODE_MAX -/* Default Pointing device pointing modes */ -enum pointing_device_mode_list { - // Built in pointing modes OVERWRITABLE - PM_HISTORY = POINTING_MODE_COUNT - 6, - PM_VOLUME, - PM_CARET, - PM_PRECISION, - PM_DRAG, - // null pointing mode NOT OVERWRITABLE - PM_NONE = POINTING_MODE_COUNT - 1, - // safe range for custom modes - PM_SAFE_RANGE -}; - -/* pointing mode aliases */ -#define PM_PRE PM_PRECISION -#define PM_HST PM_HISTORY -#define PM_VOL PM_VOLUME -#define PM_CRT PM_CARET -#define PM_DRG PM_DRAG - /* enum of directions */ enum { PD_DOWN = 0, PD_UP, PD_LEFT, PD_RIGHT }; @@ -111,8 +92,8 @@ typedef struct { uint8_t id; uint8_t divisor; uint8_t direction; - int16_t h; - int16_t v; + int16_t x; + int16_t y; } pointing_mode_t; /* context structure to track additional data */ @@ -167,6 +148,11 @@ bool process_pointing_mode_records(uint16_t keyrecord, keyrecord_t* re # define POINTING_MODE_MAP_COUNT 0 #endif #if (POINTING_MODE_MAP_COUNT > 0) +# ifndef EXTRAKEY_ENABLE +# define POINTING_MODE_MAP_START PM_VOLUME +# else +# define POINTING_MODE_MAP_START PM_SAFE_RANGE +# endif # define POINTING_MODE_LAYOUT(Y_POS, X_NEG, X_POS, Y_NEG) \ { X_NEG, Y_NEG, Y_POS, X_POS } diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 84c225e07e7b..38a1265ec358 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -125,14 +125,6 @@ #define QK_MOD_TAP_GET_MODS(kc) (((kc) >> 8) & 0x1F) #define QK_MOD_TAP_GET_TAP_KEYCODE(kc) ((kc)&0xFF) -// Scroll mode keys 16 scroll mode max -// pointing device mode key macros -#define POINTING_MODE_COUNT ((QK_POINTING_MODE_MAX - QK_POINTING_MODE + 1) / 2) -// Momentary scroll mode -#define PM_MO(pm) (MIN((pm), (POINTING_MODE_COUNT - 1)) + QK_POINTING_MODE) -// Toggle default scroll mode -#define PM_TG(pm) (MIN((pm), (POINTING_MODE_COUNT - 1)) + QK_POINTING_MODE + POINTING_MODE_COUNT) - #define LCTL_T(kc) MT(MOD_LCTL, kc) #define RCTL_T(kc) MT(MOD_RCTL, kc) #define CTL_T(kc) LCTL_T(kc) @@ -228,9 +220,31 @@ #define SQ_R(n) (n < SEQUENCER_RESOLUTIONS ? SEQUENCER_RESOLUTION_MIN + n : KC_NO) #define SQ_T(n) (n < SEQUENCER_TRACKS ? SEQUENCER_TRACK_MIN + n : KC_NO) -// Scroll mode aliases -#define PM_DRG PM_DRAG -#define PM_CRT PM_CARET +// Pointing device mode keys 16 modes max +// pointing device mode key macros +#define POINTING_MODE_COUNT ((QK_POINTING_MODE_MAX - QK_POINTING_MODE + 1) / 2) +// Momentary scroll mode +#define PM_MO(pm) (MIN((pm), (POINTING_MODE_COUNT - 1)) + QK_POINTING_MODE) +// Toggle default scroll mode +#define PM_TG(pm) (MIN((pm), (POINTING_MODE_COUNT - 1)) + QK_POINTING_MODE + POINTING_MODE_COUNT) + +// Default Pointing device pointing modes +enum pointing_device_mode_list { + PM_NONE, + PM_DRAG, + PM_PRECISION, + PM_CARET, + PM_HISTORY, + PM_VOLUME, + // safe range for custom modes + PM_SAFE_RANGE +}; + +// pointing mode aliases +#define PM_PRE PM_PRECISION +#define PM_HST PM_HISTORY #define PM_VOL PM_VOLUME +#define PM_CRT PM_CARET +#define PM_DRG PM_DRAG #include "quantum_keycodes_legacy.h"