action_util.c (15633B)
1 /* 2 Copyright 2013 Jun Wako <wakojun@gmail.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 #include "host.h" 18 #include "report.h" 19 #include "debug.h" 20 #include "action_util.h" 21 #include "action_layer.h" 22 #include "action_tapping.h" 23 #include "timer.h" 24 #include "keycode_config.h" 25 #include <string.h> 26 27 extern keymap_config_t keymap_config; 28 29 static uint8_t real_mods = 0; 30 static uint8_t weak_mods = 0; 31 #ifdef KEY_OVERRIDE_ENABLE 32 static uint8_t weak_override_mods = 0; 33 static uint8_t suppressed_mods = 0; 34 #endif 35 36 // TODO: pointer variable is not needed 37 // report_keyboard_t keyboard_report = {}; 38 report_keyboard_t *keyboard_report = &(report_keyboard_t){}; 39 #ifdef NKRO_ENABLE 40 report_nkro_t *nkro_report = &(report_nkro_t){}; 41 #endif 42 43 extern inline void add_key(uint8_t key); 44 extern inline void del_key(uint8_t key); 45 extern inline void clear_keys(void); 46 47 #ifndef NO_ACTION_ONESHOT 48 static uint8_t oneshot_mods = 0; 49 static uint8_t oneshot_locked_mods = 0; 50 /** 51 * @brief Retrieve current state of locked oneshot modifiers. 52 * 53 * @return Current state of the locked oneshot modifier keys as a bitmask. 54 */ 55 uint8_t get_oneshot_locked_mods(void) { 56 return oneshot_locked_mods; 57 } 58 /** 59 * Same as \ref get_oneshot_locked_mods but returns \ref mod_t for convenience. 60 */ 61 mod_t get_oneshot_locked_mod_state(void) { 62 return (mod_t)get_oneshot_locked_mods(); 63 } 64 void add_oneshot_locked_mods(uint8_t mods) { 65 if ((oneshot_locked_mods & mods) != mods) { 66 oneshot_locked_mods |= mods; 67 oneshot_locked_mods_changed_kb(oneshot_locked_mods); 68 } 69 } 70 void set_oneshot_locked_mods(uint8_t mods) { 71 if (mods != oneshot_locked_mods) { 72 oneshot_locked_mods = mods; 73 oneshot_locked_mods_changed_kb(oneshot_locked_mods); 74 } 75 } 76 void clear_oneshot_locked_mods(void) { 77 if (oneshot_locked_mods) { 78 oneshot_locked_mods = 0; 79 oneshot_locked_mods_changed_kb(oneshot_locked_mods); 80 } 81 } 82 void del_oneshot_locked_mods(uint8_t mods) { 83 if (oneshot_locked_mods & mods) { 84 oneshot_locked_mods &= ~mods; 85 oneshot_locked_mods_changed_kb(oneshot_locked_mods); 86 } 87 } 88 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 89 static uint16_t oneshot_time = 0; 90 bool has_oneshot_mods_timed_out(void) { 91 return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; 92 } 93 # else 94 bool has_oneshot_mods_timed_out(void) { 95 return false; 96 } 97 # endif 98 #endif 99 100 /* oneshot layer */ 101 #ifndef NO_ACTION_ONESHOT 102 /** \brief oneshot_layer_data bits 103 * LLLL LSSS 104 * where: 105 * L => are layer bits 106 * S => oneshot state bits 107 */ 108 static uint8_t oneshot_layer_data = 0; 109 110 inline uint8_t get_oneshot_layer(void) { 111 return oneshot_layer_data >> 3; 112 } 113 inline uint8_t get_oneshot_layer_state(void) { 114 return oneshot_layer_data & 0b111; 115 } 116 117 # ifdef SWAP_HANDS_ENABLE 118 enum { 119 SHO_OFF, 120 SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet 121 SHO_PRESSED, // Swap hands button is currently pressed 122 SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys 123 } swap_hands_oneshot = SHO_OFF; 124 # endif 125 126 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 127 static uint16_t oneshot_layer_time = 0; 128 inline bool has_oneshot_layer_timed_out(void) { 129 return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); 130 } 131 # ifdef SWAP_HANDS_ENABLE 132 static uint16_t oneshot_swaphands_time = 0; 133 inline bool has_oneshot_swaphands_timed_out(void) { 134 return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE); 135 } 136 # endif 137 # endif 138 139 # ifdef SWAP_HANDS_ENABLE 140 141 void set_oneshot_swaphands(void) { 142 swap_hands_oneshot = SHO_PRESSED; 143 swap_hands = true; 144 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 145 oneshot_swaphands_time = timer_read(); 146 if (oneshot_layer_time != 0) { 147 oneshot_layer_time = oneshot_swaphands_time; 148 } 149 # endif 150 } 151 152 void release_oneshot_swaphands(void) { 153 if (swap_hands_oneshot == SHO_PRESSED) { 154 swap_hands_oneshot = SHO_ACTIVE; 155 } 156 if (swap_hands_oneshot == SHO_USED) { 157 clear_oneshot_swaphands(); 158 } 159 } 160 161 void use_oneshot_swaphands(void) { 162 if (swap_hands_oneshot == SHO_PRESSED) { 163 swap_hands_oneshot = SHO_USED; 164 } 165 if (swap_hands_oneshot == SHO_ACTIVE) { 166 clear_oneshot_swaphands(); 167 } 168 } 169 170 void clear_oneshot_swaphands(void) { 171 swap_hands_oneshot = SHO_OFF; 172 swap_hands = false; 173 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 174 oneshot_swaphands_time = 0; 175 # endif 176 } 177 178 # endif 179 180 /** \brief Set oneshot layer 181 * 182 * FIXME: needs doc 183 */ 184 void set_oneshot_layer(uint8_t layer, uint8_t state) { 185 if (keymap_config.oneshot_enable) { 186 oneshot_layer_data = layer << 3 | state; 187 layer_on(layer); 188 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 189 oneshot_layer_time = timer_read(); 190 # endif 191 oneshot_layer_changed_kb(get_oneshot_layer()); 192 } else { 193 layer_on(layer); 194 } 195 } 196 /** \brief Reset oneshot layer 197 * 198 * FIXME: needs doc 199 */ 200 void reset_oneshot_layer(void) { 201 oneshot_layer_data = 0; 202 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 203 oneshot_layer_time = 0; 204 # endif 205 oneshot_layer_changed_kb(get_oneshot_layer()); 206 } 207 /** \brief Clear oneshot layer 208 * 209 * FIXME: needs doc 210 */ 211 void clear_oneshot_layer_state(oneshot_fullfillment_t state) { 212 uint8_t start_state = oneshot_layer_data; 213 oneshot_layer_data &= ~state; 214 if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) && keymap_config.oneshot_enable) { 215 layer_off(get_oneshot_layer()); 216 reset_oneshot_layer(); 217 } 218 } 219 /** \brief Is oneshot layer active 220 * 221 * FIXME: needs doc 222 */ 223 bool is_oneshot_layer_active(void) { 224 return get_oneshot_layer_state(); 225 } 226 227 /** \brief set oneshot 228 * 229 * FIXME: needs doc 230 */ 231 void oneshot_set(bool active) { 232 if (keymap_config.oneshot_enable != active) { 233 keymap_config.oneshot_enable = active; 234 eeconfig_update_keymap(&keymap_config); 235 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 236 dprintf("Oneshot: active: %d\n", active); 237 } 238 } 239 240 /** \brief toggle oneshot 241 * 242 * FIXME: needs doc 243 */ 244 void oneshot_toggle(void) { 245 oneshot_set(!keymap_config.oneshot_enable); 246 } 247 248 /** \brief enable oneshot 249 * 250 * FIXME: needs doc 251 */ 252 void oneshot_enable(void) { 253 oneshot_set(true); 254 } 255 256 /** \brief disable oneshot 257 * 258 * FIXME: needs doc 259 */ 260 void oneshot_disable(void) { 261 oneshot_set(false); 262 } 263 264 bool is_oneshot_enabled(void) { 265 return keymap_config.oneshot_enable; 266 } 267 268 #endif 269 270 static uint8_t get_mods_for_report(void) { 271 uint8_t mods = real_mods | weak_mods; 272 273 #ifndef NO_ACTION_ONESHOT 274 if (oneshot_mods) { 275 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 276 if (has_oneshot_mods_timed_out()) { 277 dprintf("Oneshot: timeout\n"); 278 clear_oneshot_mods(); 279 } 280 # endif 281 mods |= oneshot_mods; 282 if (has_anykey()) { 283 clear_oneshot_mods(); 284 } 285 } 286 #endif 287 288 #ifdef SPECULATIVE_HOLD 289 mods |= get_speculative_mods(); 290 #endif 291 292 #ifdef KEY_OVERRIDE_ENABLE 293 // These need to be last to be able to properly control key overrides 294 mods &= ~suppressed_mods; 295 mods |= weak_override_mods; 296 #endif 297 298 return mods; 299 } 300 301 void send_6kro_report(void) { 302 keyboard_report->mods = get_mods_for_report(); 303 304 #ifdef PROTOCOL_VUSB 305 host_keyboard_send(keyboard_report); 306 #else 307 static report_keyboard_t last_report; 308 309 /* Only send the report if there are changes to propagate to the host. */ 310 if (memcmp(keyboard_report, &last_report, sizeof(report_keyboard_t)) != 0) { 311 memcpy(&last_report, keyboard_report, sizeof(report_keyboard_t)); 312 host_keyboard_send(keyboard_report); 313 } 314 #endif 315 } 316 317 #ifdef NKRO_ENABLE 318 void send_nkro_report(void) { 319 nkro_report->mods = get_mods_for_report(); 320 321 static report_nkro_t last_report; 322 323 /* Only send the report if there are changes to propagate to the host. */ 324 if (memcmp(nkro_report, &last_report, sizeof(report_nkro_t)) != 0) { 325 memcpy(&last_report, nkro_report, sizeof(report_nkro_t)); 326 host_nkro_send(nkro_report); 327 } 328 } 329 #endif 330 331 /** \brief Send keyboard report 332 * 333 * FIXME: needs doc 334 */ 335 void send_keyboard_report(void) { 336 #ifdef NKRO_ENABLE 337 if (host_can_send_nkro() && keymap_config.nkro) { 338 send_nkro_report(); 339 return; 340 } 341 #endif 342 send_6kro_report(); 343 } 344 345 /** 346 * @brief Retrieve current state of modifiers. 347 * 348 * @return Current state of the modifier keys as a bitmask. 349 */ 350 uint8_t get_mods(void) { 351 return real_mods; 352 } 353 /** 354 * Same as \ref get_mods but returns \ref mod_t for convenience. 355 */ 356 mod_t get_mod_state(void) { 357 return (mod_t)get_mods(); 358 } 359 /** \brief add mods 360 * 361 * FIXME: needs doc 362 */ 363 void add_mods(uint8_t mods) { 364 real_mods |= mods; 365 } 366 /** \brief del mods 367 * 368 * FIXME: needs doc 369 */ 370 void del_mods(uint8_t mods) { 371 real_mods &= ~mods; 372 } 373 /** \brief set mods 374 * 375 * FIXME: needs doc 376 */ 377 void set_mods(uint8_t mods) { 378 real_mods = mods; 379 } 380 /** \brief clear mods 381 * 382 * FIXME: needs doc 383 */ 384 void clear_mods(void) { 385 real_mods = 0; 386 } 387 388 /** 389 * @brief Retrieve current state of weak modifiers. 390 * 391 * @return Current state of the weak modifier keys as a bitmask. 392 */ 393 uint8_t get_weak_mods(void) { 394 return weak_mods; 395 } 396 /** 397 * Same as \ref get_weak_mods but returns \ref mod_t for convenience. 398 */ 399 mod_t get_weak_mod_state(void) { 400 return (mod_t)get_weak_mods(); 401 } 402 /** \brief add weak mods 403 * 404 * FIXME: needs doc 405 */ 406 void add_weak_mods(uint8_t mods) { 407 weak_mods |= mods; 408 } 409 /** \brief del weak mods 410 * 411 * FIXME: needs doc 412 */ 413 void del_weak_mods(uint8_t mods) { 414 weak_mods &= ~mods; 415 } 416 /** \brief set weak mods 417 * 418 * FIXME: needs doc 419 */ 420 void set_weak_mods(uint8_t mods) { 421 weak_mods = mods; 422 } 423 /** \brief clear weak mods 424 * 425 * FIXME: needs doc 426 */ 427 void clear_weak_mods(void) { 428 weak_mods = 0; 429 } 430 431 #ifdef KEY_OVERRIDE_ENABLE 432 /** \brief set weak mods used by key overrides. DO not call this manually 433 */ 434 void set_weak_override_mods(uint8_t mods) { 435 weak_override_mods = mods; 436 } 437 /** \brief clear weak mods used by key overrides. DO not call this manually 438 */ 439 void clear_weak_override_mods(void) { 440 weak_override_mods = 0; 441 } 442 443 /** \brief set suppressed mods used by key overrides. DO not call this manually 444 */ 445 void set_suppressed_override_mods(uint8_t mods) { 446 suppressed_mods = mods; 447 } 448 /** \brief clear suppressed mods used by key overrides. DO not call this manually 449 */ 450 void clear_suppressed_override_mods(void) { 451 suppressed_mods = 0; 452 } 453 #endif 454 455 #ifndef NO_ACTION_ONESHOT 456 /** 457 * @brief Retrieve current state of oneshot modifiers. 458 * 459 * @return Current state of the oneshot modifier keys as a bitmask. 460 */ 461 uint8_t get_oneshot_mods(void) { 462 return oneshot_mods; 463 } 464 465 /** 466 * Same as \ref get_oneshot_mods but returns \ref mod_t for convenience. 467 */ 468 mod_t get_oneshot_mod_state(void) { 469 return (mod_t)get_oneshot_mods(); 470 } 471 472 void add_oneshot_mods(uint8_t mods) { 473 if ((oneshot_mods & mods) != mods) { 474 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 475 oneshot_time = timer_read(); 476 # endif 477 oneshot_mods |= mods; 478 oneshot_mods_changed_kb(mods); 479 } 480 } 481 482 void del_oneshot_mods(uint8_t mods) { 483 if (oneshot_mods & mods) { 484 oneshot_mods &= ~mods; 485 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 486 oneshot_time = oneshot_mods ? timer_read() : 0; 487 # endif 488 oneshot_mods_changed_kb(oneshot_mods); 489 } 490 } 491 492 /** \brief set oneshot mods 493 * 494 * FIXME: needs doc 495 */ 496 void set_oneshot_mods(uint8_t mods) { 497 if (keymap_config.oneshot_enable) { 498 if (oneshot_mods != mods) { 499 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 500 oneshot_time = timer_read(); 501 # endif 502 oneshot_mods = mods; 503 oneshot_mods_changed_kb(mods); 504 } 505 } 506 } 507 508 /** \brief clear oneshot mods 509 * 510 * FIXME: needs doc 511 */ 512 void clear_oneshot_mods(void) { 513 if (oneshot_mods) { 514 oneshot_mods = 0; 515 # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 516 oneshot_time = 0; 517 # endif 518 oneshot_mods_changed_kb(oneshot_mods); 519 } 520 } 521 #endif 522 523 /** \brief Called when the one shot modifiers have been changed. 524 * 525 * \param mods Contains the active modifiers active after the change. 526 */ 527 __attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {} 528 529 /** \brief Called when the locked one shot modifiers have been changed. 530 * 531 * \param mods Contains the active modifiers active after the change. 532 */ 533 __attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) { 534 oneshot_locked_mods_changed_user(mods); 535 } 536 537 /** \brief Called when the one shot modifiers have been changed. 538 * 539 * \param mods Contains the active modifiers active after the change. 540 */ 541 __attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {} 542 543 /** \brief Called when the one shot modifiers have been changed. 544 * 545 * \param mods Contains the active modifiers active after the change. 546 */ 547 __attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) { 548 oneshot_mods_changed_user(mods); 549 } 550 551 /** \brief Called when the one shot layers have been changed. 552 * 553 * \param layer Contains the layer that is toggled on, or zero when toggled off. 554 */ 555 __attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {} 556 557 /** \brief Called when the one shot layers have been changed. 558 * 559 * \param layer Contains the layer that is toggled on, or zero when toggled off. 560 */ 561 __attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) { 562 oneshot_layer_changed_user(layer); 563 } 564 565 /** \brief inspect keyboard state 566 * 567 * FIXME: needs doc 568 */ 569 uint8_t has_anymod(void) { 570 return bitpop(real_mods); 571 } 572 573 #ifdef DUMMY_MOD_NEUTRALIZER_KEYCODE 574 /** \brief Send a dummy keycode in between the register and unregister event of a modifier key, to neutralize the "flashing modifiers" phenomenon. 575 * 576 * \param active_mods 8-bit packed bit-array describing the currently active modifiers (in the format GASCGASC). 577 * 578 * Certain QMK features like key overrides or retro tap must unregister a previously 579 * registered modifier before sending another keycode but this can trigger undesired 580 * keyboard shortcuts if the clean tap of a single modifier key is bound to an action 581 * on the host OS, as is for example the case for the left GUI key on Windows, which 582 * opens the Start Menu when tapped. 583 */ 584 void neutralize_flashing_modifiers(uint8_t active_mods) { 585 // In most scenarios, the flashing modifiers phenomenon is a problem 586 // only for a subset of modifier masks. 587 const static uint8_t mods_to_neutralize[] = MODS_TO_NEUTRALIZE; 588 const static uint8_t n_mods = ARRAY_SIZE(mods_to_neutralize); 589 for (uint8_t i = 0; i < n_mods; ++i) { 590 if (active_mods == mods_to_neutralize[i]) { 591 tap_code(DUMMY_MOD_NEUTRALIZER_KEYCODE); 592 break; 593 } 594 } 595 } 596 #endif