Parent directory

action_util.c

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