qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

keymap.c (42761B)


      1 /*
      2 Copyright 2017 Priyadi Iman Nurcahyo
      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 This program is distributed in the hope that it will be useful,
      9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 GNU General Public License for more details.
     12 You should have received a copy of the GNU General Public License
     13 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     14 */
     15 
     16 #include QMK_KEYBOARD_H
     17 
     18 #include "action_layer.h"
     19 #ifdef AUDIO_ENABLE
     20   #include "audio.h"
     21   #include "musical_notes.h"
     22 #endif
     23 #include "eeconfig.h"
     24 #include "process_unicode.h"
     25 #ifdef RGBSPS_ENABLE
     26 #include "rgbsps.h"
     27 #include "rgbtheme.h"
     28 #endif
     29 #ifdef PS2_MOUSE_ENABLE
     30 #include "ps2_mouse.h"
     31 #include "ps2.h"
     32 #endif
     33 #ifdef FAUXCLICKY_ENABLE
     34 #include "fauxclicky.h"
     35 #ifdef RGBSPS_ENABLE
     36 #undef FAUXCLICKY_OFF
     37 #define FAUXCLICKY_OFF do { \
     38     fauxclicky_enabled = false; \
     39     rgbsps_set(LED_AUDIO, COLOR_BLANK); \
     40     fauxclicky_stop(); \
     41 } while (0)
     42 #undef FAUXCLICKY_ON
     43 #define FAUXCLICKY_ON do { \
     44     fauxclicky_enabled = true; \
     45     rgbsps_set(LED_AUDIO, THEME_COLOR_AUDIO); \
     46 } while (0)
     47 #endif
     48 #endif
     49 #include "outputselect.h"
     50 #include "led.h"
     51 #define COUNT(x) ARRAY_SIZE((x))
     52 
     53 #define KC_WWWB KC_WWW_BACK
     54 #define KC_WWWF KC_WWW_FORWARD
     55 
     56 // hybrid right-alt & scroll lock (mapped to Compose in OS)
     57 #define C_RALT MT(MOD_RALT, KC_SCRL)
     58 
     59 // dual use right-shift & del key
     60 // #define C_RSFT MT(MOD_RSFT, KC_DEL)
     61 
     62 bool capslock = false;
     63 #ifdef DOUBLESPACE_LAYER_ENABLE
     64 bool lspace_active = false;
     65 bool rspace_active = false;
     66 bool lspace_emitted = false;
     67 bool rspace_emitted = false;
     68 bool space_layer_entered = false;
     69 #endif
     70 
     71 // glow
     72 enum glow_modes {
     73   GLOW_NONE,
     74   GLOW_MIN,
     75   GLOW_FULL
     76 };
     77 uint8_t glow_mode = GLOW_MIN;
     78 
     79 void turn_off_capslock(void);
     80 
     81 // layers, ordering is important!
     82 enum layers {
     83   _QWERTY,
     84   _DVORAK,
     85   _COLEMAK,
     86   _WORKMAN,
     87   _NORMAN,
     88   _DEFAULT_LAYER_MAX = _NORMAN,
     89 
     90   _GREEKU,
     91   _GREEKL,
     92 
     93   _NUM,
     94   _FUN,
     95   _PUNC,
     96 
     97   _EMPTY,
     98   _EMOJI,
     99   _GUI,
    100   _SYS
    101 };
    102 
    103 // double-space layer
    104 #define _SPACE _GUI
    105 
    106 enum planck_keycodes {
    107   // layouts
    108   QWERTY = SAFE_RANGE,
    109   DVORAK,
    110   COLEMAK,
    111   WORKMAN,
    112   NORMAN,
    113 
    114   // layer switchers
    115   EMOJI,
    116   GUI,
    117   GREEK,
    118 
    119   // os switchers
    120   LINUX,
    121   WIN,
    122   OSX,
    123 
    124   // others
    125   LSPACE,
    126   RSPACE,
    127   GLOW,
    128 
    129   // stub
    130 #ifndef FAUXCLICKY_ENABLE
    131   FC_TOG,
    132 #endif
    133   RGBDEMO,
    134   KEYCODE_END
    135 };
    136 
    137 #define EMPTY MO(_EMPTY)
    138 #define NUM MO(_NUM)
    139 #define FUN MO(_FUN)
    140 #define FUN0 LT(_FUN, KC_0)
    141 
    142 // unicode map
    143 
    144 enum unicode_name {
    145   GRIN, // grinning face 😊
    146   TJOY, // tears of joy 😂
    147   SMILE, // grining face with smiling eyes 😁
    148   HEART, // heart ❤
    149   EYERT, // smiling face with heart shaped eyes 😍
    150   CRY, // crying face 😭
    151   SMEYE, // smiling face with smiling eyes 😊
    152   UNAMU, // unamused 😒
    153   KISS, // kiss 😘
    154   HART2, // two hearts 💕
    155   WEARY, // weary 😩
    156   OKHND, // ok hand sign 👌
    157   PENSV, // pensive 😔
    158   SMIRK, // smirk 😏
    159   RECYC, // recycle ♻
    160   WINK, // wink 😉
    161   THMUP, // thumb up 👍
    162   THMDN, // thumb down 👎
    163   PRAY, // pray 🙏
    164   PHEW, // relieved 😌
    165   MUSIC, // musical notes
    166   FLUSH, // flushed 😳
    167   CELEB, // celebration 🙌
    168   CRY2, // crying face 😢
    169   COOL, // smile with sunglasses 😎
    170   NOEVS, // see no evil
    171   NOEVH, // hear no evil
    172   NOEVK, // speak no evil
    173   POO, // pile of poo
    174   EYES, // eyes
    175   VIC, // victory hand
    176   BHART, // broken heart
    177   SLEEP, // sleeping face
    178   SMIL2, // smiling face with open mouth & sweat
    179   HUNRD, // 100
    180   CONFU, // confused
    181   TONGU, // face with tongue & winking eye
    182   DISAP, // disappointed
    183   YUMMY, // face savoring delicious food
    184   CLAP, // hand clapping
    185   FEAR, // face screaming in fear
    186   HORNS, // smiling face with horns
    187   HALO, // smiling face with halo
    188   BYE, // waving hand
    189   SUN, // sun
    190   MOON, // moon
    191   SKULL, // skull
    192 
    193   // greek letters
    194   UALPH,
    195   UBETA,
    196   UGAMM,
    197   UDELT,
    198   UEPSI,
    199   UZETA,
    200   UETA,
    201   UTHET,
    202   UIOTA,
    203   UKAPP,
    204   ULAMB,
    205   UMU,
    206   UNU,
    207   UXI,
    208   UOMIC,
    209   UPI,
    210   URHO,
    211   USIGM,
    212   UTAU,
    213   UUPSI,
    214   UPHI,
    215   UCHI,
    216   UPSI,
    217   UOMEG,
    218 
    219   LALPH,
    220   LBETA,
    221   LGAMM,
    222   LDELT,
    223   LEPSI,
    224   LZETA,
    225   LETA,
    226   LTHET,
    227   LIOTA,
    228   LKAPP,
    229   LLAMB,
    230   LMU,
    231   LNU,
    232   LXI,
    233   LOMIC,
    234   LPI,
    235   LRHO,
    236   LSIGM,
    237   LTAU,
    238   LUPSI,
    239   LPHI,
    240   LCHI,
    241   LPSI,
    242   LOMEG,
    243 
    244   FSIGM,
    245 
    246   LTEQ,
    247   GTEQ,
    248   NOTEQ,
    249   PLMIN,
    250 };
    251 
    252 const uint32_t unicode_map[] PROGMEM = {
    253   [GRIN] = 0x1F600,
    254   [TJOY] = 0x1F602,
    255   [SMILE] = 0x1F601,
    256   [HEART] = 0x2764,
    257   [EYERT] = 0x1f60d,
    258   [CRY] = 0x1f62d,
    259   [SMEYE] = 0x1F60A,
    260   [UNAMU] = 0x1F612,
    261   [KISS] = 0x1F618,
    262   [HART2] = 0x1F495,
    263   [WEARY] = 0x1F629,
    264   [OKHND] = 0x1F44C,
    265   [PENSV] = 0x1F614,
    266   [SMIRK] = 0x1F60F,
    267   [RECYC] = 0x267B,
    268   [WINK] = 0x1F609,
    269   [THMUP] = 0x1F44D,
    270   [THMDN] = 0x1F44E,
    271   [PRAY] = 0x1F64F,
    272   [PHEW] = 0x1F60C,
    273   [MUSIC] = 0x1F3B6,
    274   [FLUSH] = 0x1F633,
    275   [CELEB] = 0x1F64C,
    276   [CRY2] = 0x1F622,
    277   [COOL] = 0x1F60E,
    278   [NOEVS] = 0x1F648,
    279   [NOEVH] = 0x1F649,
    280   [NOEVK] = 0x1F64A,
    281   [POO] = 0x1F4A9,
    282   [EYES] = 0x1F440,
    283   [VIC] = 0x270C,
    284   [BHART] = 0x1F494,
    285   [SLEEP] = 0x1F634,
    286   [SMIL2] = 0x1F605,
    287   [HUNRD] = 0x1F4AF,
    288   [CONFU] = 0x1F615,
    289   [TONGU] = 0x1F61C,
    290   [DISAP] = 0x1F61E,
    291   [YUMMY] = 0x1F60B,
    292   [CLAP] = 0x1F44F,
    293   [FEAR] = 0x1F631,
    294   [HORNS] = 0x1F608,
    295   [HALO] = 0x1F607,
    296   [BYE] = 0x1F44B,
    297   [SUN] = 0x2600,
    298   [MOON] = 0x1F314,
    299   [SKULL] = 0x1F480,
    300 
    301   // greek letters
    302   [UALPH] = 0x0391,
    303   [UBETA] = 0x0392,
    304   [UGAMM] = 0x0393,
    305   [UDELT] = 0x0394,
    306   [UEPSI] = 0x0395,
    307   [UZETA] = 0x0396,
    308   [UETA] = 0x0397,
    309   [UTHET] = 0x0398,
    310   [UIOTA] = 0x0399,
    311   [UKAPP] = 0x039A,
    312   [ULAMB] = 0x039B,
    313   [UMU] = 0x039C,
    314   [UNU] = 0x039D,
    315   [UXI] = 0x039E,
    316   [UOMIC] = 0x039F,
    317   [UPI] = 0x03A0,
    318   [URHO] = 0x03A1,
    319   [USIGM] = 0x03A3,
    320   [UTAU] = 0x03A4,
    321   [UUPSI] = 0x03A5,
    322   [UPHI] = 0x03A6,
    323   [UCHI] = 0x03A7,
    324   [UPSI] = 0x03A8,
    325   [UOMEG] = 0x03A9,
    326   [LALPH] = 0x03B1,
    327   [LBETA] = 0x03B2,
    328   [LGAMM] = 0x03B3,
    329   [LDELT] = 0x03B4,
    330   [LEPSI] = 0x03B5,
    331   [LZETA] = 0x03B6,
    332   [LETA] = 0x03B7,
    333   [LTHET] = 0x03B8,
    334   [LIOTA] = 0x03B9,
    335   [LKAPP] = 0x03BA,
    336   [LLAMB] = 0x03BB,
    337   [LMU] = 0x03BC,
    338   [LNU] = 0x03BD,
    339   [LXI] = 0x03BE,
    340   [LOMIC] = 0x03BF,
    341   [LPI] = 0x03C0,
    342   [LRHO] = 0x03C1,
    343   [LSIGM] = 0x03C3,
    344   [LTAU] = 0x03C4,
    345   [LUPSI] = 0x03C5,
    346   [LPHI] = 0x03C6,
    347   [LCHI] = 0x03C7,
    348   [LPSI] = 0x03C8,
    349   [LOMEG] = 0x03C9,
    350   [FSIGM] = 0x03C2,
    351 
    352   // other
    353   [LTEQ] = 0x2264, // less than or equal
    354   [GTEQ] = 0x2265, // greater than or equal
    355   [NOTEQ] = 0x2260, // not equal
    356   [PLMIN] = 0xB1, // plus minus
    357 };
    358 
    359 // RGBSPS
    360 
    361 #ifdef RGBSPS_ENABLE
    362 const uint8_t PROGMEM LED_ALNUM[] = {
    363   LED_Z,
    364   LED_A,
    365   LED_Q,
    366   LED_W,
    367   LED_S,
    368   LED_X,
    369   LED_C,
    370   LED_D,
    371   LED_E,
    372   LED_R,
    373   LED_F,
    374   LED_V,
    375   LED_B,
    376   LED_G,
    377   LED_T,
    378   LED_N,
    379   LED_HH,
    380   LED_Y,
    381   LED_U,
    382   LED_J,
    383   LED_M,
    384   LED_COMM,
    385   LED_K,
    386   LED_I,
    387   LED_O,
    388   LED_L,
    389   LED_DOT,
    390   LED_SLSH,
    391   LED_SCLN,
    392   LED_P,
    393   LED_LSPC,
    394   LED_RSPC
    395 };
    396 
    397 const uint8_t PROGMEM LED_HOMING[] = {
    398   LED_A,
    399   LED_S,
    400   LED_D,
    401   LED_F,
    402   LED_J,
    403   LED_K,
    404   LED_L,
    405   LED_SCLN
    406 };
    407 
    408 const uint8_t PROGMEM LED_MODS[] = {
    409   LED_TAB,
    410   LED_ESC,
    411   LED_LSFT,
    412   LED_LCTL,
    413   LED_LGUI,
    414   LED_LALT,
    415   LED_RALT,
    416   LED_RGUI,
    417   LED_BKSP,
    418   LED_ENT,
    419   LED_RSFT,
    420   LED_RCTL
    421 };
    422 
    423 const uint8_t PROGMEM LED_FN[] = {
    424   LED_EMPTY,
    425   LED_NUM,
    426   LED_FUN,
    427   LED_GREEK
    428 };
    429 
    430 const uint8_t PROGMEM LED_INDICATORS[] = {
    431   LED_IND_LINUX,
    432   LED_IND_APPLE,
    433   LED_IND_WINDOWS,
    434   LED_IND_QWERTY,
    435   LED_IND_ALT,
    436   LED_IND_AUDIO,
    437   LED_IND_BLUETOOTH,
    438   LED_IND_USB,
    439 
    440   LED_IND_BATTERY,
    441   LED_IND_CAPSLOCK,
    442   LED_IND_GUI,
    443   LED_IND_FUN,
    444   LED_IND_NUM,
    445   LED_IND_PUNC,
    446   LED_IND_EMOJI,
    447   LED_IND_GREEK,
    448 };
    449 
    450 const uint8_t PROGMEM LED_TRACKPOINT[] = {
    451   LED_TRACKPOINT1,
    452   LED_TRACKPOINT2,
    453   LED_TRACKPOINT3,
    454 };
    455 
    456 void led_turnoff_keys(void) {
    457   for(uint8_t i = 0; i < COUNT(LED_ALNUM); i++) {
    458     rgbsps_set(pgm_read_byte(&LED_ALNUM[i]), COLOR_BLACK);
    459   }
    460   for(uint8_t i = 0; i < COUNT(LED_MODS); i++) {
    461     rgbsps_set(pgm_read_byte(&LED_MODS[i]), COLOR_BLACK);
    462   }
    463   for(uint8_t i = 0; i < COUNT(LED_FN); i++) {
    464     rgbsps_set(pgm_read_byte(&LED_FN[i]), COLOR_BLACK);
    465   }
    466 }
    467 
    468 #ifdef RGBSPS_DEMO_ENABLE
    469 void led_demo(void) {
    470   rgbsps_set(LED_IND_LINUX, THEME_COLOR_LINUX);
    471   rgbsps_set(LED_IND_APPLE, THEME_COLOR_APPLE);
    472   rgbsps_set(LED_IND_WINDOWS, THEME_COLOR_WINDOWS);
    473   rgbsps_set(LED_IND_QWERTY, THEME_COLOR_QWERTY);
    474   rgbsps_set(LED_IND_ALT, THEME_COLOR_ALT);
    475   rgbsps_set(LED_IND_AUDIO, THEME_COLOR_AUDIO);
    476   rgbsps_set(LED_IND_BLUETOOTH, THEME_COLOR_BLUETOOTH);
    477   rgbsps_set(LED_IND_USB, THEME_COLOR_USB);
    478   rgbsps_set(LED_IND_CAPSLOCK, THEME_COLOR_CAPSLOCK);
    479   rgbsps_set(LED_IND_GUI, THEME_COLOR_GUI);
    480   rgbsps_set(LED_IND_FUN, THEME_COLOR_FUN);
    481   rgbsps_set(LED_IND_NUM, THEME_COLOR_NUM);
    482   rgbsps_set(LED_IND_PUNC, THEME_COLOR_PUNC);
    483   rgbsps_set(LED_IND_GREEK, THEME_COLOR_GREEK);
    484   rgbsps_set(LED_IND_EMOJI, THEME_COLOR_EMOJI);
    485   rgbsps_send();
    486 }
    487 #endif
    488 
    489 void led_reset(void) {
    490   switch (glow_mode) {
    491     case GLOW_NONE:
    492       led_turnoff_keys();
    493       break;
    494     case GLOW_MIN:
    495       led_turnoff_keys();
    496       for(uint8_t i = 0; i < COUNT(LED_HOMING); i++) {
    497         rgbsps_set(pgm_read_byte(&LED_HOMING[i]), THEME_COLOR_GLOW1_HOME);
    498       }
    499       rgbsps_set(LED_F, THEME_COLOR_GLOW1_HOMING);
    500       rgbsps_set(LED_J, THEME_COLOR_GLOW1_HOMING);
    501       break;
    502     case GLOW_FULL:
    503       for(uint8_t i = 0; i < COUNT(LED_ALNUM); i++) {
    504         rgbsps_set(pgm_read_byte(&LED_ALNUM[i]), THEME_COLOR_GLOW2_ALPHA);
    505       }
    506       for(uint8_t i = 0; i < COUNT(LED_MODS); i++) {
    507         rgbsps_set(pgm_read_byte(&LED_MODS[i]), THEME_COLOR_GLOW2_MODS);
    508       }
    509       for(uint8_t i = 0; i < COUNT(LED_FN); i++) {
    510         rgbsps_set(pgm_read_byte(&LED_FN[i]), THEME_COLOR_GLOW2_FN);
    511       }
    512       for(uint8_t i = 0; i < COUNT(LED_HOMING); i++) {
    513         rgbsps_set(pgm_read_byte(&LED_HOMING[i]), THEME_COLOR_GLOW2_HOME);
    514       }
    515       rgbsps_set(LED_F, THEME_COLOR_GLOW2_HOMING);
    516       rgbsps_set(LED_J, THEME_COLOR_GLOW2_HOMING);
    517       break;
    518   }
    519 }
    520 
    521 void led_set_default_layer_indicator(void) {
    522   uint8_t default_layer = get_highest_layer(default_layer_state);
    523   if (default_layer == _QWERTY) {
    524     rgbsps_set(LED_IND_QWERTY, THEME_COLOR_QWERTY);
    525     rgbsps_set(LED_IND_ALT, COLOR_BLANK);
    526   } else {
    527     rgbsps_set(LED_IND_QWERTY, COLOR_BLANK);
    528     rgbsps_set(LED_IND_ALT, THEME_COLOR_ALT);
    529   }
    530   rgbsps_send();
    531   return;
    532 }
    533 
    534 void led_set_layer_indicator(void) {
    535   static uint8_t oldlayer = 255;
    536 
    537   led_reset();
    538 
    539   rgbsps_set(LED_IND_GUI, COLOR_BLANK);
    540   rgbsps_set(LED_IND_FUN, COLOR_BLANK);
    541   rgbsps_set(LED_IND_NUM, COLOR_BLANK);
    542   rgbsps_set(LED_IND_PUNC, COLOR_BLANK);
    543   rgbsps_set(LED_IND_GREEK, COLOR_BLANK);
    544   rgbsps_set(LED_IND_EMOJI, COLOR_BLANK);
    545 
    546   uint8_t layer = get_highest_layer(layer_state);
    547   if (oldlayer == layer) {
    548     return;
    549   }
    550 
    551   oldlayer = layer;
    552 
    553   if (layer <= _DEFAULT_LAYER_MAX) {
    554     rgbsps_send();
    555     return;
    556   }
    557 
    558   switch(layer) {
    559     case _GUI:
    560       rgbsps_set(LED_IND_GUI, THEME_COLOR_GUI);
    561       break;
    562     case _FUN:
    563       rgbsps_set(LED_IND_FUN, THEME_COLOR_FUN);
    564       break;
    565     case _NUM:
    566       rgbsps_set(LED_IND_NUM, THEME_COLOR_NUM);
    567       break;
    568     case _PUNC:
    569       rgbsps_set(LED_IND_PUNC, THEME_COLOR_PUNC);
    570       break;
    571     case _GREEKL:
    572     case _GREEKU:
    573       rgbsps_set(LED_IND_GREEK, THEME_COLOR_GREEK);
    574       break;
    575     case _EMOJI:
    576       rgbsps_set(LED_IND_EMOJI, THEME_COLOR_EMOJI);
    577       break;
    578     default:
    579       rgbsps_set(LED_IND_GUI, THEME_COLOR_OTHERLAYER);
    580       rgbsps_set(LED_IND_FUN, THEME_COLOR_OTHERLAYER);
    581       rgbsps_set(LED_IND_NUM, THEME_COLOR_OTHERLAYER);
    582       rgbsps_set(LED_IND_PUNC, THEME_COLOR_OTHERLAYER);
    583       rgbsps_set(LED_IND_GREEK, THEME_COLOR_OTHERLAYER);
    584       rgbsps_set(LED_IND_EMOJI, THEME_COLOR_OTHERLAYER);
    585   }
    586 
    587   rgbsps_send();
    588 }
    589 
    590 void led_set_unicode_input_mode(void) {
    591   rgbsps_set(LED_IND_LINUX, COLOR_BLANK);
    592   rgbsps_set(LED_IND_APPLE, COLOR_BLANK);
    593   rgbsps_set(LED_IND_WINDOWS, COLOR_BLANK);
    594 
    595   switch (get_unicode_input_mode()) {
    596     case UNICODE_MODE_LINUX:
    597       rgbsps_set(LED_IND_LINUX, THEME_COLOR_LINUX);
    598       break;
    599     case UNICODE_MODE_MACOS:
    600       rgbsps_set(LED_IND_APPLE, THEME_COLOR_APPLE);
    601       break;
    602     case UNICODE_MODE_WINDOWS:
    603     case UNICODE_MODE_WINCOMPOSE:
    604       rgbsps_set(LED_IND_WINDOWS, THEME_COLOR_WINDOWS);
    605       break;
    606   }
    607   rgbsps_send();
    608 }
    609 
    610 void led_set_output_ble(void) {
    611   rgbsps_set(LED_IND_BLUETOOTH, THEME_COLOR_BLUETOOTH);
    612   rgbsps_set(LED_IND_USB, COLOR_BLANK);
    613   rgbsps_send();
    614 }
    615 
    616 void led_set_output_usb(void) {
    617   rgbsps_set(LED_IND_BLUETOOTH, COLOR_BLANK);
    618   rgbsps_set(LED_IND_USB, THEME_COLOR_USB);
    619   rgbsps_send();
    620 }
    621 
    622 void led_set_output_none(void) {
    623   rgbsps_set(LED_IND_BLUETOOTH, COLOR_BLANK);
    624   rgbsps_set(LED_IND_USB, COLOR_BLANK);
    625   rgbsps_send();
    626 }
    627 
    628 void led_init(void) {
    629   // turn off all
    630   rgbsps_turnoff();
    631 
    632   // set trackpoint color
    633   rgbsps_set(LED_TRACKPOINT1, THEME_COLOR_TP1);
    634   rgbsps_set(LED_TRACKPOINT2, THEME_COLOR_TP2);
    635   rgbsps_set(LED_TRACKPOINT3, THEME_COLOR_TP3);
    636 
    637   // unicode input mode
    638   led_set_unicode_input_mode();
    639 
    640   // layer indicator
    641   led_set_layer_indicator();
    642   led_set_default_layer_indicator();
    643 
    644   // clicky
    645 #ifdef FAUXCLICKY_ENABLE
    646   if (fauxclicky_enabled) {
    647     rgbsps_set(LED_IND_AUDIO, THEME_COLOR_AUDIO);
    648   } else {
    649     rgbsps_set(LED_IND_AUDIO, COLOR_BLANK);
    650   }
    651 #endif
    652 
    653   rgbsps_send();
    654 }
    655 
    656 
    657 #endif // RGBSPS_ENABLE
    658 
    659 // keymaps
    660 
    661 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    662 
    663 /* Qwerty
    664  * ,-----------------------------------------------------------------------------------.
    665  * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
    666  * |------+------+------+------+------+-------------+------+------+------+------+------|
    667  * | Esc  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   '  |Enter |
    668  * |------+------+------+------+------+------|------+------+------+------+------+------|
    669  * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Shift |
    670  * |------+------+------+------+------+------+------+------+------+------+------+------|
    671  * | Ctrl | Alt  | GUI  | Punc | Num  |    Space    | Fun  |Greek | GUI  |AltGr | Ctrl |
    672  * `-----------------------------------------------------------------------------------'
    673  */
    674 [_QWERTY] = LAYOUT(
    675   KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
    676   KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_QUOT, KC_ENT ,
    677   KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,
    678   KC_LCTL, KC_LALT, KC_LGUI, EMPTY,   NUM,     LSPACE,  RSPACE,  FUN,     GREEK,   KC_RGUI, C_RALT,  KC_RCTL,
    679                                            _______, _______, _______
    680 ),
    681 
    682 /* Dvorak
    683  * ,-----------------------------------------------------------------------------------.
    684  * | Tab  |   '  |   ,  |   .  |   P  |   Y  |   F  |   G  |   C  |   R  |   L  | Bksp |
    685  * |------+------+------+------+------+-------------+------+------+------+------+------|
    686  * | Esc  |   A  |   O  |   E  |   U  |   I  |   D  |   H  |   T  |   N  |   S  |Enter |
    687  * |------+------+------+------+------+------|------+------+------+------+------+------|
    688  * | Shift|   /  |   Q  |   J  |   K  |   X  |   B  |   M  |   W  |   V  |   Z  |Shift |
    689  * |------+------+------+------+------+------+------+------+------+------+------+------|
    690  * | Ctrl | Alt  | GUI  | Punc | Num  |    Space    | Func |Greek | GUI  |AltGr | Ctrl |
    691  * `-----------------------------------------------------------------------------------'
    692  */
    693 #ifdef LAYOUT_DVORAK
    694 [_DVORAK] = LAYOUT(
    695   _______, KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,    KC_F,    KC_G,    KC_C,    KC_R,    KC_L,    _______,
    696   _______, KC_A,    KC_O,    KC_E,    KC_U,    KC_I,    KC_D,    KC_H,    KC_T,    KC_N,    KC_S,    _______,
    697   _______, KC_SLSH, KC_Q,    KC_J,    KC_K,    KC_X,    KC_B,    KC_M,    KC_W,    KC_V,    KC_Z,    _______,
    698   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    699                                            _______, _______, _______
    700 ),
    701 #endif
    702 
    703 /* Colemak
    704  * ,-----------------------------------------------------------------------------------.
    705  * | Tab  |   Q  |   W  |   F  |   P  |   G  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
    706  * |------+------+------+------+------+-------------+------+------+------+------+------|
    707  * | Esc  |   A  |   R  |   S  |   T  |   D  |   H  |   N  |   E  |   I  |   O  |Enter |
    708  * |------+------+------+------+------+------|------+------+------+------+------+------|
    709  * | Shift|   Z  |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  |   /  |Shift |
    710  * |------+------+------+------+------+------+------+------+------+------+------+------|
    711  * | Ctrl | Alt  | GUI  | Punc | Num  |    Space    | Func |Greek | GUI  |AltGr | Ctrl |
    712  * `-----------------------------------------------------------------------------------'
    713  */
    714 
    715 #ifdef LAYOUT_COLEMAK
    716 [_COLEMAK] = LAYOUT(
    717   _______, KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_QUOT, _______,
    718   _______, KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    _______,
    719   _______, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, _______,
    720   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    721                                            _______, _______, _______
    722 ),
    723 #endif
    724 
    725 /* Norman
    726  * ,-----------------------------------------------------------------------------------.
    727  * | Tab  |   Q  |   W  |   D  |   F  |   K  |   J  |   U  |   R  |   L  |   ;  | Bksp |
    728  * |------+------+------+------+------+-------------+------+------+------+------+------|
    729  * | Esc  |   A  |   S  |   E  |   T  |   G  |   Y  |   N  |   I  |   O  |   H  |Enter |
    730  * |------+------+------+------+------+------|------+------+------+------+------+------|
    731  * | Shift|   Z  |   X  |   C  |   V  |   B  |   P  |   M  |   ,  |   .  |   /  |Shift |
    732  * |------+------+------+------+------+------+------+------+------+------+------+------|
    733  * | Ctrl | Alt  | GUI  | Punc | Num  |    Space    | Func |Greek | GUI  |AltGr | Ctrl |
    734  * `-----------------------------------------------------------------------------------'
    735  */
    736 
    737 #ifdef LAYOUT_NORMAN
    738 [_NORMAN] = LAYOUT(
    739   _______, KC_Q,    KC_W,    KC_D,    KC_F,    KC_K,    KC_J,    KC_U,    KC_R,    KC_L,    KC_QUOT, _______,
    740   _______, KC_A,    KC_S,    KC_E,    KC_T,    KC_G,    KC_Y,    KC_N,    KC_I,    KC_O,    KC_H,    _______,
    741   _______, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_P,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, _______,
    742   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    743                                            _______, _______, _______
    744 ),
    745 #endif
    746 
    747 /* Workman
    748  * ,-----------------------------------------------------------------------------------.
    749  * | Tab  |   Q  |   D  |   R  |   W  |   B  |   J  |   F  |   U  |   P  |   ;  | Bksp |
    750  * |------+------+------+------+------+-------------+------+------+------+------+------|
    751  * | Esc  |   A  |   S  |   H  |   T  |   G  |   Y  |   N  |   E  |   O  |   I  |Enter |
    752  * |------+------+------+------+------+------|------+------+------+------+------+------|
    753  * | Shift|   Z  |   X  |   M  |   C  |   V  |   K  |   K  |   ,  |   .  |   /  |Shift |
    754  * |------+------+------+------+------+------+------+------+------+------+------+------|
    755  * | Ctrl | Alt  | GUI  | Punc | Num  |    Space    | Func |Greek | GUI  |AltGr | Ctrl |
    756  * `-----------------------------------------------------------------------------------'
    757  */
    758 
    759 #ifdef LAYOUT_WORKMAN
    760 [_WORKMAN] = LAYOUT(
    761   _______, KC_Q,    KC_D,    KC_R,    KC_W,    KC_B,    KC_J,    KC_F,    KC_U,    KC_P,    KC_QUOT, _______,
    762   _______, KC_A,    KC_S,    KC_H,    KC_T,    KC_G,    KC_Y,    KC_N,    KC_E,    KC_O,    KC_I,    _______,
    763   _______, KC_Z,    KC_X,    KC_M,    KC_C,    KC_V,    KC_K,    KC_L,    KC_COMM, KC_DOT,  KC_SLSH, _______,
    764   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    765                                            _______, _______, _______
    766 ),
    767 #endif
    768 
    769 /* Punc
    770  * ,-----------------------------------------------------------------------------------.
    771  * |   ~  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   ≤  |   ≥  |   `  |
    772  * |------+------+------+------+------+-------------+------+------+------+------+------|
    773  * |      |   *  |   \  |   -  |   =  |   /  |   ≠  |   (  |   )  |   <  |   >  |      |
    774  * |------+------+------+------+------+------|------+------+------+------+------+------|
    775  * |   &  |   ^  |   |  |   _  |   +  |   ?  |   ±  |   [  |   ]  |   {  |   }  |      |
    776  * |------+------+------+------+------+------+------+------+------+------+------+------|
    777  * |      |      |      |      |      |             |      |      |      |   :  |      |
    778  * `-----------------------------------------------------------------------------------'
    779  */
    780 [_PUNC] = LAYOUT(
    781   KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, UM(LTEQ), UM(GTEQ), _______,
    782   KC_GRV,  KC_ASTR, KC_BSLS, KC_MINS,  KC_EQL, KC_SLSH, UM(NOTEQ),KC_LPRN, KC_RPRN, KC_LABK, KC_RABK, _______,
    783   KC_AMPR, KC_CIRC, KC_PIPE, KC_UNDS, KC_PLUS, KC_QUES, UM(PLMIN),KC_LBRC, KC_RBRC, KC_LCBR, KC_RCBR, _______,
    784   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_COLN, _______,
    785                                            _______, _______, _______
    786 ),
    787 
    788 /* Num
    789  * ,-----------------------------------------------------------------------------------.
    790  * |   ~  |   !  |   @  |   #  |   $  |   %  |   A  |   7  |   8  |   9  |   D  |      |
    791  * |------+------+------+------+------+-------------+------+------+------+------+------|
    792  * |   `  |   *  |   \  |   -  |   =  |   /  |   B  |   4  |   5  |   6  |   E  |      |
    793  * |------+------+------+------+------+------|------+------+------+------+------+------|
    794  * |   &  |   ^  |   |  |   _  |   +  |   ?  |   C  |   1  |   2  |   3  |   F  |      |
    795  * |------+------+------+------+------+------+------+------+------+------+------+------|
    796  * |      |      |   x  |      |      |      |      |   0  |   ,  |   .  |   :  |      |
    797  * `-----------------------------------------------------------------------------------'
    798  */
    799 [_NUM] = LAYOUT(
    800   KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, S(KC_A),  KC_1,    KC_2,    KC_3,   S(KC_D), _______,
    801   KC_GRV,  KC_ASTR, KC_BSLS, KC_MINS,  KC_EQL, KC_SLSH, S(KC_B),  KC_4,    KC_5,    KC_6,   S(KC_E), _______,
    802   KC_AMPR, KC_CIRC, KC_PIPE, KC_UNDS, KC_PLUS, KC_QUES, S(KC_C),  KC_7,    KC_8,    KC_9,   S(KC_F), _______,
    803   _______, _______, KC_X,    _______, _______, _______, _______,  FUN0 ,   KC_COMM, KC_DOT, KC_COLN, _______,
    804                                            _______, _______, _______
    805 ),
    806 
    807 /* Func
    808  * ,-----------------------------------------------------------------------------------.
    809  * |      |  F1  |  F2  |  F3  |  F4  | Ins  |      | PgUp |  Up  | PgDn | PgUp |      |
    810  * |------+------+------+------+------+-------------+------+------+------+------+------|
    811  * | Caps |  F5  |  F6  |  F7  |  F8  |PrtSc |      | Left | Down | Right| PgDn |      |
    812  * |------+------+------+------+------+------|------+------+------+------+------+------|
    813  * |      |  F9  |  F10 |  F11 |  F12 |Pause |      |      | Home |  End |      |      |
    814  * |------+------+------+------+------+------+------+------+------+------+------+------|
    815  * |      |      |      |      |      |             |      |      |      |      |      |
    816  * `-----------------------------------------------------------------------------------'
    817  */
    818 [_FUN] = LAYOUT(
    819   XXXXXXX,   KC_F1,   KC_F2,   KC_F3,  KC_F4,   KC_INS,  XXXXXXX, KC_PGUP,   KC_UP, KC_PGDN, KC_PGUP, KC_DEL,
    820   KC_CAPS,   KC_F5,   KC_F6,   KC_F7,  KC_F8,   KC_PSCR, XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, _______,
    821   _______,   KC_F9,  KC_F10,  KC_F11,  KC_F12,  KC_PAUS, XXXXXXX, XXXXXXX, KC_HOME,  KC_END, XXXXXXX, _______,
    822   _______, _______, _______, _______,  _______, _______, _______, _______, _______, _______, _______, _______,
    823                                            _______, _______, _______
    824 ),
    825 
    826 /* Uppercase Greek
    827  * ,-----------------------------------------------------------------------------------.
    828  * |      |      |      |      |      |      |      |      |      |      |      |      |
    829  * |------+------+------+------+------+-------------+------+------+------+------+------|
    830  * |      |      |      |      |      |      |      |      |      |      |      |      |
    831  * |------+------+------+------+------+------+------+------+------+------+------+------|
    832  * |      |      |      |      |      |      |      |      |      |      |      |      |
    833  * |------+------+------+------+------+------+------+------+------+------+------+------|
    834  * |      |      |      |      |      |      |      |      |      |      |      |      |
    835  * `-----------------------------------------------------------------------------------'
    836  */
    837 [_GREEKU] = LAYOUT(
    838   _______, XXXXXXX, XXXXXXX,UM(UEPSI), UM(URHO), UM(UTAU),UM(UUPSI),UM(UTHET),UM(UIOTA),UM(UOMIC),  UM(UPI), _______,
    839   _______,UM(UALPH),UM(USIGM),UM(UDELT), UM(UPHI),UM(UGAMM), UM(UETA),  UM(UXI),UM(UKAPP),UM(ULAMB), KC_QUOT, _______,
    840   _______,UM(UZETA), UM(UCHI), UM(UPSI),UM(UOMEG),UM(UBETA),  UM(UNU),  UM(UMU), KC_COMM, KC_DOT,  KC_SLSH, _______,
    841   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    842                                            _______, _______, _______
    843 ),
    844 
    845 /* Lowercase Greek
    846  * ,-----------------------------------------------------------------------------------.
    847  * |      |      |      |      |      |      |      |      |      |      |      |      |
    848  * |------+------+------+------+------+-------------+------+------+------+------+------|
    849  * |      |      |      |      |      |      |      |      |      |      |      |      |
    850  * |------+------+------+------+------+------+------+------+------+------+------+------|
    851  * |      |      |      |      |      |      |      |      |      |      |      |      |
    852  * |------+------+------+------+------+------+------+------+------+------+------+------|
    853  * |      |      |      |      |      |      |      |      |      |      |      |      |
    854  * `-----------------------------------------------------------------------------------'
    855  */
    856 [_GREEKL] = LAYOUT(
    857   _______, XXXXXXX,UM(FSIGM),UM(LEPSI), UM(LRHO), UM(LTAU),UM(LUPSI),UM(LTHET),UM(LIOTA),UM(LOMIC),  UM(LPI), _______,
    858   _______,UM(LALPH),UM(LSIGM),UM(LDELT), UM(LPHI),UM(LGAMM), UM(LETA),  UM(LXI),UM(LKAPP),UM(LLAMB), KC_QUOT, _______,
    859   _______,UM(LZETA), UM(LCHI), UM(LPSI),UM(LOMEG),UM(LBETA),  UM(LNU),  UM(LMU), KC_COMM, KC_DOT,  KC_SLSH, _______,
    860   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    861                                            _______, _______, _______
    862 ),
    863 
    864 /* Empty
    865  * ,-----------------------------------------------------------------------------------.
    866  * |      |      |      |      |      |      |      |      |      |      |      |      |
    867  * |------+------+------+------+------+-------------+------+------+------+------+------|
    868  * |      |      |      |      |      |      |      |      |      |      |      |      |
    869  * |------+------+------+------+------+------+------+------+------+------+------+------|
    870  * |      |      |      |      |      |      |      |      |      |      |      |      |
    871  * |------+------+------+------+------+------+------+------+------+------+------+------|
    872  * |      |      |      |      |      |      |      |      |      |      |      |      |
    873  * `-----------------------------------------------------------------------------------'
    874  */
    875 [_EMPTY] = LAYOUT(
    876   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    877   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    878   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    879   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
    880                                            _______, _______, _______
    881 ),
    882 
    883 /* Emoji
    884  * ,-----------------------------------------------------------------------------------.
    885  * |      |      |      |      |      |      |      |      |      |      |      |      |
    886  * |------+------+------+------+------+-------------+------+------+------+------+------|
    887  * |      |      |      |      |      |      |      |      |      |      |      |      |
    888  * |------+------+------+------+------+------+------+------+------+------+------+------|
    889  * |      |      |      |      |      |      |      |      |      |      |      |      |
    890  * |------+------+------+------+------+------+------+------+------+------+------+------|
    891  * |      |      |      |      |      |      |      |      |      |      |      |      |
    892  * `-----------------------------------------------------------------------------------'
    893  */
    894 [_EMOJI] = LAYOUT(
    895   UM(HART2), UM(CRY2),UM(WEARY),UM(EYERT),UM(SMIRK), UM(TJOY),UM(RECYC),UM(UNAMU),UM(MUSIC),UM(OKHND),UM(PENSV), UM(PHEW),
    896   UM(THMUP), UM(PRAY),UM(SMILE),UM(SMIL2),UM(FLUSH), UM(GRIN),UM(HEART),  UM(BYE), UM(KISS),UM(CELEB), UM(COOL),UM(NOEVS),
    897   UM(THMDN),UM(SLEEP), UM(CLAP),  UM(CRY),  UM(VIC),UM(BHART),  UM(SUN),UM(SMEYE), UM(WINK), UM(MOON),UM(CONFU),UM(NOEVH),
    898     UM(POO), UM(EYES), UM(HUNRD),_______, UM(SKULL),UM(HORNS), UM(HALO), UM(FEAR),_______,UM(YUMMY),UM(DISAP),UM(NOEVK),
    899                                            _______, _______, _______
    900 ),
    901 
    902 /* GUI
    903  * ,-----------------------------------------------------------------------------------.
    904  * |      |  D1  |  D2  |  D3  |  D4  |  D5  |  D6  |  D7  |  D8  |  D9  |  D10 |      |
    905  * |------+------+------+------+------+-------------+------+------+------+------+------|
    906  * | Esc  |      | Btab | Esc  | Tab  |      |      | Prev |      | Next |      |      |
    907  * |------+------+------+------+------+------+------+------+------+------+------+------|
    908  * |      |      | Prev | Play | Next |      |      |      |      |      |      |      |
    909  * |------+------+------+------+------+------+------+------+------+------+------+------|
    910  * |      |      |      |      |      |      |      |      |      |      |      |      |
    911  * `-----------------------------------------------------------------------------------'
    912  */
    913 [_GUI] = LAYOUT(
    914   XXXXXXX, G(KC_1), G(KC_2), G(KC_3), G(KC_4), G(KC_5), G(KC_6), G(KC_7), G(KC_8), G(KC_9), G(KC_0), XXXXXXX,
    915   KC_ESC,  XXXXXXX, S(KC_TAB),KC_ESC, KC_TAB,  XXXXXXX, XXXXXXX, KC_WWWB, XXXXXXX, KC_WWWF, XXXXXXX, XXXXXXX,
    916   XXXXXXX, XXXXXXX, KC_VOLD, KC_MUTE, KC_VOLU, KC_SPC,  KC_SPC,  KC_MPRV, KC_MPLY, KC_MNXT, XXXXXXX, XXXXXXX,
    917   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    918                                            _______, _______, _______
    919 ),
    920 
    921 /* Sys
    922  * ,-----------------------------------------------------------------------------------.
    923  * |      |Qwerty| Win  |      |Reset |      |      | USB  |      |      |      |      |
    924  * |------+------+------+------+------+-------------+------+------+------+------+------|
    925  * |      |Audio |      |Dvorak|      | Glow |      |      |WorkMn|Linux |      |      |
    926  * |------+------+------+------+------+------+------+------+------+------+------+------|
    927  * |      |      |      |Colmak|      | BLE  |Norman|MacOS |      |      |      |      |
    928  * |------+------+------+------+------+------+------+------+------+------+------+------|
    929  * |      |      |      |      |      |      |      |      |      |      |      |      |
    930  * `-----------------------------------------------------------------------------------'
    931  */
    932 [_SYS] = LAYOUT(
    933   DB_TOGG, QWERTY,  WIN,     XXXXXXX, QK_BOOT, XXXXXXX, XXXXXXX, OU_USB,  XXXXXXX, XXXXXXX, XXXXXXX, RGBDEMO,
    934   XXXXXXX, FC_TOG,  XXXXXXX, DVORAK,  XXXXXXX, GLOW,    XXXXXXX, XXXXXXX, WORKMAN, LINUX,   XXXXXXX, XXXXXXX,
    935   XXXXXXX, XXXXXXX, XXXXXXX, COLEMAK, XXXXXXX, OU_BT,   NORMAN,  OSX,     XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    936   _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
    937                                            _______, _______, _______
    938 ),
    939 
    940 
    941 };
    942 
    943 void persistent_default_layer_set(uint8_t default_layer) {
    944   set_single_persistent_default_layer(default_layer);
    945 #ifdef RGBSPS_ENABLE
    946   led_set_default_layer_indicator();
    947 #endif
    948 }
    949 
    950 #ifdef DOUBLESPACE_LAYER_ENABLE
    951 void process_doublespace(bool pressed, bool *isactive, bool *otheractive, bool *isemitted) {
    952   if (pressed) {
    953     *isactive = true;
    954     if (*otheractive) {
    955       layer_on(_SPACE);
    956       register_code(KC_LALT);  // sends alt and enter layer
    957       space_layer_entered = true;
    958     }
    959   } else {
    960     *isactive = false;
    961     if (space_layer_entered) {
    962       unregister_code(KC_LALT);  // release alt and exit layer
    963       layer_off(_SPACE);
    964       if (!*otheractive) {
    965         space_layer_entered = false;
    966       }
    967     } else {
    968       if (!*isemitted) {
    969         register_code(KC_SPC);
    970         unregister_code(KC_SPC);
    971       }
    972       *isemitted = false;
    973     }
    974   }
    975 }
    976 #endif
    977 
    978 layer_state_t layer_state_set_user(layer_state_t state)
    979 {
    980   // turn on punc layer if both fun & num are on
    981   if ((state & ((1UL<<_NUM) | (1UL<<_FUN))) == ((1UL<<_NUM) | (1UL<<_FUN))) {
    982     state |= (1UL<<_PUNC);
    983   } else {
    984     state &= ~(1UL<<_PUNC);
    985   }
    986 
    987   // turn on emoji layer if empty and greek layer are on
    988   if (
    989     (state & ((1UL<<_EMPTY) | (1UL<<_GREEKU))) == ((1UL<<_EMPTY) | (1UL<<_GREEKU))
    990     || (state & ((1UL<<_EMPTY) | (1UL<<_GREEKL))) == ((1UL<<_EMPTY) | (1UL<<_GREEKL))
    991   ) {
    992     state |= (1UL<<_EMOJI);
    993   } else {
    994     state &= ~(1UL<<_EMOJI);
    995   }
    996   return state;
    997 }
    998 
    999 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
   1000   static bool lshift = false;
   1001   static bool rshift = false;
   1002   static uint8_t layer = 0;
   1003 
   1004   lshift = keyboard_report->mods & MOD_BIT(KC_LSFT);
   1005   rshift = keyboard_report->mods & MOD_BIT(KC_RSFT);
   1006   layer = get_highest_layer(layer_state);
   1007 
   1008 #ifdef DOUBLESPACE_LAYER_ENABLE
   1009   // double-space: send space immediately if any other key depressed before space is released
   1010   if ((lspace_active ^ rspace_active)
   1011       && keycode != LSPACE
   1012       && keycode != RSPACE
   1013       && record->event.pressed)
   1014   {
   1015     if (lspace_active) {
   1016       if (!lspace_emitted) {
   1017         register_code(KC_SPC);
   1018         unregister_code(KC_SPC);
   1019       }
   1020       lspace_emitted = true;
   1021     }
   1022     if (rspace_active) {
   1023       if (!rspace_emitted) {
   1024         register_code(KC_SPC);
   1025         unregister_code(KC_SPC);
   1026       }
   1027       rspace_emitted = true;
   1028     }
   1029   }
   1030 
   1031   if (layer == _SPACE && keycode != S(KC_TAB) && keycode != KC_TAB && keycode != KC_ESC && keycode != XXXXXXX) {
   1032     if (record->event.pressed) {
   1033       unregister_code(KC_LALT);
   1034     } else {
   1035       register_code(KC_LALT);
   1036     }
   1037   }
   1038 #endif
   1039 
   1040   switch (keycode) {
   1041 
   1042 #ifdef DOUBLESPACE_LAYER_ENABLE
   1043     // double-space enter space layer
   1044     case LSPACE:
   1045       process_doublespace(record->event.pressed, &lspace_active, &rspace_active, &lspace_emitted);
   1046       return false;
   1047       break;
   1048     case RSPACE:
   1049       process_doublespace(record->event.pressed, &rspace_active, &lspace_active, &rspace_emitted);
   1050       return false;
   1051       break;
   1052 #endif
   1053 
   1054     // handle greek layer shift
   1055     case KC_LSFT:
   1056     case KC_RSFT:
   1057       ;
   1058       if (layer == _GREEKU || layer == _GREEKL) {
   1059         if (record->event.pressed) {
   1060           layer_on(_GREEKU);
   1061           layer_off(_GREEKL);
   1062         } else {
   1063           if (lshift ^ rshift) { // if only one shift was pressed
   1064             layer_on(_GREEKL);
   1065             layer_off(_GREEKU);
   1066           }
   1067         }
   1068       }
   1069       return true;
   1070       break;
   1071 
   1072     // press both ctrls to activate SYS layer
   1073     case KC_LCTL:
   1074     case KC_RCTL:
   1075       ;
   1076       bool lctrl = keyboard_report->mods & MOD_BIT(KC_LCTL);
   1077       bool rctrl = keyboard_report->mods & MOD_BIT(KC_RCTL);
   1078       if (record->event.pressed) {
   1079         if (lctrl ^ rctrl) { // if only one ctrl was pressed
   1080           layer_on(_SYS);
   1081         }
   1082       } else {
   1083         layer_off(_SYS);
   1084       }
   1085       return true;
   1086       break;
   1087 
   1088     // QWERTZ style comma and dot: semicolon and colon when shifted
   1089     case KC_COMM:
   1090       if (record->event.pressed) {
   1091         if (lshift || rshift) {
   1092           if (lshift) unregister_code(KC_LSFT);
   1093           if (rshift) unregister_code(KC_RSFT);
   1094           register_code(KC_SCLN);
   1095           unregister_code(KC_SCLN);
   1096           if (lshift) register_code(KC_LSFT);
   1097           if (rshift) register_code(KC_RSFT);
   1098         } else {
   1099           register_code(KC_COMM);
   1100           unregister_code(KC_COMM);
   1101         }
   1102       }
   1103       return false;
   1104       break;
   1105     case KC_DOT:
   1106       if (record->event.pressed) {
   1107         if ((keyboard_report->mods & MOD_BIT(KC_LSFT)) || (keyboard_report->mods & MOD_BIT(KC_RSFT))) {
   1108           register_code(KC_SCLN);
   1109           unregister_code(KC_SCLN);
   1110         } else {
   1111           register_code(KC_DOT);
   1112           unregister_code(KC_DOT);
   1113         }
   1114       }
   1115       return false;
   1116       break;
   1117 
   1118     // layout switchers
   1119     case QWERTY:
   1120       if (record->event.pressed) {
   1121         persistent_default_layer_set(_QWERTY);
   1122       }
   1123       return false;
   1124       break;
   1125 #ifdef LAYOUT_DVORAK
   1126     case DVORAK:
   1127       if (record->event.pressed) {
   1128         persistent_default_layer_set(_DVORAK);
   1129       }
   1130       return false;
   1131       break;
   1132 #endif
   1133 #ifdef LAYOUT_COLEMAK
   1134     case COLEMAK:
   1135       if (record->event.pressed) {
   1136         persistent_default_layer_set(_COLEMAK);
   1137       }
   1138       return false;
   1139       break;
   1140 #endif
   1141 #ifdef LAYOUT_WORKMAN
   1142     case WORKMAN:
   1143       if (record->event.pressed) {
   1144         persistent_default_layer_set(_WORKMAN);
   1145       }
   1146       return false;
   1147       break;
   1148 #endif
   1149 #ifdef LAYOUT_NORMAN
   1150     case NORMAN:
   1151       if (record->event.pressed) {
   1152         persistent_default_layer_set(_NORMAN);
   1153       }
   1154       return false;
   1155       break;
   1156 #endif
   1157 
   1158     // only process Fnumber on key release, and only when layer switcher is still pressed.
   1159     // this is to avoid accidental presses on potentially destructive keys
   1160     case KC_F1 ... KC_F12:
   1161     case KC_PAUS:
   1162     case KC_PSCR:
   1163     case KC_INS:
   1164       if (!record->event.pressed && layer == _FUN) { // key released and still in FUN layer
   1165           register_code(keycode);
   1166           unregister_code(keycode);
   1167       }
   1168       return false;
   1169       break;
   1170 
   1171     // layer switcher
   1172     //
   1173     case GREEK:
   1174       if (record->event.pressed) {
   1175         if (lshift || rshift) {
   1176           layer_on(_GREEKU);
   1177           layer_off(_GREEKL);
   1178         } else {
   1179           layer_on(_GREEKL);
   1180           layer_off(_GREEKU);
   1181         }
   1182       } else {
   1183         layer_off(_GREEKU);
   1184         layer_off(_GREEKL);
   1185       }
   1186       return false;
   1187       break;
   1188 
   1189     // OS switchers
   1190     case LINUX:
   1191       set_unicode_input_mode(UNICODE_MODE_LINUX);
   1192 #ifdef RGBSPS_ENABLE
   1193       led_set_unicode_input_mode();
   1194 #endif
   1195       return false;
   1196       break;
   1197     case WIN:
   1198       set_unicode_input_mode(UNICODE_MODE_WINCOMPOSE);
   1199 #ifdef RGBSPS_ENABLE
   1200       led_set_unicode_input_mode();
   1201 #endif
   1202       return false;
   1203       break;
   1204     case OSX:
   1205       set_unicode_input_mode(UNICODE_MODE_MACOS);
   1206 #ifdef RGBSPS_ENABLE
   1207       led_set_unicode_input_mode();
   1208 #endif
   1209       return false;
   1210       break;
   1211 
   1212     // glow mode changer
   1213 #ifdef RGBSPS_ENABLE
   1214     case GLOW:
   1215       if (record->event.pressed) {
   1216         glow_mode++;
   1217         if (glow_mode > GLOW_FULL) {
   1218           glow_mode = GLOW_NONE;
   1219         }
   1220         led_reset();
   1221         rgbsps_send();
   1222       }
   1223       return false;
   1224       break;
   1225 #endif
   1226 
   1227     // faux clicky indicator
   1228 #ifdef FAUXCLICKY_ENABLE
   1229     case FC_TOG:
   1230 #ifdef RGBSPS_ENABLE
   1231       if (fauxclicky_enabled) {
   1232         rgbsps_set(LED_IND_AUDIO, THEME_COLOR_AUDIO);
   1233       } else {
   1234         rgbsps_set(LED_IND_AUDIO, COLOR_BLANK);
   1235       }
   1236       rgbsps_send();
   1237 #endif
   1238       return true;
   1239       break;
   1240 #endif
   1241 
   1242 #ifdef RGBSPS_DEMO_ENABLE
   1243     case RGBDEMO:
   1244       led_demo();
   1245       return false;
   1246       break;
   1247 #endif
   1248   }
   1249   return true;
   1250 }
   1251 
   1252 void set_output_user(uint8_t output) {
   1253 #ifdef BLUETOOTH_BLUEFRUIT_LE
   1254   switch(output) {
   1255     case OUTPUT_USB:
   1256       led_set_output_usb();
   1257       break;
   1258     case OUTPUT_BLUETOOTH:
   1259       led_set_output_ble();
   1260       break;
   1261     default:
   1262       led_set_output_none();
   1263   }
   1264 #endif
   1265 }
   1266 
   1267 void matrix_init_user(void) {
   1268   wait_ms(500); // give time for usb to initialize
   1269 
   1270   set_unicode_input_mode(UNICODE_MODE_LINUX);
   1271 
   1272 #ifdef RGBSPS_ENABLE
   1273   led_init();
   1274 #endif
   1275 
   1276   // auto detect output on init
   1277 #ifdef BLUETOOTH_BLUEFRUIT_LE
   1278   uint8_t output = auto_detect_output();
   1279   if (output == OUTPUT_USB) {
   1280     set_output(OUTPUT_USB);
   1281   } else {
   1282     set_output(OUTPUT_BLUETOOTH);
   1283   }
   1284 #endif
   1285 }
   1286 
   1287 void turn_off_capslock(void) {
   1288   if (capslock) {
   1289     register_code(KC_CAPS);
   1290     unregister_code(KC_CAPS);
   1291   }
   1292 }
   1293 
   1294 #ifdef RGBSPS_ENABLE
   1295   void matrix_scan_user(void) {
   1296     led_set_layer_indicator();
   1297   }
   1298 
   1299   void battery_poll(uint8_t level) {
   1300     rgbsps_sethsv(LED_IND_BATTERY, level * 120/255, 255, 15);
   1301     rgbsps_send();
   1302   }
   1303 
   1304   bool led_update_user(led_t led_state) {
   1305     bool new_capslock = led_state.caps_lock;
   1306     if (new_capslock ^ capslock) { // capslock state is different
   1307       if ((capslock = new_capslock)) {
   1308         rgbsps_set(LED_IND_CAPSLOCK, THEME_COLOR_CAPSLOCK);
   1309       } else {
   1310         rgbsps_set(LED_IND_CAPSLOCK, COLOR_BLANK);
   1311       }
   1312       rgbsps_send();
   1313     }
   1314     return false;
   1315   }
   1316 #endif
   1317 
   1318 #ifdef PS2_MOUSE_ENABLE
   1319   void ps2_mouse_init_user(void) {
   1320       uint8_t rcv;
   1321 
   1322       // set TrackPoint sensitivity
   1323       PS2_MOUSE_SEND(0xE2, "tpsens: 0xE2");
   1324       PS2_MOUSE_SEND(0x81, "tpsens: 0x81");
   1325       PS2_MOUSE_SEND(0x4A, "tpsens: 0x4A");
   1326       PS2_MOUSE_SEND(0x49, "tpsens: 0x59");
   1327 
   1328       // set TrackPoint Negative Inertia factor
   1329       PS2_MOUSE_SEND(0xE2, "tpnegin: 0xE2");
   1330       PS2_MOUSE_SEND(0x81, "tpnegin: 0x81");
   1331       PS2_MOUSE_SEND(0x4D, "tpnegin: 0x4D");
   1332       PS2_MOUSE_SEND(0x06, "tpnegin: 0x06");
   1333 
   1334       // set TrackPoint speed
   1335       // (transfer function upper plateau speed)
   1336       PS2_MOUSE_SEND(0xE2, "tpsp: 0xE2");
   1337       PS2_MOUSE_SEND(0x81, "tpsp: 0x81");
   1338       PS2_MOUSE_SEND(0x60, "tpsp: 0x60");
   1339       PS2_MOUSE_SEND(0x61, "tpsp: 0x61");
   1340 
   1341       // inquire pts status
   1342       rcv = ps2_host_send(0xE2);
   1343       rcv = ps2_host_send(0x2C);
   1344       rcv = ps2_host_recv_response();
   1345       if ((rcv & 1) == 1) {
   1346         // if on, disable pts
   1347         rcv = ps2_host_send(0xE2);
   1348         rcv = ps2_host_send(0x47);
   1349         rcv = ps2_host_send(0x2C);
   1350         rcv = ps2_host_send(0x01);
   1351       }
   1352   }
   1353 #endif