diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index c3514f58828e..6a5729a30428 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -835,25 +835,27 @@ 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_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 device mode maps | `1-255` | `None` | `PM_SAFE_RANGE` or `PM_VOLUME` | -| `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` | x value per left/right tap in `PM_CARET`(_overrides_ `POINTING_CARET_DIVISOR` _Recommended:_ `32`) | `1-255` | `(y)/tap` | `POINTING_CARET_DIVISOR` | -| `POINTING_CARET_DIVISOR_H` | y value per up/down 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` | +| `POINTING_DEVICE_MODES_ENABLE` | (Required) Enables pointing device pointing device modes feature | `NA` | `None` | _Not defined_ | +| `POINTING_DEVICE_MODES_INVERT_X` | (optional) Inverts stored y axis accumulation (affects all modes) | `NA` | `None` | _Not defined_ | +| `POINTING_DEVICE_MODES_INVERT_Y` | (optional) Inverts stored x axis accumulation (affects all modes) | `NA` | `None` | _Not defined_ | +| `POINTING_DEVICE_MODES_FASTCALC` | (optional) Enables fast calculations for division operations limiting divisors to base 2 | `NA` | `None` | _Not defined_ | +| `POINTING_MODE_DEFAULT` | (optional) Default pointing device mode | `0-255` | `None` | `PM_NONE` | +| `POINTING_TAP_DELAY` | (optional) Delay between key presses in `pointing_tap_codes` in ms | `0-255` | `ms` | `0` | +| `POINTING_MODE_MAP_COUNT` | (optional) Number of modes defined in `pointing_device_mode_maps` | `0-255` | `None` | `0` | +| `POINTING_DEFAULT_DIVISOR` | (optional) Default divisor for all modes that do not have a defined divisor | `1-255` | `Varies` | `64` | +| `POINTING_HISTORY_DIVISOR` | (optional) Accumulated stored x/y per key tap in `PM_HISTORY` mode | `1-255` | `(x\|y)/tap` | `64` | +| `POINTING_VOLUME_DIVISOR` | (optional) Accumulated stored x/y per key tap in `PM_VOLUME` mode | `1-255` | `(x\|y)/tap` | `64` | +| `POINTING_CARET_DIVISOR` | (optional) Accumulated stored x/y per key tap in `PM_CARET` mode | `1-255` | `(x\|y)/tap` | `32` | +| `POINTING_CARET_DIVISOR_V` | (optional) x input per left/right tap in `PM_CARET`(_overrides_ `POINTING_CARET_DIVISOR`) | `1-255` | `(y)/tap` | `POINTING_CARET_DIVISOR` | +| `POINTING_CARET_DIVISOR_H` | (optional) y input per up/down tap in `PM_CARET`(_overrides_ `POINTING_CARET_DIVISOR`) | `1-255` | `(x)/tap` | `POINTING_CARET_DIVISOR` | +| `POINTING_PRECISION_DIVISOR` | (optional) Pointing device x/y movement per output x/y in `PM_PRECISION` mode | `1-255` | `(x\|y)/dot` | `2` | +| `POINTING_DRAG_DIVISOR` | (optional) Pointing device x/y movement per h/v axis tick in `PM_DRAG` mode | `1-255` | `(x\|y)/dot` | `4` | +| `POINTING_DRAG_DIVISOR_V` | (optional) y input per v axis tick in `PM_DRAG`(_overrides_ `POINTING_DRAG_DIVISOR`) | `1-255` | `(y)/dot` | `POINTING_DRAG_DIVISOR` | +| `POINTING_DRAG_DIVISOR_H` | (optional) x input per h axis tick in `PM_DRAG`(_overrides_ `POINTING_DRAG_DIVISOR`) | `1-255` | `(x)/dot` | `POINTING_DRAG_DIVISOR` | ***Notes:*** -1. `POINTING_MODE_MAP_START` will be `PM_SAFE_RANGE` by default if `EXTRAKEY_ENABLED` is defined and will start at `PM_VOLUME` if `EXTRAKEY_ENABLED` is not defined. -2. 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. +1. `POINTING_DEVICE_MODES_FASTCALC` will force all divisors to powers of two but will enable fast calculation of division. +2. it is recommended that generally powers of 2 are used for divisors **(e.g. 1, 2, 4, 8, 16, 32, 64, 128*)** and using `POINTING_DEVICE_MODES_FASTCALC` as will optimize better, but as long as `POINTING_DEVICE_MODES_FASTCALC` is not used **any positive integer of 255 or less** will work. 3. Drag scroll speed will be effected by OS mouse settings (_there are usually separate settings for scroll "wheel" and "wheel tilt"_) - The `POINTING_DRAG_DIVISOR` default value of 8 is based on having mouse settings in the OS set to one line per tick of "mouse wheel" or "wheel tilt" (_the minimum_) 4. `POINTING_PRECISION_DIVISOR` default will half cursor speed when active (_divisor of 2_) but a divisor of 4 is fine to use as well but the cursor will be quite a bit slower, however divisors of 8 or greater will likely only work well for high cpi settings. @@ -951,13 +953,14 @@ For most keycode tapping modes a divisor of `64` works well, which is the defaul ***NOTE: if checking `pointing_mode.direction` or `direction` is on either the x or y axis using `direction < PD_LEFT` could be used to return true for the y axis and false for the x axis respectively (see example below)*** #### Callbacks to set pointing device mode divisors -The following callbacks can be used to overwrite built in mode divisors or to set divisors for new modes. The `get_pointing_mode_divisor` stacks works by checking the functions until a non zero value is reached in order of `user`->`kb`->`built in`->`default_value`. Returning a divisor of `0` will allow processing to continue on to the next function, However this means that if any of the callback returns a default value other than 0 then that will overwrite the divisors for all modes not defined in the callback functions (such as built in modes). This allows for overriding built in divisors by users/keymaps and keyboards and overriding keyboard level divisors by users/keymaps so it is possible to give built in modes the same level of divisor customization as new custom modes. - -| Callback | Description | -| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint8_t direction);` | Keyboard level callback for setting divisor based on mode id an direction | -| `uint8_t get_pointing_mode_divisor_user(uint8_t mode_id, uint8_t direction);` | Keymap/user level callback for setting divisor | - +The following callbacks can be used to overwrite built in mode divisors or to set divisors for new modes. The `get_pointing_mode_divisor` stacks works by checking the functions until a non zero value is reached in order of `user`->`kb`->`built in`->`default_value`. Returning a divisor of `0` will allow processing to continue on to the next stage, However this means that if any of the get divisor callback functions return a default value other than 0 then that will overwrite all subsequent divisors(such as built in modes). These functions allows for overriding and modifying built in divisors by users/keymaps and keyboards and overriding keyboard level divisors by users/keymaps so it is possible to give built in modes the same level of divisor customization as new custom modes. + +| Callback | Description | +| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| `uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint8_t direction);` | Keyboard level callback for setting divisor based on mode id an direction | +| `uint8_t get_pointing_mode_divisor_user(uint8_t mode_id, uint8_t direction);` | Keymap/user level callback for setting divisor | +| `uint8_t pointing_mode_divisor_postprocess_kb(uint8_t mode_id, uint8_t direction);` | keyboard level callback for modifying all divisors before being updated | +| `uint8_t pointing_mode_divisor_postprocess_user(uint8_t mode_id, uint8_t direction);` | Keymap/user level callback for modifying all divisors | #### Example code of assigning divisors for new modes ```c @@ -1108,21 +1111,21 @@ There are a number of functions allowing access and control of different aspects ### `pointing_mode_t` structure The current active pointing mode is controlled by tracking an internal `pointing_mode_t` data structure. The `pointing_mode.direction`, and `pointing_mode.divisor` variables are updated immediately after `pointing_mode.x`, and `pointing_mode.y` at the start of the pointing device modes process before the callback functions are called. Therefore if the `h`,`v`, or `mode_id` are modified and it is desired to have the direction and divisor reflect the changes they will need to be updated by calling `pointing_mode_update()`. A few other variables are tracked outside of the pointing mode structure and there are specialized functions to access/modify them. all of these variables are cleared on mode changes/resets (_mode id will be set to tg_mode_id_) -| Variable | Description | Data type | Functions to access/modify | -| :------------------------ | :---------------------------------------- | :--------: | :---------------------------------------------- | -| `pointing_mode.id` | Id number of current active mode | `uint8_t` | `get_pointing_mode_id`, `set_pointing_mode_id` | -| `pointing_mode.divisor` | Divisor of current mode id and direction | `uint8_t` | -| `pointing_mode.direction` | Direction based on stored x and y values | `uint8_t` | -| `pointing_mode.x` | Stored horizontal axis value | `uint16_t` | -| `pointing_mode.y` | Stored vertical axis value | `uint16_t` | +| Variable | Description | Data type | Functions to access/modify outside of mode processing | +| :------------------------ | :---------------------------------------- | :--------: | :--------------------------------------------------------------------- | +| `pointing_mode.id` | Id number of current active mode | `uint8_t` | `get_pointing_mode_id`, `set_pointing_mode_id` | +| `pointing_mode.divisor` | Divisor of current mode id and direction | `uint8_t` | `get_pointing_mode_divisor_*`, `pointing_mode_divisor_postprocess_*` | +| `pointing_mode.direction` | Direction based on stored x and y values | `uint8_t` | _Available in_ `get_pointing_mode_divisor_*` | +| `pointing_mode.x` | Stored horizontal axis value | `uint16_t` | _None_ | +| `pointing_mode.y` | Stored vertical axis value | `uint16_t` | _None_ | ### Other tracked variables (Not directly accessible use functions) These variables are tracked outside of the `pointing_mode_t` structure as they are not cleared on mode reset/change. -| Variable | Description | Data type | Functions -| :----------: | :-------------------------------------------------------------- | :--------: | -| `tg_mode_id` | Mode id of last active toggle mode | `uint8_t` | -| `is_left` | if mode is on left pointing device (see split pointing below) | `bool` | +| Variable | Description | Data type | Access/Control Functions | +| :----------: | :------------------------------------------------------------------------------------------ | :--------: | --------------------------------------------------------- | +| `tg_mode_id` | Mode id of last active toggle mode | `uint8_t` | `toggle_pointing_mode_id`, `get_toggled_pointing_mode_id` | +| `is_left` | if mode is on left pointing device (see [split-pointing](#multiple-pointing-devices) below) | `bool` | `is_pointing_mode_on_left`, `pointing_mode_switch_hands` | ***NOTE: `is_left` is only available when `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED` are both defined*** @@ -1198,11 +1201,17 @@ These callbacks work similar to keycode processing callbacks in that returning f There are several functions available to assist with the creation of custom modes. These allow for setting the internal `pointing_mode` values with any changes that have been made, as well as updating divisor and direction after changes. -| Function | Description | Return type | -| :------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------- | :---------: | -| `set_pointing_mode(pointing_mode_t pointing_mode)` | Set stored pointing mode state to `pointing_mode` | _None_ | -| `pointing_mode_update(void)` | Update stored direction and divisor based on current mode id and h/v values | _None_ | -| `pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint16_t kc_right)` | Convert stored h/v axis value to key taps depending on direction, 1 key tap per current divisor | _None_ | +| Function | Description | Return type | +| :------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------- | :----------: | +| `set_pointing_mode(pointing_mode_t pointing_mode)` | Set stored pointing mode state to `pointing_mode` | _None_ | +| `pointing_mode_update(void)` | Update stored direction and divisor based on current mode id and h/v values | _None_ | +| `pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint16_t kc_right)` | Convert stored h/v axis value to key taps depending on direction, 1 key tap per current divisor | _None_ | +| `apply_divisor_xy(int16_t value)` | divides value by the current divisor clamped to mouse cursor output | `mouse_xy_t` | +| `apply_divisor_hv(int16_t value)` | divides value by the current divisor clamped to mouse scroll output | `int8_t` | +| `multiply_divisor_xy(mouse_xy_report_t value)` | multiplies cursor value by the current divisor clamped to `int16_t` (_to collect the residual_) | `int16_t` | +| `multiply_divisor_hv(int8_t value)` | multiplies scroll value by the current divisor clamped to `int16_t` (_to collect the residual_) | `int16_t` | +| `multiply_divisor_hv(int8_t value)` | multiplies scroll value by the current divisor clamped to `int16_t` (_to collect the residual_) | `int16_t` | + #### Creating modes using callback functions: ```c @@ -1245,7 +1254,7 @@ uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint8_t direction) { return 0; // continue processing } -#define CONSTRAIN_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt))) +#define CONSTRAIN_XY(value) (value > REPORT_XY_MAX? REPORT_XY_MAX : value < REPORT_XY_MIN? REPORT_XY_MIN : value) bool process_pointing_mode_kb(pointing_mode_t pointing_mode, report_mouse_t* mouse_report) { switch(pointing_mode.id){ @@ -1259,24 +1268,29 @@ bool process_pointing_mode_kb(pointing_mode_t pointing_mode, report_mouse_t* mou // Manipulating pointing_mode & mouse_report (cursor speed boost mode example) case PM_CUR_ACCEL: - // reset mouse_report note tha mouse_report is a pointer in this function's context + // reset mouse_report note that mouse_report is a pointer in this function's context *mouse_report = pointing_device_get_report(); + // set up temp variable and context + { + // add linear boost to cursor x speed + mouse_xy_report_t temp_mouse_axis = apply_divisor_xy(pointing_mode.x); #ifdef POINTING_DEVICE_INVERT_H - // add linear boost to cursor x speed - mouse_report->x = CONSTRAIN_XY(mouse_report->x - pointing_mode.x / pointing_mode.divisor); + mouse_report->x = CONSTRAIN_XY(mouse_report->x - temp_mouse_axis); #else - mouse_report->x = CONSTRAIN_XY(mouse_report->x + pointing_mode.x / pointing_mode.divisor); + mouse_report->x = CONSTRAIN_XY(mouse_report->x + temp_mouse_axis); #endif - // collect residuals - pointing_mode.x = 0; - // add linear boost to cursor y speed + // collect residuals + pointing_mode.x -= multiply_divisor_xy(temp_mouse_axis); + // add linear boost to cursor y speed + temp_mouse_axis = apply_divisor_xy(pointing_mode.y); #ifdef POINTING_DEVICE_INVERT_V - mouse_report->y = CONSTRAIN_XY(mouse_report->y - pointing_mode.y / pointing_mode.divisor); + mouse_report->y = CONSTRAIN_XY(mouse_report->y - apply_divisor_xy(pointing_mode.y)); #else - mouse_report->y = CONSTRAIN_XY(mouse_report->y + pointing_mode.y / pointing_mode.divisor); + mouse_report->y = CONSTRAIN_XY(mouse_report->y + apply_divisor_xy(pointing_mode.y)); #endif - // collect residuals - pointing_mode.y = 0; + // collect residuals + pointing_mode.y -= multiply_divisor_xy(temp_mouse_axis); + } // update pointing_mode with residual stored x & y set_pointing_mode(pointing_mode); // NOTE: mouse_report does not need to be set or sent here as it will be carried forward @@ -1335,7 +1349,7 @@ Also there is an ability to modify how pointing device output is converted to st -***Additional Note: `pointing_modes_axes_conv` does not need to be overwritten to avoid clearing pointing device x/y*** -***!Warning!: changes made to `pointing_mode` within `pointing_modes_axes_conv` must be saved by calling `set_pointing_mode(pointing_mode)` before returning the updated `mouse_report`*** -## Multiple pointing devices +## Multiple Pointing Devices If both `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED` are defined then the pointing device modes will use the input from either left or right pointing devices which can set at compile time with `POINTING_MODES_LEFT` and switched at run time using `pointing_mode_switch_hands()`. Currently pointing device modes does not support control of multiple pointing devices simultaneously, so only one device will be affected by the current active mode with the other giving default output. #### Relevant Settings diff --git a/keyboards/gray_studio/think65/solder/keymaps/yt/config.h b/keyboards/gray_studio/think65/solder/keymaps/yt/config.h new file mode 100644 index 000000000000..6bdff5008e44 --- /dev/null +++ b/keyboards/gray_studio/think65/solder/keymaps/yt/config.h @@ -0,0 +1,19 @@ +/* Copyright 2022 Yt Liu + * + * 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 + +#define RGBLIGHT_LAYERS diff --git a/keyboards/gray_studio/think65/solder/keymaps/yt/keymap.c b/keyboards/gray_studio/think65/solder/keymaps/yt/keymap.c new file mode 100644 index 000000000000..bc2854261f45 --- /dev/null +++ b/keyboards/gray_studio/think65/solder/keymaps/yt/keymap.c @@ -0,0 +1,139 @@ +/* Copyright 2021 Qiaowei Tang + * + * 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 . + */ + + + + /* + * LED ranges for Think6.5v2 2U + * These values were derived from manual testing. Derived from keymaps/rys. + * ┌───────┬───────┬─────────────┬───────────────────────────────────────────┐ + * │ 00 01 │ 02 03 │ 04 05 06 07 │ 08 09 10 11 12 13 14 15 16 17 18 19 20 21 │ + * │ badge │ badge │    (?)     │              underglow (?)                │ + * │  bar │ icon │         │                               │ + * └───────┴───────┴─────────────┴───────────────────────────────────────────┘ + */ + + +// Setup some layers to control mac/win layouts +#include QMK_KEYBOARD_H + +enum bs_layers { + _WIN, + _MAC, + _FN, + _BLANC +}; + +// Setup some keycodes to control cycling and range toggling +enum bs_keycodes { + WIN = SAFE_RANGE, + MAC +}; + +// Light LEDs 6 to 9 and 12 to 15 red when caps lock is active. Hard to ignore! +const rgblight_segment_t PROGMEM my_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS( + {0, 4, HSV_WHITE} // Light 4 LEDs, starting with LED 12 +); + +// Now define the array of layers. Later layers take precedence +const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST( + my_capslock_layer // Overrides other layers +); + +void keyboard_post_init_user(void) { + // Enable the LED layers + rgblight_layers = my_rgb_layers; +}; + +bool led_update_user(led_t led_state) { + rgblight_set_layer_state(0, led_state.caps_lock); + return true; +}; + +layer_state_t default_layer_state_set_user(layer_state_t state) { + if (get_highest_layer(state) == _MAC) { + rgblight_mode_noeeprom(6); + } else { + rgblight_mode_noeeprom(9); + } + return state; +} + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Win Layer + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐ + * │Esc│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ Bckspc│pup│ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤ + * │Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│| \│pdw│ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ + * │lTCap │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter│ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤ │ + * │Shift │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│ Shift│ Up│ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴───┴┬─┬───┼───┼───┤ + * │Ctrl│ win│ alt│ Space │ Func │ │Lef│Dow│Rig│ + * └────┴────┴────┴────────────────────────┴─────────┴─┴───┴───┴───┘ + */ + [_WIN] = LAYOUT_65_ansi_blocker( + QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN, + LT(_FN, KC_CAPS), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, _______, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, _______, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_1, MO(_FN), KC_LEFT, KC_DOWN, KC_RGHT + ), + /* Mac Layer + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐ + * │Esc│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ Bckspc│pup│ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤ + * │Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│| \│pdw│ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ + * │lTCap │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter│ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤ │ + * │Shift │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│ Shift│ Up│ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴───┴┬─┬───┼───┼───┤ + * │Ctrl│ Opt│ Cmd│ Space │ Func │ │Lef│Dow│Rig│ + * └────┴────┴────┴────────────────────────┴─────────┴─┴───┴───┴───┘ + */ + [_MAC] = LAYOUT_65_ansi_blocker( + QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN, + LT(_FN, KC_CAPS), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, _______, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, _______, + KC_LCTL, KC_LOPT, KC_LCMD, KC_SPC, KC_1, MO(_FN), KC_LEFT, KC_DOWN, KC_RGHT + ), + /* Fn Layer + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬────────┬───┐ + * │lck│ F1│ F2│ F3│ F4│ F5│ F6│ F7│ F8│ F9│F10│F11│F12│ delete │mac│ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬──────┼───┤ + * │ TOG │MB1│MSU│MB2│MDU│ │ │ │UP │ │Hom│pgu│End│ │win│ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴──────┼───┤ + * │MO(2) │MSL│MSD│MSR│MWD│ │ │Lft│Dwn│rgt│END│pgd│ reset │ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬────┤ │ + * │ RGB_mod│F13│F14│F15│F16│F17│F18│F19│F20│F21│F22│F23 │Bri+│ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼────┼───┤ + * │Vold│Mute│Volu│ │ │ │ │ │Bri-│ │ + * └────┴────┴────┴────────────────────────┴────┴────┴─┴───┴────┴───┘ + */ + [_FN] = LAYOUT_65_ansi_blocker( + KC_LOCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, MAC, + RGB_TOG, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_MS_WH_UP, _______, _______, _______, KC_UP, _______, KC_HOME, KC_PGUP, _______, _______, WIN, + _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN, _______, _______, KC_LEFT, KC_DOWN, KC_RIGHT, KC_END, KC_PGDN, QK_BOOT, _______, + RGB_MOD, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_BRIU, _______, + KC_VOLD, KC_MUTE, KC_VOLU, _______, _______, _______, _______, KC_BRID, _______ + ), + +}; + + diff --git a/keyboards/gray_studio/think65/solder/keymaps/yt/readme.md b/keyboards/gray_studio/think65/solder/keymaps/yt/readme.md new file mode 100644 index 000000000000..84286c5e342f --- /dev/null +++ b/keyboards/gray_studio/think65/solder/keymaps/yt/readme.md @@ -0,0 +1,3 @@ +# YT45's Think6.5v2 keymap + +My personal keymap for the Think6.5v2. Using the dangjoeltang as a the base and adding a quick switch from mac to win layouts. also with indication of the current layer with RGB lights. diff --git a/keyboards/gray_studio/think65/solder/keymaps/yt/rules.mk b/keyboards/gray_studio/think65/solder/keymaps/yt/rules.mk new file mode 100644 index 000000000000..378684852980 --- /dev/null +++ b/keyboards/gray_studio/think65/solder/keymaps/yt/rules.mk @@ -0,0 +1,5 @@ +LTO_ENABLE = yes +VIA_ENABLE = yes +MOUSEKEY_ENABLE = yes +KEY_LOCK_ENABLE = yes +CONSOLE_ENABLE = no \ No newline at end of file diff --git a/keyboards/handwired/jscotto/scotto40/info.json b/keyboards/handwired/jscotto/scotto40/info.json new file mode 100644 index 000000000000..dd52bd7a1f90 --- /dev/null +++ b/keyboards/handwired/jscotto/scotto40/info.json @@ -0,0 +1,180 @@ +{ + "manufacturer": "Joe Scotto", + "keyboard_name": "Scotto40", + "maintainer": "joe-scotto", + "bootloader": "caterina", + "diode_direction": "COL2ROW", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + "cols": ["D1", "D0", "D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5"], + "rows": ["B1", "B3", "B2", "B6"] + }, + "processor": "atmega32u4", + "url": "", + "usb": { + "device_version": "1.0.0", + "pid": "0x0000", + "vid": "0xFEED" + }, + "layouts": { + "LAYOUT_ortho_3x10_7": { + "layout": [ + // Row 1 + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1, "y": 0 }, + { "matrix": [0, 2], "x": 2, "y": 0 }, + { "matrix": [0, 3], "x": 3, "y": 0 }, + { "matrix": [0, 4], "x": 4, "y": 0 }, + { "matrix": [0, 5], "x": 5, "y": 0 }, + { "matrix": [0, 6], "x": 6, "y": 0 }, + { "matrix": [0, 7], "x": 7, "y": 0 }, + { "matrix": [0, 8], "x": 8, "y": 0 }, + { "matrix": [0, 9], "x": 9, "y": 0 }, + + // Row 2 + { "matrix": [1, 0], "x": 0, "y": 1 }, + { "matrix": [1, 1], "x": 1, "y": 1 }, + { "matrix": [1, 2], "x": 2, "y": 1 }, + { "matrix": [1, 3], "x": 3, "y": 1 }, + { "matrix": [1, 4], "x": 4, "y": 1 }, + { "matrix": [1, 5], "x": 5, "y": 1 }, + { "matrix": [1, 6], "x": 6, "y": 1 }, + { "matrix": [1, 7], "x": 7, "y": 1 }, + { "matrix": [1, 8], "x": 8, "y": 1 }, + { "matrix": [1, 9], "x": 9, "y": 1 }, + + // Row 3 + { "matrix": [2, 0], "x": 0, "y": 2 }, + { "matrix": [2, 1], "x": 1, "y": 2 }, + { "matrix": [2, 2], "x": 2, "y": 2 }, + { "matrix": [2, 3], "x": 3, "y": 2 }, + { "matrix": [2, 4], "x": 4, "y": 2 }, + { "matrix": [2, 5], "x": 5, "y": 2 }, + { "matrix": [2, 6], "x": 6, "y": 2 }, + { "matrix": [2, 7], "x": 7, "y": 2 }, + { "matrix": [2, 8], "x": 8, "y": 2 }, + { "matrix": [2, 9], "x": 9, "y": 2 }, + + // Row 4 + { "matrix": [3, 0], "x": 0, "y": 3 }, + + { "matrix": [3, 2], "x": 2, "y": 3 }, + { "matrix": [3, 3], "x": 3, "y": 3 }, + { "matrix": [3, 4], "x": 4, "y": 3, "w": 2 }, + { "matrix": [3, 6], "x": 6, "y": 3 }, + { "matrix": [3, 7], "x": 7, "y": 3 }, + + { "matrix": [3, 9], "x": 9, "y": 3 } + ] + }, + "LAYOUT_ortho_3x10_8": { + "layout": [ + // Row 1 + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1, "y": 0 }, + { "matrix": [0, 2], "x": 2, "y": 0 }, + { "matrix": [0, 3], "x": 3, "y": 0 }, + { "matrix": [0, 4], "x": 4, "y": 0 }, + { "matrix": [0, 5], "x": 5, "y": 0 }, + { "matrix": [0, 6], "x": 6, "y": 0 }, + { "matrix": [0, 7], "x": 7, "y": 0 }, + { "matrix": [0, 8], "x": 8, "y": 0 }, + { "matrix": [0, 9], "x": 9, "y": 0 }, + + // Row 2 + { "matrix": [1, 0], "x": 0, "y": 1 }, + { "matrix": [1, 1], "x": 1, "y": 1 }, + { "matrix": [1, 2], "x": 2, "y": 1 }, + { "matrix": [1, 3], "x": 3, "y": 1 }, + { "matrix": [1, 4], "x": 4, "y": 1 }, + { "matrix": [1, 5], "x": 5, "y": 1 }, + { "matrix": [1, 6], "x": 6, "y": 1 }, + { "matrix": [1, 7], "x": 7, "y": 1 }, + { "matrix": [1, 8], "x": 8, "y": 1 }, + { "matrix": [1, 9], "x": 9, "y": 1 }, + + // Row 3 + { "matrix": [2, 0], "x": 0, "y": 2 }, + { "matrix": [2, 1], "x": 1, "y": 2 }, + { "matrix": [2, 2], "x": 2, "y": 2 }, + { "matrix": [2, 3], "x": 3, "y": 2 }, + { "matrix": [2, 4], "x": 4, "y": 2 }, + { "matrix": [2, 5], "x": 5, "y": 2 }, + { "matrix": [2, 6], "x": 6, "y": 2 }, + { "matrix": [2, 7], "x": 7, "y": 2 }, + { "matrix": [2, 8], "x": 8, "y": 2 }, + { "matrix": [2, 9], "x": 9, "y": 2 }, + + // Row 4 + { "matrix": [3, 0], "x": 0, "y": 3 }, + + { "matrix": [3, 2], "x": 2, "y": 3 }, + { "matrix": [3, 3], "x": 3, "y": 3 }, + { "matrix": [3, 4], "x": 4, "y": 3 }, + { "matrix": [3, 5], "x": 5, "y": 3 }, + { "matrix": [3, 6], "x": 6, "y": 3 }, + { "matrix": [3, 7], "x": 7, "y": 3 }, + + { "matrix": [3, 9], "x": 9, "y": 3 } + ] + }, + "LAYOUT_ortho_4x10": { + "layout": [ + // Row 1 + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1, "y": 0 }, + { "matrix": [0, 2], "x": 2, "y": 0 }, + { "matrix": [0, 3], "x": 3, "y": 0 }, + { "matrix": [0, 4], "x": 4, "y": 0 }, + { "matrix": [0, 5], "x": 5, "y": 0 }, + { "matrix": [0, 6], "x": 6, "y": 0 }, + { "matrix": [0, 7], "x": 7, "y": 0 }, + { "matrix": [0, 8], "x": 8, "y": 0 }, + { "matrix": [0, 9], "x": 9, "y": 0 }, + + // Row 2 + { "matrix": [1, 0], "x": 0, "y": 1 }, + { "matrix": [1, 1], "x": 1, "y": 1 }, + { "matrix": [1, 2], "x": 2, "y": 1 }, + { "matrix": [1, 3], "x": 3, "y": 1 }, + { "matrix": [1, 4], "x": 4, "y": 1 }, + { "matrix": [1, 5], "x": 5, "y": 1 }, + { "matrix": [1, 6], "x": 6, "y": 1 }, + { "matrix": [1, 7], "x": 7, "y": 1 }, + { "matrix": [1, 8], "x": 8, "y": 1 }, + { "matrix": [1, 9], "x": 9, "y": 1 }, + + // Row 3 + { "matrix": [2, 0], "x": 0, "y": 2 }, + { "matrix": [2, 1], "x": 1, "y": 2 }, + { "matrix": [2, 2], "x": 2, "y": 2 }, + { "matrix": [2, 3], "x": 3, "y": 2 }, + { "matrix": [2, 4], "x": 4, "y": 2 }, + { "matrix": [2, 5], "x": 5, "y": 2 }, + { "matrix": [2, 6], "x": 6, "y": 2 }, + { "matrix": [2, 7], "x": 7, "y": 2 }, + { "matrix": [2, 8], "x": 8, "y": 2 }, + { "matrix": [2, 9], "x": 9, "y": 2 }, + + // Row 4 + { "matrix": [3, 0], "x": 0, "y": 3 }, + { "matrix": [3, 1], "x": 1, "y": 3 }, + { "matrix": [3, 2], "x": 2, "y": 3 }, + { "matrix": [3, 3], "x": 3, "y": 3 }, + { "matrix": [3, 4], "x": 4, "y": 3 }, + { "matrix": [3, 5], "x": 5, "y": 3 }, + { "matrix": [3, 6], "x": 6, "y": 3 }, + { "matrix": [3, 7], "x": 7, "y": 3 }, + { "matrix": [3, 8], "x": 8, "y": 3 }, + { "matrix": [3, 9], "x": 9, "y": 3 } + ] + } + } +} diff --git a/keyboards/handwired/jscotto/scotto40/keymaps/default/config.h b/keyboards/handwired/jscotto/scotto40/keymaps/default/config.h new file mode 100644 index 000000000000..8723c294cb5d --- /dev/null +++ b/keyboards/handwired/jscotto/scotto40/keymaps/default/config.h @@ -0,0 +1,24 @@ +/* +Copyright 2022 Joe Scotto + +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 + +// Define options +#define IGNORE_MOD_TAP_INTERRUPT +#define TAPPING_TERM 135 +#define PERMISSIVE_HOLD +#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c b/keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c new file mode 100644 index 000000000000..adfcdc559c71 --- /dev/null +++ b/keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c @@ -0,0 +1,114 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#include QMK_KEYBOARD_H + +// Tap Dance declarations +enum { + TD_ESC_SPOTLIGHT_EMOJI, + TD_ESC_WINDOWS_EMOJI +}; + +void td_esc_spotlight_emoji (qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + tap_code(KC_ESC); + } else if (state->count == 2) { + tap_code16(G(KC_SPC)); + } else if (state->count == 3) { + tap_code16(C(G(KC_SPC))); + } +} + +void td_esc_windows_emoji (qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + tap_code(KC_ESC); + } else if (state->count == 2) { + tap_code(KC_LGUI); + } else if (state->count == 3) { + tap_code16(G(KC_DOT)); + } +}; + + // Tap Dance definitions +qk_tap_dance_action_t tap_dance_actions[] = { + [TD_ESC_SPOTLIGHT_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_spotlight_emoji), + [TD_ESC_WINDOWS_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_windows_emoji) +}; + +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case TD(TD_ESC_SPOTLIGHT_EMOJI) : + case TD(TD_ESC_WINDOWS_EMOJI) : + case LGUI_T(KC_SPC) : + case LT(1, KC_TAB) : + case LT(2, KC_ENT) : + return 200; + default: + return TAPPING_TERM; + } +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_ortho_3x10_7( + KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, + KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [1] = LAYOUT_ortho_3x10_7( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [2] = LAYOUT_ortho_3x10_7( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [3] = LAYOUT_ortho_3x10_7( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [4] = LAYOUT_ortho_3x10_7( + KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, + KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [5] = LAYOUT_ortho_3x10_7( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [6] = LAYOUT_ortho_3x10_7( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(7), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [7] = LAYOUT_ortho_3x10_7( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(0), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ) +}; diff --git a/keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk b/keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk new file mode 100644 index 000000000000..e5ddcae8d927 --- /dev/null +++ b/keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk @@ -0,0 +1 @@ +TAP_DANCE_ENABLE = yes diff --git a/keyboards/handwired/jscotto/scotto40/readme.md b/keyboards/handwired/jscotto/scotto40/readme.md new file mode 100644 index 000000000000..867313ecfc2b --- /dev/null +++ b/keyboards/handwired/jscotto/scotto40/readme.md @@ -0,0 +1,25 @@ +# Scotto40 + +![Scotto40](https://i.imgur.com/wtW5xOth.jpeg) + +A 37, 38, or 40 key handwired ortholinear keyboard. Case files available [here](https://github.com/joe-scotto/keyboards). + +- Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) +- Hardware Supported: ATmega32U4 +- Hardware Availability: [Amazon](https://amazon.com) + +# Compiling + +Make example for this keyboard (after setting up your build environment): + + make handwired/jscotto/scotto40:default + +Flashing example for this keyboard: + + make handwired/jscotto/scotto40:default + +# Bootloader + +Uses [bootmagic](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_bootmagic.md) allowing you to hold the top left key (0, 0) when plugging the board in to enter bootloader mode. + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/handwired/jscotto/scotto40/rules.mk b/keyboards/handwired/jscotto/scotto40/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/handwired/jscotto/scotto40/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/platforms/chibios/drivers/uart.c b/platforms/chibios/drivers/uart.c index b16130d80b0c..34f77232b6c8 100644 --- a/platforms/chibios/drivers/uart.c +++ b/platforms/chibios/drivers/uart.c @@ -42,8 +42,8 @@ void uart_init(uint32_t baud) { palSetLineMode(SD1_TX_PIN, SD1_TX_PAL_MODE); palSetLineMode(SD1_RX_PIN, SD1_RX_PAL_MODE); #else - palSetLineMode(SD1_TX_PIN, PAL_MODE_ALTERNATE(SD1_TX_PAL_MODE) | PAL_OUTPUT_TYPE_OPENDRAIN); - palSetLineMode(SD1_RX_PIN, PAL_MODE_ALTERNATE(SD1_RX_PAL_MODE) | PAL_OUTPUT_TYPE_OPENDRAIN); + palSetLineMode(SD1_TX_PIN, PAL_MODE_ALTERNATE(SD1_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); + palSetLineMode(SD1_RX_PIN, PAL_MODE_ALTERNATE(SD1_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); #endif sdStart(&SERIAL_DRIVER, &serialConfig); } diff --git a/platforms/chibios/drivers/uart.h b/platforms/chibios/drivers/uart.h index db9784027074..e9e3b0855b3f 100644 --- a/platforms/chibios/drivers/uart.h +++ b/platforms/chibios/drivers/uart.h @@ -42,19 +42,16 @@ #ifdef USE_GPIOV1 # ifndef SD1_TX_PAL_MODE -# define SD1_TX_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# define SD1_TX_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL # endif - # ifndef SD1_RX_PAL_MODE -# define SD1_RX_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# define SD1_RX_PAL_MODE PAL_MODE_INPUT # endif - # ifndef SD1_CTS_PAL_MODE -# define SD1_CTS_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# define SD1_CTS_PAL_MODE PAL_MODE_INPUT # endif - # ifndef SD1_RTS_PAL_MODE -# define SD1_RTS_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# define SD1_RTS_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL # endif #else # ifndef SD1_TX_PAL_MODE diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c index 1529ab9fe2d7..2459ad0df53f 100644 --- a/quantum/keymap_introspection.c +++ b/quantum/keymap_introspection.c @@ -11,44 +11,58 @@ #include "keymap_introspection.h" -#define NUM_KEYMAP_LAYERS ((uint8_t)(sizeof(keymaps) / ((MATRIX_ROWS) * (MATRIX_COLS) * sizeof(uint16_t)))) +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Key mapping -uint8_t keymap_layer_count(void) { - return NUM_KEYMAP_LAYERS; +#define NUM_KEYMAP_LAYERS_RAW ((uint8_t)(sizeof(keymaps) / ((MATRIX_ROWS) * (MATRIX_COLS) * sizeof(uint16_t)))) + +uint8_t keymap_layer_count_raw(void) { + return NUM_KEYMAP_LAYERS_RAW; +} + +__attribute__((weak)) uint8_t keymap_layer_count(void) { + return keymap_layer_count_raw(); } #ifdef DYNAMIC_KEYMAP_ENABLE -_Static_assert(NUM_KEYMAP_LAYERS <= MAX_LAYER, "Number of keymap layers exceeds maximum set by DYNAMIC_KEYMAP_LAYER_COUNT"); +_Static_assert(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by DYNAMIC_KEYMAP_LAYER_COUNT"); #else -_Static_assert(NUM_KEYMAP_LAYERS <= MAX_LAYER, "Number of keymap layers exceeds maximum set by LAYER_STATE_(8|16|32)BIT"); +_Static_assert(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by LAYER_STATE_(8|16|32)BIT"); #endif uint16_t keycode_at_keymap_location_raw(uint8_t layer_num, uint8_t row, uint8_t column) { - if (layer_num < NUM_KEYMAP_LAYERS && row < MATRIX_ROWS && column < MATRIX_COLS) { + if (layer_num < NUM_KEYMAP_LAYERS_RAW && row < MATRIX_ROWS && column < MATRIX_COLS) { return pgm_read_word(&keymaps[layer_num][row][column]); } - return KC_NO; + return KC_TRNS; } __attribute__((weak)) uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column) { return keycode_at_keymap_location_raw(layer_num, row, column); } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Encoder mapping + #if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) -# define NUM_ENCODERMAP_LAYERS ((uint8_t)(sizeof(encoder_map) / ((NUM_ENCODERS) * (2) * sizeof(uint16_t)))) +# define NUM_ENCODERMAP_LAYERS_RAW ((uint8_t)(sizeof(encoder_map) / ((NUM_ENCODERS) * (2) * sizeof(uint16_t)))) + +uint8_t encodermap_layer_count_raw(void) { + return NUM_ENCODERMAP_LAYERS_RAW; +} -uint8_t encodermap_layer_count(void) { - return NUM_ENCODERMAP_LAYERS; +__attribute__((weak)) uint8_t encodermap_layer_count(void) { + return encodermap_layer_count_raw(); } -_Static_assert(NUM_KEYMAP_LAYERS == NUM_ENCODERMAP_LAYERS, "Number of encoder_map layers doesn't match the number of keymap layers"); +_Static_assert(NUM_KEYMAP_LAYERS_RAW == NUM_ENCODERMAP_LAYERS_RAW, "Number of encoder_map layers doesn't match the number of keymap layers"); uint16_t keycode_at_encodermap_location_raw(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) { - if (layer_num < NUM_ENCODERMAP_LAYERS && encoder_idx < NUM_ENCODERS) { + if (layer_num < NUM_ENCODERMAP_LAYERS_RAW && encoder_idx < NUM_ENCODERS) { return pgm_read_word(&encoder_map[layer_num][encoder_idx][clockwise ? 0 : 1]); } - return KC_NO; + return KC_TRNS; } __attribute__((weak)) uint16_t keycode_at_encodermap_location(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) { diff --git a/quantum/keymap_introspection.h b/quantum/keymap_introspection.h index 9de706a02196..a8df3928a619 100644 --- a/quantum/keymap_introspection.h +++ b/quantum/keymap_introspection.h @@ -4,7 +4,12 @@ #include -// Get the number of layers defined in the keymap +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Key mapping + +// Get the number of layers defined in the keymap, stored in firmware rather than any other persistent storage +uint8_t keymap_layer_count_raw(void); +// Get the number of layers defined in the keymap, potentially stored dynamically uint8_t keymap_layer_count(void); // Get the keycode for the keymap location, stored in firmware rather than any other persistent storage @@ -12,9 +17,14 @@ uint16_t keycode_at_keymap_location_raw(uint8_t layer_num, uint8_t row, uint8_t // Get the keycode for the keymap location, potentially stored dynamically uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column); +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Encoder mapping + #if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) -// Get the number of layers defined in the encoder map +// Get the number of layers defined in the encoder map, stored in firmware rather than any other persistent storage +uint8_t encodermap_layer_count_raw(void); +// Get the number of layers defined in the encoder map, potentially stored dynamically uint8_t encodermap_layer_count(void); // Get the keycode for the encoder mapping location, stored in firmware rather than any other persistent storage diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c index c2f2f9b27b83..fb551c518db0 100644 --- a/quantum/pointing_device/pointing_device.c +++ b/quantum/pointing_device/pointing_device.c @@ -383,7 +383,7 @@ static inline mouse_hv_report_t pointing_device_hv_clamp(clamp_hv_range_t value) } /** - * @brief clamps input to mouse_xy_report_t range + * @brief clamps clamp_range_t to mouse_xy_report_t * * @param[in] clamp_xy_range_t value * @return mouse_xy_report_t clamped value diff --git a/quantum/pointing_device/pointing_device_modes.c b/quantum/pointing_device/pointing_device_modes.c index 17f349befe95..ba67ba0b9327 100644 --- a/quantum/pointing_device/pointing_device_modes.c +++ b/quantum/pointing_device/pointing_device_modes.c @@ -20,56 +20,92 @@ /* initialize static functions */ -/* local inline functions from pointing_device.c with int16_t input */ -static inline mouse_hv_report_t pointing_device_hv_clamp(int16_t value) { - if (value < HV_REPORT_MIN) { - return HV_REPORT_MIN; - } else if (value > HV_REPORT_MAX) { - return HV_REPORT_MAX; +static report_mouse_t process_pointing_mode(pointing_mode_t pointing_mode, report_mouse_t mouse_report); +static uint8_t get_pointing_device_direction(void); +static uint8_t get_pointing_mode_divisor(void); +static uint8_t divisor_postprocess(uint8_t divisor); + +// set up context and functions if using two pointing devices +# if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) +/* set up local context for storing current values */ +static context_pointing_mode_t pointing_mode_context = {.config.is_left = POINTING_MODES_LEFT_DEFAULT, .config.tg_mode_id = POINTING_MODE_DEFAULT, .mode.id = POINTING_MODE_DEFAULT, .mode.divisor = POINTING_DEFAULT_DIVISOR}; +# else +static context_pointing_mode_t pointing_mode_context = {.config.tg_mode_id = POINTING_MODE_DEFAULT, .mode.id = POINTING_MODE_DEFAULT, .mode.divisor = POINTING_DEFAULT_DIVISOR}; +# endif + +// set up clamping and divisor application functions +static inline int8_t clamp_int_16_to_8(int16_t value) { + if (value < INT8_MIN) { + return INT8_MIN; + } else if (value > INT8_MAX) { + return INT8_MAX; } else { return value; } } -static inline mouse_xy_report_t pointing_device_xy_clamp(int16_t value) { - if (value < XY_REPORT_MIN) { - return XY_REPORT_MIN; - } else if (value > XY_REPORT_MAX) { - return XY_REPORT_MAX; +static inline int16_t clamp_int_32_to_16(int32_t value) { + if (value < INT16_MIN) { + return INT16_MIN; + } else if (value > INT16_MAX) { + return INT16_MAX; } else { return value; } } -static report_mouse_t process_pointing_mode(pointing_mode_t pointing_mode, report_mouse_t mouse_report); -static uint8_t get_pointing_device_direction(void); -static uint8_t get_pointing_mode_divisor(void); +static inline int16_t divisor_multiply16(int16_t value) { + return clamp_int_32_to_16(value * (int16_t)pointing_mode_context.mode.divisor); +} -// set up context and functions if using two pointing devices -# if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) -/* set up local context for storing current values */ -static context_pointing_mode_t pointing_mode_context = {.config.is_left = POINTING_MODES_LEFT_DEFAULT, .config.tg_mode_id = POINTING_MODE_DEFAULT, .mode.id = POINTING_MODE_DEFAULT, .mode.divisor = POINTING_DEFAULT_DIVISOR}; +static inline int8_t divisor_divide8(int16_t value) { +# ifdef POINTING_DEVICE_MODES_FASTCALC + return clamp_int_16_to_8(value >> pointing_mode_context.mode.divisor); +# else + return clamp_int_16_to_8(value / (int16_t)pointing_mode_context.mode.divisor); +# endif +} -/** - * @brief Check if left side is controlled by pointing mode framework - * - * @return is left side active [bool] - */ -bool is_pointing_mode_on_left(void) { - return pointing_mode_context.config.is_left; +static inline int16_t divisor_divide16(int16_t value) { +# ifdef POINTING_DEVICE_MODES_FASTCALC + return value >> pointing_mode_context.mode.divisor; +# else + return value / (int16_t)pointing_mode_context.mode.divisor; +# endif +} + +static inline int8_t apply_divisor_count(int16_t value) { + return divisor_divide8(value); +} + +static inline int16_t multiply_divisor_count(int8_t value) { + return divisor_multiply16((int16_t)value); } /** - * @brief Allow changing of active side + * @brief local function to get single direction based on h/v * - * will change which side (left/right) is controlled by pointing mode framework + * Determines direction based on axis with largest magnitude + * + * NOTE: Defaults to PD_DOWN + * + * @return direction uint8_t */ -void pointing_mode_switch_hands(void) { - pointing_mode_context.config.is_left ^= 1; +static uint8_t get_pointing_device_direction(void) { + 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.y > 0) { + return PD_UP; + } else { + return PD_DOWN; + } + } } -# else -static context_pointing_mode_t pointing_mode_context = {.config.tg_mode_id = POINTING_MODE_DEFAULT, .mode.id = POINTING_MODE_DEFAULT, .mode.divisor = POINTING_DEFAULT_DIVISOR}; -# endif /** * @brief Reset pointing mode data @@ -91,8 +127,8 @@ void set_pointing_mode(pointing_mode_t pointing_mode) { // skip if same if (!memcmp(&pointing_mode_context.mode, &pointing_mode, sizeof(pointing_mode_t))) return; memcpy(&pointing_mode_context.mode, &pointing_mode, sizeof(pointing_mode_t)); - // dprintf("PM status saved!\n"); - // Prevent zero divisor + dprintf("PM status saved!"); + // Prevent zero divisor if (!pointing_mode_context.mode.divisor) { pointing_mode_context.mode.divisor = POINTING_DEFAULT_DIVISOR; } @@ -116,7 +152,6 @@ void set_pointing_mode_id(uint8_t mode_id) { if (pointing_mode_context.mode.id != mode_id) { pointing_mode_reset(); pointing_mode_context.mode.id = mode_id; - // dprintf("PMID Set: %d\n", mode_id); } } @@ -130,10 +165,8 @@ void set_pointing_mode_id(uint8_t mode_id) { void toggle_pointing_mode_id(uint8_t mode_id) { if (pointing_mode_context.config.tg_mode_id == mode_id) { pointing_mode_context.config.tg_mode_id = POINTING_MODE_DEFAULT; - // dprintf("Toggled PMID: %d\n Off", mode_id); } else { pointing_mode_context.config.tg_mode_id = mode_id; - // dprintf("Toggled PMID: %d\n On", mode_id); } if (pointing_mode_context.mode.id != pointing_mode_context.config.tg_mode_id) pointing_mode_reset(); } @@ -176,28 +209,27 @@ __attribute__((weak)) report_mouse_t pointing_modes_axes_conv(pointing_mode_t po } /** - * @brief local function to get single direction based on h/v + * @brief Modifies divisor after * - * Determines direction based on axis with largest magnitude - * - * NOTE: Defaults to PD_DOWN + * @params pointing_mode[in] uint8_t + * @params direction[in] uint8_t * - * @return direction uint8_t + * @return divisor uint8_t */ -static uint8_t get_pointing_device_direction(void) { - 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.y > 0) { - return PD_UP; - } else { - return PD_DOWN; - } +static uint8_t divisor_postprocess(uint8_t divisor) { + divisor = pointing_mode_divisor_postprocess_kb(divisor); + divisor = pointing_mode_divisor_postprocess_user(divisor); + // Modify divisor if precision is toggled + if (get_toggled_pointing_mode_id() == PM_PRECISION && !(get_pointing_mode_id() == PM_PRECISION)) { + divisor = ((uint16_t)divisor * POINTING_PRECISION_DIVISOR) > UINT8_MAX ? UINT8_MAX : (divisor * POINTING_PRECISION_DIVISOR); } + // Prevent 0 divisor + if (!divisor) divisor = POINTING_DEFAULT_DIVISOR; +# ifdef POINTING_DEVICE_MODES_FASTCALC + // convert to nearest power of 2 + divisor = biton(divisor); +# endif + return divisor; } /** @@ -211,43 +243,50 @@ static uint8_t get_pointing_device_direction(void) { */ static uint8_t get_pointing_mode_divisor(void) { // allow for user and keyboard overrides - uint8_t divisor; - divisor = get_pointing_mode_divisor_user(get_pointing_mode_id(), pointing_mode_context.mode.direction); - if (divisor) return divisor; - divisor = get_pointing_mode_divisor_kb(get_pointing_mode_id(), pointing_mode_context.mode.direction); - if (divisor) return divisor; + uint8_t divisor = 0; - // built in mode divisors - switch (get_pointing_mode_id()) { - case PM_HISTORY: - divisor = POINTING_HISTORY_DIVISOR; - break; + divisor = get_pointing_mode_divisor_user(get_pointing_mode_id(), pointing_mode_context.mode.direction); + if (!divisor) { + divisor = get_pointing_mode_divisor_kb(get_pointing_mode_id(), pointing_mode_context.mode.direction); + } + if (!divisor) { + // built in mode divisors + switch (get_pointing_mode_id()) { + case PM_PRECISION: + divisor = POINTING_PRECISION_DIVISOR; + break; + + case PM_DRAG: + divisor = POINTING_DRAG_DIVISOR_H; + break; + + case PM_CARET: + divisor = pointing_mode_context.mode.direction < PD_LEFT ? POINTING_CARET_DIVISOR_V : POINTING_CARET_DIVISOR_H; + break; + + case PM_HISTORY: + divisor = POINTING_HISTORY_DIVISOR; + break; + + case PM_VOLUME: # ifdef EXTRAKEY_ENABLE - case PM_VOLUME: - divisor = POINTING_VOLUME_DIVISOR; - break; + divisor = POINTING_VOLUME_DIVISOR; # endif - case PM_CARET: - divisor = pointing_mode_context.mode.direction < PD_LEFT ? POINTING_CARET_DIVISOR_V : POINTING_CARET_DIVISOR_H; - break; - - case PM_PRECISION: - divisor = POINTING_PRECISION_DIVISOR; - break; - - case PM_DRAG: - divisor = POINTING_DRAG_DIVISOR; - break; - } - // Modify divisor if precision is toggled - if (get_toggled_pointing_mode_id() == PM_PRECISION && !(get_pointing_mode_id() == PM_PRECISION)) { - divisor = ((uint16_t)divisor * POINTING_PRECISION_DIVISOR) > 255 ? 255 : (divisor * POINTING_PRECISION_DIVISOR); + break; + } } + return divisor_postprocess(divisor); +} - // Prevent 0 divisor - if (!divisor) divisor = POINTING_DEFAULT_DIVISOR; - - return divisor; +/** + * @brief override current divisor value + * + * Will only take effect until next cycle update or next call of this process + * + * @param[in] divisor uint8_t + */ +void pointing_mode_divisor_override(uint8_t divisor) { + pointing_mode_context.mode.divisor = divisor_postprocess(divisor); } /** @@ -261,6 +300,56 @@ void pointing_mode_update(void) { pointing_mode_context.mode.divisor = get_pointing_mode_divisor(); } +/** + * @brief divides/multiplies cursor value by current divisor + * + * @params value[in] int16_t input to divide + * @params multiply[in] bool multiply when true divide when false + * + * @return modified and clamped value int16_t + */ +mouse_xy_report_t apply_divisor_xy(int16_t value) { +# ifdef MOUSE_EXTENDED_REPORT + return divisor_divide16(value); +# else + return divisor_divide8(value); +# endif +} + +/** + * @brief divides scroll value by current divisor + * + * @params value[in] int16_t scroll input to divide + * @params multiply[in] bool multiply when true divide when false + * + * @return modified and clamped value int16_t + */ +int8_t apply_divisor_hv(int16_t value) { + return divisor_divide8(value); +} + +/** + * @brief multiplies value by current divisor to get residuals + * + * @params value[in] int16_t scroll output to multiply + * + * @return modified and clamped value int16_t + */ +int16_t multiply_divisor_hv(int8_t value) { + return divisor_multiply16((int16_t)value); +} + +/** + * @brief multiplies value by current divisor to get residuals + * + * @params value[in] int16_t scroll output to multiply + * + * @return modified and clamped value int16_t + */ +int16_t multiply_divisor_xy(mouse_xy_report_t value) { + return divisor_multiply16((int16_t)value); +} + /** * @brief Tap keycodes based on mode axis values * @@ -277,7 +366,7 @@ void pointing_mode_update(void) { */ void pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint16_t kc_right) { uint16_t kc_direction = 0; - int16_t count = 0; + int8_t count = 0; switch (pointing_mode_context.mode.direction) { case PD_DOWN: @@ -299,22 +388,23 @@ 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.y / (int16_t)pointing_mode_context.mode.divisor; + count = apply_divisor_count(pointing_mode_context.mode.y); if (!count) return; - pointing_mode_context.mode.y -= count * (int16_t)pointing_mode_context.mode.divisor; + pointing_mode_context.mode.y -= multiply_divisor_count(count); pointing_mode_context.mode.x = 0; break; case PD_LEFT ... PD_RIGHT: - count = pointing_mode_context.mode.x / (int16_t)pointing_mode_context.mode.divisor; + count = apply_divisor_count(pointing_mode_context.mode.x); if (!count) return; - pointing_mode_context.mode.x -= count * (int16_t)pointing_mode_context.mode.divisor; + pointing_mode_context.mode.x -= multiply_divisor_count(count); pointing_mode_context.mode.y = 0; break; } // skip if no key (but allow for axes update) if (kc_direction == KC_NO) return; - uint8_t taps = abs(count); + // tap codes (assume that ) + uint8_t taps = abs(count); for (uint8_t i = 0; i < taps; i++) { tap_code16_delay(kc_direction, POINTING_TAP_DELAY); } @@ -354,58 +444,44 @@ 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_START && pointing_mode.id <= (POINTING_MODE_MAP_START + POINTING_MODE_MAP_COUNT - 1)) { - pointing_tap_codes(POINTING_MODE_MAP(pointing_mode.id - POINTING_MODE_MAP_START)); + if (pointing_mode.id >= PM_SAFE_RANGE && pointing_mode.id <= (PM_SAFE_RANGE + POINTING_MODE_MAP_COUNT - 1)) { + pointing_tap_codes(POINTING_MODE_MAP(pointing_mode.id - PM_SAFE_RANGE)); return mouse_report; } # endif switch (pointing_mode.id) { - // drag scroll mode (sets mouse axes to mouse_report h & v with divisor) - case PM_DRAG: -# ifdef MOUSE_SCROLL_HIRES_ENABLE - { - uint8_t cur_divisor = pointing_mode.divisor; - if (MOUSE_SCROLL_MULTIPLIER_RAW_H) { - uint8_t drag_multiplier = MAX(MOUSE_SCROLL_MULTIPLIER_H / cur_divisor, 1); - pointing_mode.x *= (int16_t)drag_multiplier; - pointing_mode.divisor = 1; - } -# endif - mouse_report.h = pointing_device_hv_clamp(pointing_mode.x / (int16_t)pointing_mode.divisor); - pointing_mode.x -= (int16_t)mouse_report.h * (int16_t)pointing_mode.divisor; -# ifdef MOUSE_SCROLL_HIRES_ENABLE - if (MOUSE_SCROLL_MULTIPLIER_RAW_V) { - uint8_t drag_multiplier = MAX(MOUSE_SCROLL_MULTIPLIER_V / cur_divisor, 1); - pointing_mode.y *= (int16_t)drag_multiplier; - pointing_mode.divisor = 1; - } else { - pointing_mode.divisor = cur_divisor; - } - } -# endif - mouse_report.v = pointing_device_hv_clamp(pointing_mode.y / (int16_t)pointing_mode.divisor); - pointing_mode.y -= (int16_t)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_MODES_INVERT_X - mouse_report.x -= pointing_device_xy_clamp(pointing_mode.x / (int16_t)pointing_mode.divisor); - pointing_mode.x += mouse_report.x * (int16_t)pointing_mode.divisor; + mouse_report.x -= apply_divisor_xy(pointing_mode.x); + pointing_mode.x += multiply_divisor_xy(mouse_report.x); # else - mouse_report.x += pointing_device_xy_clamp(pointing_mode.x / (int16_t)pointing_mode.divisor); - pointing_mode.x -= mouse_report.x * (int16_t)pointing_mode.divisor; + mouse_report.x += apply_divisor_xy(pointing_mode.x); + pointing_mode.x -= multiply_divisor_xy(mouse_report.x); # endif # ifdef POINTING_DEVICE_MODES_INVERT_Y - mouse_report.y -= pointing_device_xy_clamp(pointing_mode.y / (int16_t)pointing_mode.divisor); - pointing_mode.y += mouse_report.y * (int16_t)pointing_mode.divisor; + mouse_report.y -= apply_divisor_xy(pointing_mode.y); + pointing_mode.y += multiply_divisor_xy(mouse_report.y); # else - mouse_report.y += pointing_device_xy_clamp(pointing_mode.y / (int16_t)pointing_mode.divisor); - pointing_mode.y -= mouse_report.y * (int16_t)pointing_mode.divisor; + mouse_report.y += apply_divisor_xy(pointing_mode.y); + pointing_mode.y -= multiply_divisor_xy(mouse_report.y); # endif set_pointing_mode(pointing_mode); break; + + // drag scroll mode (sets mouse axes to mouse_report h & v with divisor) + case PM_DRAG: + mouse_report.h = apply_divisor_hv(pointing_mode.x); + pointing_mode.x -= multiply_divisor_hv(mouse_report.h); +# if (POINTING_DRAG_DIVISOR_V != POINTING_DRAG_DIVISOR_H) + pointing_mode_divisor_override(POINTING_DRAG_DIVISOR_V); +# endif + mouse_report.v = apply_divisor_hv(pointing_mode.y); + pointing_mode.y -= multiply_divisor_hv(mouse_report.v); + + 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); @@ -444,6 +520,7 @@ void pointing_mode_key_momentary(uint8_t mode_id, keyrecord_t* record) { if (pointing_mode_context.mode.id == mode_id) pointing_mode_reset(); } } + /** * @brief Handle pointing mode change keypress: Toggle * @@ -550,4 +627,53 @@ __attribute__((weak)) uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint return 0; // continue processing } +/** + * @brief Weak Callback function for keyboard level modifying of divisors before use + * + * allows Modification the divisor after being set by get_pointing_mode_divisor stack before + * handing off to default post processing + * + * @params[in] divisor uint8_t + * + * @return divisor uint8_t + */ +__attribute__((weak)) uint8_t pointing_mode_divisor_postprocess_kb(uint8_t divisor) { + return divisor; +} + +/** + * @brief Weak Callback function for user level modifying of divisors before use + * + * allows Modification the divisor after being set by get_pointing_mode_divisor stack before + * handing off to default post processing + * + * @params pointing_mode[in] uint8_t + * @params direction[in] uint8_t + * + * @return divisor uint8_t + */ +__attribute__((weak)) uint8_t pointing_mode_divisor_postprocess_user(uint8_t divisor) { + return divisor; +} + +# if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) +/** + * @brief Check if left side is controlled by pointing mode framework + * + * @return is left side active [bool] + */ +bool is_pointing_mode_on_left(void) { + return pointing_mode_context.config.is_left; +} + +/** + * @brief Allow changing of active side + * + * will change which side (left/right) is controlled by pointing mode framework + */ +void pointing_mode_switch_hands(void) { + pointing_mode_context.config.is_left ^= 1; +} +# endif + #endif // POINTING_DEVICE_MODES_ENABLE diff --git a/quantum/pointing_device/pointing_device_modes.h b/quantum/pointing_device/pointing_device_modes.h index 5dd02a6d6f1c..992953c76f22 100644 --- a/quantum/pointing_device/pointing_device_modes.h +++ b/quantum/pointing_device/pointing_device_modes.h @@ -63,11 +63,13 @@ # define POINTING_PRECISION_DIVISOR 2 #endif #ifndef POINTING_DRAG_DIVISOR -# ifdef MOUSE_SCROLL_HIRES_ENABLE -# define POINTING_DRAG_DIVISOR 8 -# else -# define POINTING_DRAG_DIVISOR 4 -# endif +# define POINTING_DRAG_DIVISOR 4 +#endif +#ifndef POINTING_DRAG_DIVISOR_H +# define POINTING_DRAG_DIVISOR_H POINTING_DRAG_DIVISOR +#endif +#ifndef POINTING_DRAG_DIVISOR_V +# define POINTING_DRAG_DIVISOR_V POINTING_DRAG_DIVISOR #endif /* error checking */ @@ -87,8 +89,8 @@ #define POINTING_MODE_TG (POINTING_MODE_MO_MAX + 1) #define POINTING_MODE_TG_MAX QK_POINTING_MODE_MAX -/* enum of directions */ -enum { PD_DOWN = 0, PD_UP, PD_LEFT, PD_RIGHT }; +/* enum typedefs */ +enum pointing_device_directions { PD_DOWN = 0, PD_UP, PD_LEFT, PD_RIGHT }; /* local data structures */ /* pointing mode structure for tracking mode data */ @@ -125,9 +127,13 @@ void pointing_mode_key_momentary(uint8_t mode_id, keyrecord_t* record); // momen void pointing_mode_key_toggle(uint8_t mode_id, keyrecord_t* record); // toggle pointing mode on/off on keypress /* ----------For custom pointing modes---------------------------------------------------------------------------- */ -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, h, v -void pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint16_t kc_right); // turn h/v axis values into keycode taps +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 limit value to x/y range +int8_t apply_divisor_hv(int16_t value); // divide value by current divisor and limit value 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 mouse h/v value by current divisor +void pointing_tap_codes(uint16_t kc_left, uint16_t kc_down, uint16_t kc_up, uint16_t kc_right); // turn pointing_mode x/y values into keycode taps /* ----------For multiple pointing devices------------------------------------------------------------------------ */ #if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) @@ -136,27 +142,24 @@ void pointing_mode_switch_hands(void); // change witch hand is active on pointin #endif /* ----------Callbacks for modifying and adding pointing modes---------------------------------------------------- */ -bool process_pointing_mode_kb(pointing_mode_t pointing_mode, report_mouse_t* mouse_report); -bool process_pointing_mode_user(pointing_mode_t pointing_mode, report_mouse_t* mouse_report); +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 pointing device mode divisors--------------------------------------------------- */ -uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint8_t direction); -uint8_t get_pointing_mode_divisor_user(uint8_t mode_id, uint8_t direction); +/* ----------Callbacks for adding/modifying pointing device mode divisors----------------------------------------- */ +uint8_t get_pointing_mode_divisor_kb(uint8_t mode_id, uint8_t direction); // adding divisors at keyboard level +uint8_t get_pointing_mode_divisor_user(uint8_t mode_id, uint8_t direction); // adding divisors at user/keymap level +uint8_t pointing_mode_divisor_postprocess_kb(uint8_t divisor); // modifying divisors at keyboard level +uint8_t pointing_mode_divisor_postprocess_user(uint8_t divisor); // modifying divisors at user/keymap level +void pointing_mode_divisor_override(uint8_t divisor); // Override current divisor until next update /* ----------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) bool process_pointing_mode_records(uint16_t keyrecord, keyrecord_t* record); // handle processing of built in keyrecords (in process_record stack) /* ----------Pointing Device mode Mapping------------------------------------------------------------------------- */ -#ifndef POINTING_MODE_MAP_COUNT +#if (!defined(POINTING_MODE_MAP_COUNT) || POINTING_MODE_MAP_COUNT <= 0) # 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 +#else # 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 4ef24fdda62a..ec72a93d0f2e 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -231,13 +231,17 @@ // Default Pointing device pointing modes enum pointing_device_mode_list { PM_NONE, - PM_DRAG, PM_PRECISION, + PM_DRAG, PM_CARET, PM_HISTORY, PM_VOLUME, - // safe range for custom modes with built in keycodes +// safe range for custom modes with built in keycodes +#ifndef EXTRAKEY_ENABLE + PM_SAFE_RANGE = PM_VOLUME, +#else PM_SAFE_RANGE, +#endif // safe range for custom modes requiring custom activation/new keycodes PM_SAFE_RANGE_ADV = QK_POINTING_MODE_MAX - QK_POINTING_MODE + 1 };