logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

action.c (44197B)


  1. /*
  2. Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <limits.h>
  15. #include "host.h"
  16. #include "keycode.h"
  17. #include "keyboard.h"
  18. #include "mousekey.h"
  19. #include "programmable_button.h"
  20. #include "command.h"
  21. #include "led.h"
  22. #include "action_layer.h"
  23. #include "action_tapping.h"
  24. #include "action_util.h"
  25. #include "action.h"
  26. #include "wait.h"
  27. #include "keycode_config.h"
  28. #include "debug.h"
  29. #include "quantum.h"
  30. #ifdef BACKLIGHT_ENABLE
  31. # include "backlight.h"
  32. #endif
  33. #ifdef POINTING_DEVICE_ENABLE
  34. # include "pointing_device.h"
  35. #endif
  36. #if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) && defined(SWAP_HANDS_ENABLE)
  37. # include "encoder.h"
  38. #endif
  39. int tp_buttons;
  40. #if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  41. bool retro_tap_primed = false;
  42. uint16_t retro_tap_curr_key = 0;
  43. # if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  44. uint8_t retro_tap_curr_mods = 0;
  45. uint8_t retro_tap_next_mods = 0;
  46. # endif
  47. #endif
  48. #if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
  49. # include "process_auto_shift.h"
  50. #endif
  51. #ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
  52. __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
  53. return false;
  54. }
  55. #endif
  56. #ifdef RETRO_TAPPING_PER_KEY
  57. __attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) {
  58. return false;
  59. }
  60. #endif
  61. /** \brief Called to execute an action.
  62. *
  63. * FIXME: Needs documentation.
  64. */
  65. void action_exec(keyevent_t event) {
  66. if (IS_EVENT(event)) {
  67. ac_dprintf("\n---- action_exec: start -----\n");
  68. ac_dprintf("EVENT: ");
  69. debug_event(event);
  70. ac_dprintf("\n");
  71. #if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  72. uint16_t event_keycode = get_event_keycode(event, false);
  73. if (event.pressed) {
  74. retro_tap_primed = false;
  75. retro_tap_curr_key = event_keycode;
  76. } else if (retro_tap_curr_key == event_keycode) {
  77. retro_tap_primed = true;
  78. }
  79. #endif
  80. }
  81. if (event.pressed) {
  82. // clear the potential weak mods left by previously pressed keys
  83. clear_weak_mods();
  84. }
  85. #ifdef SWAP_HANDS_ENABLE
  86. // Swap hands handles both keys and encoders, if ENCODER_MAP_ENABLE is defined.
  87. if (IS_EVENT(event)) {
  88. process_hand_swap(&event);
  89. }
  90. #endif
  91. keyrecord_t record = {.event = event};
  92. #ifndef NO_ACTION_ONESHOT
  93. if (keymap_config.oneshot_enable) {
  94. # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  95. if (has_oneshot_layer_timed_out()) {
  96. clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
  97. }
  98. if (has_oneshot_mods_timed_out()) {
  99. clear_oneshot_mods();
  100. }
  101. # ifdef SWAP_HANDS_ENABLE
  102. if (has_oneshot_swaphands_timed_out()) {
  103. clear_oneshot_swaphands();
  104. }
  105. # endif
  106. # endif
  107. }
  108. #endif
  109. #ifndef NO_ACTION_TAPPING
  110. # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
  111. if (event.pressed) {
  112. retroshift_poll_time(&event);
  113. }
  114. # endif
  115. if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) {
  116. action_tapping_process(record);
  117. }
  118. #else
  119. if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) {
  120. process_record(&record);
  121. }
  122. if (IS_EVENT(record.event)) {
  123. ac_dprintf("processed: ");
  124. debug_record(record);
  125. dprintln();
  126. }
  127. #endif
  128. }
  129. #ifdef SWAP_HANDS_ENABLE
  130. extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS];
  131. # ifdef ENCODER_MAP_ENABLE
  132. extern const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS];
  133. # endif // ENCODER_MAP_ENABLE
  134. bool swap_hands = false;
  135. bool swap_held = false;
  136. bool should_swap_hands(size_t index, uint8_t *swap_state, bool pressed) {
  137. size_t array_index = index / (CHAR_BIT);
  138. size_t bit_index = index % (CHAR_BIT);
  139. uint8_t bit_val = 1 << bit_index;
  140. bool do_swap = pressed ? swap_hands : swap_state[array_index] & bit_val;
  141. return do_swap;
  142. }
  143. void set_swap_hands_state(size_t index, uint8_t *swap_state, bool on) {
  144. size_t array_index = index / (CHAR_BIT);
  145. size_t bit_index = index % (CHAR_BIT);
  146. uint8_t bit_val = 1 << bit_index;
  147. if (on) {
  148. swap_state[array_index] |= bit_val;
  149. } else {
  150. swap_state[array_index] &= ~bit_val;
  151. }
  152. }
  153. void swap_hands_on(void) {
  154. swap_hands = true;
  155. }
  156. void swap_hands_off(void) {
  157. swap_hands = false;
  158. }
  159. void swap_hands_toggle(void) {
  160. swap_hands = !swap_hands;
  161. }
  162. bool is_swap_hands_on(void) {
  163. return swap_hands;
  164. }
  165. /** \brief Process Hand Swap
  166. *
  167. * FIXME: Needs documentation.
  168. */
  169. void process_hand_swap(keyevent_t *event) {
  170. keypos_t pos = event->key;
  171. if (IS_KEYEVENT(*event) && pos.row < MATRIX_ROWS && pos.col < MATRIX_COLS) {
  172. static uint8_t matrix_swap_state[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)];
  173. size_t index = (size_t)(pos.row * MATRIX_COLS) + pos.col;
  174. bool do_swap = should_swap_hands(index, matrix_swap_state, event->pressed);
  175. if (do_swap) {
  176. event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row);
  177. event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col);
  178. set_swap_hands_state(index, matrix_swap_state, true);
  179. } else {
  180. set_swap_hands_state(index, matrix_swap_state, false);
  181. }
  182. }
  183. # ifdef ENCODER_MAP_ENABLE
  184. else if (IS_ENCODEREVENT(*event) && (pos.row == KEYLOC_ENCODER_CW || pos.row == KEYLOC_ENCODER_CCW)) {
  185. static uint8_t encoder_swap_state[((NUM_ENCODERS) + (CHAR_BIT)-1) / (CHAR_BIT)];
  186. size_t index = pos.col;
  187. bool do_swap = should_swap_hands(index, encoder_swap_state, event->pressed);
  188. if (do_swap) {
  189. event->key.row = pos.row;
  190. event->key.col = pgm_read_byte(&encoder_hand_swap_config[pos.col]);
  191. set_swap_hands_state(index, encoder_swap_state, true);
  192. } else {
  193. set_swap_hands_state(index, encoder_swap_state, false);
  194. }
  195. }
  196. # endif // ENCODER_MAP_ENABLE
  197. }
  198. #endif
  199. #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
  200. bool disable_action_cache = false;
  201. void process_record_nocache(keyrecord_t *record) {
  202. disable_action_cache = true;
  203. process_record(record);
  204. disable_action_cache = false;
  205. }
  206. #else
  207. void process_record_nocache(keyrecord_t *record) {
  208. process_record(record);
  209. }
  210. #endif
  211. __attribute__((weak)) bool process_record_quantum(keyrecord_t *record) {
  212. return true;
  213. }
  214. __attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {}
  215. #ifndef NO_ACTION_TAPPING
  216. /** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress.
  217. *
  218. * FIXME: Needs documentation.
  219. */
  220. void process_record_tap_hint(keyrecord_t *record) {
  221. if (!IS_KEYEVENT(record->event)) {
  222. return;
  223. }
  224. action_t action = layer_switch_get_action(record->event.key);
  225. switch (action.kind.id) {
  226. # ifdef SWAP_HANDS_ENABLE
  227. case ACT_SWAP_HANDS:
  228. switch (action.swap.code) {
  229. case OP_SH_ONESHOT:
  230. break;
  231. case OP_SH_TAP_TOGGLE:
  232. default:
  233. swap_hands = !swap_hands;
  234. swap_held = true;
  235. }
  236. break;
  237. # endif
  238. }
  239. }
  240. #endif
  241. /** \brief Take a key event (key press or key release) and processes it.
  242. *
  243. * FIXME: Needs documentation.
  244. */
  245. void process_record(keyrecord_t *record) {
  246. if (IS_NOEVENT(record->event)) {
  247. return;
  248. }
  249. #ifdef FLOW_TAP_TERM
  250. flow_tap_update_last_event(record);
  251. #endif // FLOW_TAP_TERM
  252. if (!process_record_quantum(record)) {
  253. #ifndef NO_ACTION_ONESHOT
  254. if (is_oneshot_layer_active() && record->event.pressed && keymap_config.oneshot_enable) {
  255. clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
  256. }
  257. #endif
  258. return;
  259. }
  260. process_record_handler(record);
  261. post_process_record_quantum(record);
  262. }
  263. void process_record_handler(keyrecord_t *record) {
  264. #if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE)
  265. action_t action;
  266. if (record->keycode) {
  267. action = action_for_keycode(record->keycode);
  268. } else {
  269. action = store_or_get_action(record->event.pressed, record->event.key);
  270. }
  271. #else
  272. action_t action = store_or_get_action(record->event.pressed, record->event.key);
  273. #endif
  274. ac_dprintf("ACTION: ");
  275. debug_action(action);
  276. #ifndef NO_ACTION_LAYER
  277. ac_dprintf(" layer_state: ");
  278. layer_debug();
  279. ac_dprintf(" default_layer_state: ");
  280. default_layer_debug();
  281. #endif
  282. ac_dprintf("\n");
  283. process_action(record, action);
  284. }
  285. /**
  286. * @brief handles all the messy mouse stuff
  287. *
  288. * Handles all the edgecases and special stuff that is needed for coexistense
  289. * of the multiple mouse subsystems.
  290. *
  291. * @param mouse_keycode[in] uint8_t mouse keycode
  292. * @param pressed[in] bool
  293. */
  294. void register_mouse(uint8_t mouse_keycode, bool pressed) {
  295. #ifdef MOUSEKEY_ENABLE
  296. // if mousekeys is enabled, let it do the brunt of the work
  297. if (pressed) {
  298. mousekey_on(mouse_keycode);
  299. } else {
  300. mousekey_off(mouse_keycode);
  301. }
  302. // should mousekeys send report, or does something else handle this?
  303. switch (mouse_keycode) {
  304. # if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
  305. case QK_MOUSE_BUTTON_1 ... QK_MOUSE_BUTTON_8:
  306. // let pointing device handle the buttons
  307. // expand if/when it handles more of the code
  308. # if defined(POINTING_DEVICE_ENABLE)
  309. pointing_device_keycode_handler(mouse_keycode, pressed);
  310. # endif
  311. break;
  312. # endif
  313. default:
  314. mousekey_send();
  315. break;
  316. }
  317. #elif defined(POINTING_DEVICE_ENABLE)
  318. // if mousekeys isn't enabled, and pointing device is enabled, then
  319. // let pointing device do all the heavy lifting, then
  320. if (IS_MOUSE_KEYCODE(mouse_keycode)) {
  321. pointing_device_keycode_handler(mouse_keycode, pressed);
  322. }
  323. #endif
  324. #ifdef PS2_MOUSE_ENABLE
  325. // make sure that ps2 mouse has button report synced
  326. if (QK_MOUSE_BUTTON_1 <= mouse_keycode && mouse_keycode <= QK_MOUSE_BUTTON_3) {
  327. uint8_t tmp_button_msk = MOUSE_BTN_MASK(mouse_keycode - QK_MOUSE_BUTTON_1);
  328. tp_buttons = pressed ? tp_buttons | tmp_button_msk : tp_buttons & ~tmp_button_msk;
  329. }
  330. #endif
  331. }
  332. /** \brief Take an action and processes it.
  333. *
  334. * FIXME: Needs documentation.
  335. */
  336. void process_action(keyrecord_t *record, action_t action) {
  337. keyevent_t event = record->event;
  338. #ifndef NO_ACTION_TAPPING
  339. uint8_t tap_count = record->tap.count;
  340. #endif
  341. #ifndef NO_ACTION_ONESHOT
  342. bool do_release_oneshot = false;
  343. // notice we only clear the one shot layer if the pressed key is not a modifier.
  344. if (is_oneshot_layer_active() && event.pressed &&
  345. (action.kind.id == ACT_USAGE || !(IS_MODIFIER_KEYCODE(action.key.code)
  346. # ifndef NO_ACTION_TAPPING
  347. || ((action.kind.id == ACT_LMODS_TAP || action.kind.id == ACT_RMODS_TAP) && (action.layer_tap.code <= MODS_TAP_TOGGLE || tap_count == 0))
  348. # endif
  349. ))
  350. # ifdef SWAP_HANDS_ENABLE
  351. && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)
  352. # endif
  353. && keymap_config.oneshot_enable) {
  354. clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
  355. do_release_oneshot = !is_oneshot_layer_active();
  356. }
  357. #endif
  358. switch (action.kind.id) {
  359. /* Key and Mods */
  360. case ACT_LMODS:
  361. case ACT_RMODS: {
  362. uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods << 4;
  363. if (event.pressed) {
  364. if (mods) {
  365. if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
  366. // e.g. LSFT(KC_LEFT_GUI): we don't want the LSFT to be weak as it would make it useless.
  367. // This also makes LSFT(KC_LEFT_GUI) behave exactly the same as LGUI(KC_LEFT_SHIFT).
  368. // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
  369. add_mods(mods);
  370. } else {
  371. add_weak_mods(mods);
  372. }
  373. send_keyboard_report();
  374. }
  375. register_code(action.key.code);
  376. } else {
  377. unregister_code(action.key.code);
  378. if (mods) {
  379. if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
  380. del_mods(mods);
  381. } else {
  382. del_weak_mods(mods);
  383. }
  384. send_keyboard_report();
  385. }
  386. }
  387. } break;
  388. case ACT_LMODS_TAP:
  389. case ACT_RMODS_TAP: {
  390. #ifndef NO_ACTION_TAPPING
  391. uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4;
  392. switch (action.layer_tap.code) {
  393. # ifndef NO_ACTION_ONESHOT
  394. case MODS_ONESHOT:
  395. // Oneshot modifier
  396. if (!keymap_config.oneshot_enable) {
  397. if (event.pressed) {
  398. if (mods) {
  399. if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
  400. // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
  401. // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
  402. // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
  403. add_mods(mods);
  404. } else {
  405. add_weak_mods(mods);
  406. }
  407. send_keyboard_report();
  408. }
  409. register_code(action.key.code);
  410. } else {
  411. unregister_code(action.key.code);
  412. if (mods) {
  413. if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
  414. del_mods(mods);
  415. } else {
  416. del_weak_mods(mods);
  417. }
  418. send_keyboard_report();
  419. }
  420. }
  421. } else {
  422. if (event.pressed) {
  423. if (tap_count == 0) {
  424. // Not a tap, but a hold: register the held mod
  425. ac_dprintf("MODS_TAP: Oneshot: 0\n");
  426. register_mods(mods);
  427. } else if (tap_count == 1) {
  428. ac_dprintf("MODS_TAP: Oneshot: start\n");
  429. add_oneshot_mods(mods);
  430. # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
  431. } else if (tap_count == ONESHOT_TAP_TOGGLE) {
  432. ac_dprintf("MODS_TAP: Toggling oneshot");
  433. register_mods(mods);
  434. del_oneshot_mods(mods);
  435. add_oneshot_locked_mods(mods);
  436. # endif
  437. }
  438. } else {
  439. if (tap_count == 0) {
  440. // Release hold: unregister the held mod and its variants
  441. unregister_mods(mods);
  442. del_oneshot_mods(mods);
  443. del_oneshot_locked_mods(mods);
  444. # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
  445. } else if (tap_count == 1 && (mods & get_mods())) {
  446. unregister_mods(mods);
  447. del_oneshot_mods(mods);
  448. del_oneshot_locked_mods(mods);
  449. # endif
  450. }
  451. }
  452. }
  453. break;
  454. # endif
  455. case MODS_TAP_TOGGLE:
  456. if (event.pressed) {
  457. if (tap_count <= TAPPING_TOGGLE) {
  458. register_mods(mods);
  459. }
  460. } else {
  461. if (tap_count < TAPPING_TOGGLE) {
  462. unregister_mods(mods);
  463. }
  464. }
  465. break;
  466. default:
  467. if (event.pressed) {
  468. if (tap_count > 0) {
  469. # ifdef HOLD_ON_OTHER_KEY_PRESS
  470. if (
  471. # ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
  472. get_hold_on_other_key_press(get_event_keycode(record->event, false), record) &&
  473. # endif
  474. record->tap.interrupted) {
  475. ac_dprintf("mods_tap: tap: cancel: add_mods\n");
  476. // ad hoc: set 0 to cancel tap
  477. record->tap.count = 0;
  478. register_mods(mods);
  479. } else
  480. # endif
  481. {
  482. ac_dprintf("MODS_TAP: Tap: register_code\n");
  483. register_code(action.key.code);
  484. }
  485. } else {
  486. ac_dprintf("MODS_TAP: No tap: add_mods\n");
  487. register_mods(mods);
  488. }
  489. } else {
  490. if (tap_count > 0) {
  491. ac_dprintf("MODS_TAP: Tap: unregister_code\n");
  492. if (action.layer_tap.code == KC_CAPS_LOCK) {
  493. wait_ms(TAP_HOLD_CAPS_DELAY);
  494. } else {
  495. wait_ms(TAP_CODE_DELAY);
  496. }
  497. unregister_code(action.key.code);
  498. } else {
  499. ac_dprintf("MODS_TAP: No tap: add_mods\n");
  500. # if defined(RETRO_TAPPING) && defined(DUMMY_MOD_NEUTRALIZER_KEYCODE)
  501. // Send a dummy keycode to neutralize flashing modifiers
  502. // if the key was held and then released with no interruptions.
  503. uint16_t ev_kc = get_event_keycode(event, false);
  504. if (retro_tap_primed && retro_tap_curr_key == ev_kc) {
  505. neutralize_flashing_modifiers(get_mods());
  506. }
  507. # endif
  508. unregister_mods(mods);
  509. }
  510. }
  511. break;
  512. }
  513. #endif // NO_ACTION_TAPPING
  514. } break;
  515. #ifdef EXTRAKEY_ENABLE
  516. /* other HID usage */
  517. case ACT_USAGE:
  518. switch (action.usage.page) {
  519. case PAGE_SYSTEM:
  520. host_system_send(event.pressed ? action.usage.code : 0);
  521. break;
  522. case PAGE_CONSUMER:
  523. host_consumer_send(event.pressed ? action.usage.code : 0);
  524. break;
  525. }
  526. break;
  527. #endif // EXTRAKEY_ENABLE
  528. /* Mouse key */
  529. case ACT_MOUSEKEY:
  530. register_mouse(action.key.code, event.pressed);
  531. break;
  532. #ifndef NO_ACTION_LAYER
  533. case ACT_LAYER:
  534. if (action.layer_bitop.on == 0) {
  535. /* Default Layer Bitwise Operation */
  536. if (!event.pressed) {
  537. uint8_t shift = action.layer_bitop.part * 4;
  538. layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift;
  539. layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0;
  540. switch (action.layer_bitop.op) {
  541. case OP_BIT_AND:
  542. default_layer_and(bits | mask);
  543. break;
  544. case OP_BIT_OR:
  545. default_layer_or(bits | mask);
  546. break;
  547. case OP_BIT_XOR:
  548. default_layer_xor(bits | mask);
  549. break;
  550. case OP_BIT_SET:
  551. default_layer_set(bits | mask);
  552. break;
  553. }
  554. }
  555. } else {
  556. /* Layer Bitwise Operation */
  557. if (event.pressed ? (action.layer_bitop.on & ON_PRESS) : (action.layer_bitop.on & ON_RELEASE)) {
  558. uint8_t shift = action.layer_bitop.part * 4;
  559. layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift;
  560. layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0;
  561. switch (action.layer_bitop.op) {
  562. case OP_BIT_AND:
  563. layer_and(bits | mask);
  564. break;
  565. case OP_BIT_OR:
  566. layer_or(bits | mask);
  567. break;
  568. case OP_BIT_XOR:
  569. layer_xor(bits | mask);
  570. break;
  571. case OP_BIT_SET:
  572. layer_state_set(bits | mask);
  573. break;
  574. }
  575. }
  576. }
  577. break;
  578. case ACT_LAYER_MODS:
  579. if (event.pressed) {
  580. layer_on(action.layer_mods.layer);
  581. register_mods(action.layer_mods.mods);
  582. } else {
  583. unregister_mods(action.layer_mods.mods);
  584. layer_off(action.layer_mods.layer);
  585. }
  586. break;
  587. case ACT_LAYER_TAP:
  588. case ACT_LAYER_TAP_EXT:
  589. switch (action.layer_tap.code) {
  590. # ifndef NO_ACTION_TAPPING
  591. case OP_TAP_TOGGLE:
  592. /* tap toggle */
  593. if (event.pressed) {
  594. if (tap_count < TAPPING_TOGGLE) {
  595. layer_invert(action.layer_tap.val);
  596. }
  597. } else {
  598. if (tap_count <= TAPPING_TOGGLE) {
  599. layer_invert(action.layer_tap.val);
  600. }
  601. }
  602. break;
  603. # endif
  604. case OP_ON_OFF:
  605. event.pressed ? layer_on(action.layer_tap.val) : layer_off(action.layer_tap.val);
  606. break;
  607. case OP_OFF_ON:
  608. event.pressed ? layer_off(action.layer_tap.val) : layer_on(action.layer_tap.val);
  609. break;
  610. case OP_SET_CLEAR:
  611. event.pressed ? layer_move(action.layer_tap.val) : layer_clear();
  612. break;
  613. # if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
  614. case OP_ONESHOT:
  615. // Oneshot modifier
  616. if (!keymap_config.oneshot_enable) {
  617. if (event.pressed) {
  618. layer_on(action.layer_tap.val);
  619. } else {
  620. layer_off(action.layer_tap.val);
  621. }
  622. } else {
  623. # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
  624. do_release_oneshot = false;
  625. if (event.pressed) {
  626. if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
  627. reset_oneshot_layer();
  628. layer_off(action.layer_tap.val);
  629. break;
  630. } else if (tap_count < ONESHOT_TAP_TOGGLE) {
  631. set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
  632. }
  633. } else {
  634. if (tap_count >= ONESHOT_TAP_TOGGLE) {
  635. reset_oneshot_layer();
  636. set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
  637. } else {
  638. clear_oneshot_layer_state(ONESHOT_PRESSED);
  639. }
  640. }
  641. # else
  642. if (event.pressed) {
  643. set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
  644. } else {
  645. clear_oneshot_layer_state(ONESHOT_PRESSED);
  646. if (tap_count > 1) {
  647. clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
  648. }
  649. }
  650. # endif
  651. }
  652. # else // NO_ACTION_ONESHOT && NO_ACTION_TAPPING
  653. if (event.pressed) {
  654. layer_on(action.layer_tap.val);
  655. } else {
  656. layer_off(action.layer_tap.val);
  657. }
  658. # endif // !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
  659. break;
  660. default:
  661. # ifndef NO_ACTION_TAPPING /* tap key */
  662. if (event.pressed) {
  663. if (tap_count > 0) {
  664. ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n");
  665. register_code(action.layer_tap.code);
  666. } else {
  667. ac_dprintf("KEYMAP_TAP_KEY: No tap: On on press\n");
  668. layer_on(action.layer_tap.val);
  669. }
  670. } else {
  671. if (tap_count > 0) {
  672. ac_dprintf("KEYMAP_TAP_KEY: Tap: unregister_code\n");
  673. if (action.layer_tap.code == KC_CAPS_LOCK) {
  674. wait_ms(TAP_HOLD_CAPS_DELAY);
  675. } else {
  676. wait_ms(TAP_CODE_DELAY);
  677. }
  678. unregister_code(action.layer_tap.code);
  679. } else {
  680. ac_dprintf("KEYMAP_TAP_KEY: No tap: Off on release\n");
  681. layer_off(action.layer_tap.val);
  682. }
  683. }
  684. # else
  685. if (event.pressed) {
  686. ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n");
  687. register_code(action.layer_tap.code);
  688. } else {
  689. ac_dprintf("KEYMAP_TAP_KEY: Tap: unregister_code\n");
  690. if (action.layer_tap.code == KC_CAPS) {
  691. wait_ms(TAP_HOLD_CAPS_DELAY);
  692. } else {
  693. wait_ms(TAP_CODE_DELAY);
  694. }
  695. unregister_code(action.layer_tap.code);
  696. }
  697. # endif
  698. break;
  699. }
  700. break;
  701. #endif // NO_ACTION_LAYER
  702. #ifdef SWAP_HANDS_ENABLE
  703. case ACT_SWAP_HANDS:
  704. switch (action.swap.code) {
  705. case OP_SH_TOGGLE:
  706. if (event.pressed) {
  707. swap_hands = !swap_hands;
  708. }
  709. break;
  710. case OP_SH_ON_OFF:
  711. swap_hands = event.pressed;
  712. break;
  713. case OP_SH_OFF_ON:
  714. swap_hands = !event.pressed;
  715. break;
  716. case OP_SH_ON:
  717. if (!event.pressed) {
  718. swap_hands = true;
  719. }
  720. break;
  721. case OP_SH_OFF:
  722. if (!event.pressed) {
  723. swap_hands = false;
  724. }
  725. break;
  726. # ifndef NO_ACTION_ONESHOT
  727. case OP_SH_ONESHOT:
  728. if (event.pressed) {
  729. set_oneshot_swaphands();
  730. } else {
  731. release_oneshot_swaphands();
  732. }
  733. break;
  734. # endif
  735. # ifndef NO_ACTION_TAPPING
  736. case OP_SH_TAP_TOGGLE:
  737. /* tap toggle */
  738. if (event.pressed) {
  739. if (swap_held) {
  740. swap_held = false;
  741. } else {
  742. swap_hands = !swap_hands;
  743. }
  744. } else {
  745. if (tap_count < TAPPING_TOGGLE) {
  746. swap_hands = !swap_hands;
  747. }
  748. }
  749. break;
  750. default:
  751. /* tap key */
  752. if (tap_count > 0) {
  753. if (swap_held) {
  754. swap_hands = !swap_hands; // undo hold set up in _tap_hint
  755. swap_held = false;
  756. }
  757. if (event.pressed) {
  758. register_code(action.swap.code);
  759. } else {
  760. wait_ms(TAP_CODE_DELAY);
  761. unregister_code(action.swap.code);
  762. *record = (keyrecord_t){}; // hack: reset tap mode
  763. }
  764. } else {
  765. if (swap_held && !event.pressed) {
  766. swap_hands = !swap_hands; // undo hold set up in _tap_hint
  767. swap_held = false;
  768. }
  769. }
  770. # endif
  771. }
  772. #endif
  773. default:
  774. break;
  775. }
  776. #ifndef NO_ACTION_LAYER
  777. // if this event is a layer action, update the leds
  778. switch (action.kind.id) {
  779. case ACT_LAYER:
  780. case ACT_LAYER_MODS:
  781. # ifndef NO_ACTION_TAPPING
  782. case ACT_LAYER_TAP:
  783. case ACT_LAYER_TAP_EXT:
  784. # endif
  785. led_set(host_keyboard_leds());
  786. # ifndef NO_ACTION_ONESHOT
  787. // don't release the key
  788. do_release_oneshot = false;
  789. # endif
  790. break;
  791. default:
  792. break;
  793. }
  794. #endif
  795. #ifndef NO_ACTION_TAPPING
  796. # if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  797. if (is_tap_action(action)) {
  798. if (event.pressed) {
  799. if (tap_count > 0) {
  800. retro_tap_primed = false;
  801. } else {
  802. # if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  803. retro_tap_curr_mods = retro_tap_next_mods;
  804. retro_tap_next_mods = get_mods();
  805. # endif
  806. }
  807. } else {
  808. uint16_t event_keycode = get_event_keycode(event, false);
  809. # if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  810. uint8_t curr_mods = get_mods();
  811. # endif
  812. if (tap_count > 0) {
  813. retro_tap_primed = false;
  814. } else if (retro_tap_curr_key == event_keycode) {
  815. if (
  816. # ifdef RETRO_TAPPING_PER_KEY
  817. get_retro_tapping(event_keycode, record) &&
  818. # endif
  819. retro_tap_primed) {
  820. # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
  821. process_auto_shift(action.layer_tap.code, record);
  822. # else
  823. register_mods(retro_tap_curr_mods);
  824. wait_ms(TAP_CODE_DELAY);
  825. tap_code(action.layer_tap.code);
  826. wait_ms(TAP_CODE_DELAY);
  827. unregister_mods(retro_tap_curr_mods);
  828. # endif
  829. }
  830. retro_tap_primed = false;
  831. }
  832. # if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  833. retro_tap_next_mods = curr_mods;
  834. # endif
  835. }
  836. }
  837. # endif
  838. #endif
  839. #ifdef SWAP_HANDS_ENABLE
  840. # ifndef NO_ACTION_ONESHOT
  841. if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) {
  842. use_oneshot_swaphands();
  843. }
  844. # endif
  845. #endif
  846. #ifndef NO_ACTION_ONESHOT
  847. /* Because we switch layers after a oneshot event, we need to release the
  848. * key before we leave the layer or no key up event will be generated.
  849. */
  850. if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED)) {
  851. record->event.pressed = false;
  852. layer_on(get_oneshot_layer());
  853. process_record(record);
  854. layer_off(get_oneshot_layer());
  855. }
  856. #endif
  857. }
  858. /** \brief Utilities for actions. (FIXME: Needs better description)
  859. *
  860. * FIXME: Needs documentation.
  861. */
  862. __attribute__((weak)) void register_code(uint8_t code) {
  863. if (code == KC_NO) {
  864. return;
  865. #ifdef LOCKING_SUPPORT_ENABLE
  866. } else if (KC_LOCKING_CAPS_LOCK == code) {
  867. # ifdef LOCKING_RESYNC_ENABLE
  868. // Resync: ignore if caps lock already is on
  869. if (host_keyboard_led_state().caps_lock) return;
  870. # endif
  871. add_key(KC_CAPS_LOCK);
  872. send_keyboard_report();
  873. wait_ms(TAP_HOLD_CAPS_DELAY);
  874. del_key(KC_CAPS_LOCK);
  875. send_keyboard_report();
  876. } else if (KC_LOCKING_NUM_LOCK == code) {
  877. # ifdef LOCKING_RESYNC_ENABLE
  878. if (host_keyboard_led_state().num_lock) return;
  879. # endif
  880. add_key(KC_NUM_LOCK);
  881. send_keyboard_report();
  882. wait_ms(100);
  883. del_key(KC_NUM_LOCK);
  884. send_keyboard_report();
  885. } else if (KC_LOCKING_SCROLL_LOCK == code) {
  886. # ifdef LOCKING_RESYNC_ENABLE
  887. if (host_keyboard_led_state().scroll_lock) return;
  888. # endif
  889. add_key(KC_SCROLL_LOCK);
  890. send_keyboard_report();
  891. wait_ms(100);
  892. del_key(KC_SCROLL_LOCK);
  893. send_keyboard_report();
  894. #endif
  895. } else if (IS_BASIC_KEYCODE(code)) {
  896. // TODO: should push command_proc out of this block?
  897. if (command_proc(code)) return;
  898. // Force a new key press if the key is already pressed
  899. // without this, keys with the same keycode, but different
  900. // modifiers will be reported incorrectly, see issue #1708
  901. if (is_key_pressed(code)) {
  902. del_key(code);
  903. send_keyboard_report();
  904. }
  905. add_key(code);
  906. send_keyboard_report();
  907. } else if (IS_MODIFIER_KEYCODE(code)) {
  908. add_mods(MOD_BIT(code));
  909. send_keyboard_report();
  910. #ifdef EXTRAKEY_ENABLE
  911. } else if (IS_SYSTEM_KEYCODE(code)) {
  912. host_system_send(KEYCODE2SYSTEM(code));
  913. } else if (IS_CONSUMER_KEYCODE(code)) {
  914. host_consumer_send(KEYCODE2CONSUMER(code));
  915. #endif
  916. } else if (IS_MOUSE_KEYCODE(code)) {
  917. register_mouse(code, true);
  918. }
  919. }
  920. /** \brief Utilities for actions. (FIXME: Needs better description)
  921. *
  922. * FIXME: Needs documentation.
  923. */
  924. __attribute__((weak)) void unregister_code(uint8_t code) {
  925. if (code == KC_NO) {
  926. return;
  927. #ifdef LOCKING_SUPPORT_ENABLE
  928. } else if (KC_LOCKING_CAPS_LOCK == code) {
  929. # ifdef LOCKING_RESYNC_ENABLE
  930. // Resync: ignore if caps lock already is off
  931. if (!host_keyboard_led_state().caps_lock) return;
  932. # endif
  933. add_key(KC_CAPS_LOCK);
  934. send_keyboard_report();
  935. del_key(KC_CAPS_LOCK);
  936. send_keyboard_report();
  937. } else if (KC_LOCKING_NUM_LOCK == code) {
  938. # ifdef LOCKING_RESYNC_ENABLE
  939. if (!host_keyboard_led_state().num_lock) return;
  940. # endif
  941. add_key(KC_NUM_LOCK);
  942. send_keyboard_report();
  943. del_key(KC_NUM_LOCK);
  944. send_keyboard_report();
  945. } else if (KC_LOCKING_SCROLL_LOCK == code) {
  946. # ifdef LOCKING_RESYNC_ENABLE
  947. if (!host_keyboard_led_state().scroll_lock) return;
  948. # endif
  949. add_key(KC_SCROLL_LOCK);
  950. send_keyboard_report();
  951. del_key(KC_SCROLL_LOCK);
  952. send_keyboard_report();
  953. #endif
  954. } else if (IS_BASIC_KEYCODE(code)) {
  955. del_key(code);
  956. send_keyboard_report();
  957. } else if (IS_MODIFIER_KEYCODE(code)) {
  958. del_mods(MOD_BIT(code));
  959. send_keyboard_report();
  960. #ifdef EXTRAKEY_ENABLE
  961. } else if (IS_SYSTEM_KEYCODE(code)) {
  962. host_system_send(0);
  963. } else if (IS_CONSUMER_KEYCODE(code)) {
  964. host_consumer_send(0);
  965. #endif
  966. } else if (IS_MOUSE_KEYCODE(code)) {
  967. register_mouse(code, false);
  968. }
  969. }
  970. /** \brief Tap a keycode with a delay.
  971. *
  972. * \param code The basic keycode to tap.
  973. * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it.
  974. */
  975. __attribute__((weak)) void tap_code_delay(uint8_t code, uint16_t delay) {
  976. register_code(code);
  977. wait_ms(delay);
  978. unregister_code(code);
  979. }
  980. /** \brief Tap a keycode with the default delay.
  981. *
  982. * \param code The basic keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
  983. */
  984. __attribute__((weak)) void tap_code(uint8_t code) {
  985. tap_code_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY);
  986. }
  987. /** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.
  988. *
  989. * \param mods A bitfield of modifiers to register.
  990. */
  991. __attribute__((weak)) void register_mods(uint8_t mods) {
  992. if (mods) {
  993. add_mods(mods);
  994. send_keyboard_report();
  995. }
  996. }
  997. /** \brief Removes the given physically pressed modifiers and sends a keyboard report immediately.
  998. *
  999. * \param mods A bitfield of modifiers to unregister.
  1000. */
  1001. __attribute__((weak)) void unregister_mods(uint8_t mods) {
  1002. if (mods) {
  1003. del_mods(mods);
  1004. send_keyboard_report();
  1005. }
  1006. }
  1007. /** \brief Adds the given weak modifiers and sends a keyboard report immediately.
  1008. *
  1009. * \param mods A bitfield of modifiers to register.
  1010. */
  1011. __attribute__((weak)) void register_weak_mods(uint8_t mods) {
  1012. if (mods) {
  1013. add_weak_mods(mods);
  1014. send_keyboard_report();
  1015. }
  1016. }
  1017. /** \brief Removes the given weak modifiers and sends a keyboard report immediately.
  1018. *
  1019. * \param mods A bitfield of modifiers to unregister.
  1020. */
  1021. __attribute__((weak)) void unregister_weak_mods(uint8_t mods) {
  1022. if (mods) {
  1023. del_weak_mods(mods);
  1024. send_keyboard_report();
  1025. }
  1026. }
  1027. /** \brief Utilities for actions. (FIXME: Needs better description)
  1028. *
  1029. * FIXME: Needs documentation.
  1030. */
  1031. void clear_keyboard(void) {
  1032. clear_mods();
  1033. clear_keyboard_but_mods();
  1034. }
  1035. /** \brief Utilities for actions. (FIXME: Needs better description)
  1036. *
  1037. * FIXME: Needs documentation.
  1038. */
  1039. void clear_keyboard_but_mods(void) {
  1040. clear_keys();
  1041. clear_keyboard_but_mods_and_keys();
  1042. }
  1043. /** \brief Utilities for actions. (FIXME: Needs better description)
  1044. *
  1045. * FIXME: Needs documentation.
  1046. */
  1047. void clear_keyboard_but_mods_and_keys(void) {
  1048. #ifdef EXTRAKEY_ENABLE
  1049. host_system_send(0);
  1050. host_consumer_send(0);
  1051. #endif
  1052. clear_weak_mods();
  1053. send_keyboard_report();
  1054. #ifdef MOUSEKEY_ENABLE
  1055. mousekey_clear();
  1056. mousekey_send();
  1057. #endif
  1058. #ifdef PROGRAMMABLE_BUTTON_ENABLE
  1059. programmable_button_clear();
  1060. #endif
  1061. }
  1062. /** \brief Utilities for actions. (FIXME: Needs better description)
  1063. *
  1064. * FIXME: Needs documentation.
  1065. */
  1066. bool is_tap_record(keyrecord_t *record) {
  1067. if (IS_NOEVENT(record->event)) {
  1068. return false;
  1069. }
  1070. #if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE)
  1071. action_t action;
  1072. if (record->keycode) {
  1073. action = action_for_keycode(record->keycode);
  1074. } else {
  1075. action = layer_switch_get_action(record->event.key);
  1076. }
  1077. #else
  1078. action_t action = layer_switch_get_action(record->event.key);
  1079. #endif
  1080. return is_tap_action(action);
  1081. }
  1082. /** \brief Utilities for actions. (FIXME: Needs better description)
  1083. *
  1084. * FIXME: Needs documentation.
  1085. */
  1086. bool is_tap_action(action_t action) {
  1087. switch (action.kind.id) {
  1088. case ACT_LMODS_TAP:
  1089. case ACT_RMODS_TAP:
  1090. case ACT_LAYER_TAP:
  1091. case ACT_LAYER_TAP_EXT:
  1092. switch (action.layer_tap.code) {
  1093. case KC_NO ... KC_RIGHT_GUI:
  1094. case OP_TAP_TOGGLE:
  1095. case OP_ONESHOT:
  1096. return true;
  1097. }
  1098. return false;
  1099. case ACT_SWAP_HANDS:
  1100. switch (action.swap.code) {
  1101. case KC_NO ... KC_RIGHT_GUI:
  1102. case OP_SH_TAP_TOGGLE:
  1103. return true;
  1104. }
  1105. return false;
  1106. }
  1107. return false;
  1108. }
  1109. uint16_t get_tap_keycode(uint16_t keycode) {
  1110. switch (keycode) {
  1111. case QK_MOD_TAP ... QK_MOD_TAP_MAX:
  1112. return QK_MOD_TAP_GET_TAP_KEYCODE(keycode);
  1113. case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
  1114. return QK_LAYER_TAP_GET_TAP_KEYCODE(keycode);
  1115. case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
  1116. // IS_SWAP_HANDS_KEYCODE() tests for the special action keycodes
  1117. // like SH_TOGG, SH_TT, ..., which overlap the SH_T(kc) range.
  1118. if (!IS_SWAP_HANDS_KEYCODE(keycode)) {
  1119. return QK_SWAP_HANDS_GET_TAP_KEYCODE(keycode);
  1120. }
  1121. break;
  1122. }
  1123. return keycode;
  1124. }
  1125. /** \brief Debug print (FIXME: Needs better description)
  1126. *
  1127. * FIXME: Needs documentation.
  1128. */
  1129. void debug_event(keyevent_t event) {
  1130. ac_dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time);
  1131. }
  1132. /** \brief Debug print (FIXME: Needs better description)
  1133. *
  1134. * FIXME: Needs documentation.
  1135. */
  1136. void debug_record(keyrecord_t record) {
  1137. debug_event(record.event);
  1138. #ifndef NO_ACTION_TAPPING
  1139. ac_dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' '));
  1140. #endif
  1141. }
  1142. /** \brief Debug print (FIXME: Needs better description)
  1143. *
  1144. * FIXME: Needs documentation.
  1145. */
  1146. void debug_action(action_t action) {
  1147. switch (action.kind.id) {
  1148. case ACT_LMODS:
  1149. ac_dprintf("ACT_LMODS");
  1150. break;
  1151. case ACT_RMODS:
  1152. ac_dprintf("ACT_RMODS");
  1153. break;
  1154. case ACT_LMODS_TAP:
  1155. ac_dprintf("ACT_LMODS_TAP");
  1156. break;
  1157. case ACT_RMODS_TAP:
  1158. ac_dprintf("ACT_RMODS_TAP");
  1159. break;
  1160. case ACT_USAGE:
  1161. ac_dprintf("ACT_USAGE");
  1162. break;
  1163. case ACT_MOUSEKEY:
  1164. ac_dprintf("ACT_MOUSEKEY");
  1165. break;
  1166. case ACT_LAYER:
  1167. ac_dprintf("ACT_LAYER");
  1168. break;
  1169. case ACT_LAYER_MODS:
  1170. ac_dprintf("ACT_LAYER_MODS");
  1171. break;
  1172. case ACT_LAYER_TAP:
  1173. ac_dprintf("ACT_LAYER_TAP");
  1174. break;
  1175. case ACT_LAYER_TAP_EXT:
  1176. ac_dprintf("ACT_LAYER_TAP_EXT");
  1177. break;
  1178. case ACT_SWAP_HANDS:
  1179. ac_dprintf("ACT_SWAP_HANDS");
  1180. break;
  1181. default:
  1182. ac_dprintf("UNKNOWN");
  1183. break;
  1184. }
  1185. ac_dprintf("[%X:%02X]", action.kind.param >> 8, action.kind.param & 0xff);
  1186. }