/* Copyright 2017 Jack Humbert * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PROCESS_UNICODE_COMMON_H #define PROCESS_UNICODE_COMMON_H #include "quantum.h" #ifndef UNICODE_TYPE_DELAY #define UNICODE_TYPE_DELAY 10 #endif __attribute__ ((unused)) static uint8_t input_mode; void set_unicode_input_mode(uint8_t os_target); uint8_t get_unicode_input_mode(void); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); #define UC_OSX 0 // Mac OS X #define UC_LNX 1 // Linux #define UC_WIN 2 // Windows 'HexNumpad' #define UC_BSD 3 // BSD (not implemented) #define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose #define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose #define UC_BSPC UC(0x0008) #define UC_SPC UC(0x0020) #define UC_EXLM UC(0x0021) #define UC_DQUT UC(0x0022) #define UC_HASH UC(0x0023) #define UC_DLR UC(0x0024) #define UC_PERC UC(0x0025) #define UC_AMPR UC(0x0026) #define UC_QUOT UC(0x0027) #define UC_LPRN UC(0x0028) #define UC_RPRN UC(0x0029) #define UC_ASTR UC(0x002A) #define UC_PLUS UC(0x002B) #define UC_COMM UC(0x002C) #define UC_DASH UC(0x002D) #define UC_DOT UC(0x002E) #define UC_SLSH UC(0x002F) #define UC_0 UC(0x0030) #define UC_1 UC(0x0031) #define UC_2 UC(0x0032) #define UC_3 UC(0x0033) #define UC_4 UC(0x0034) #define UC_5 UC(0x0035) #define UC_6 UC(0x0036) #define UC_7 UC(0x0037) #define UC_8 UC(0x0038) #define UC_9 UC(0x0039) #define UC_COLN UC(0x003A) #define UC_SCLN UC(0x003B) #define UC_LT UC(0x003C) #define UC_EQL UC(0x003D) #define UC_GT UC(0x003E) #define UC_QUES UC(0x003F) #define UC_AT UC(0x0040) #define UC_A UC(0x0041) #define UC_B UC(0x0042) #define UC_C UC(0x0043) #define UC_D UC(0x0044) #define UC_E UC(0x0045) #define UC_F UC(0x0046) #define UC_G UC(0x0047) #define UC_H UC(0x0048) #define UC_I UC(0x0049) #define UC_J UC(0x004A) #define UC_K UC(0x004B) #define UC_L UC(0x004C) #define UC_M UC(0x004D) #define UC_N UC(0x004E) #define UC_O UC(0x004F) #define UC_P UC(0x0050) #define UC_Q UC(0x0051) #define UC_R UC(0x0052) #define UC_S UC(0x0053) #define UC_T UC(0x0054) #define UC_U UC(0x0055) #define UC_V UC(0x0056) #define UC_W UC(0x0057) #define UC_X UC(0x0058) #define UC_Y UC(0x0059) #define UC_Z UC(0x005A) #define UC_LBRC UC(0x005B) #define UC_BSLS UC(0x005C) #define UC_RBRC UC(0x005D) #define UC_CIRM UC(0x005E) #define UC_UNDR UC(0x005F) #define UC_GRV UC(0x0060) #define UC_a UC(0x0061) #define UC_b UC(0x0062) #define UC_c UC(0x0063) #define UC_d UC(0x0064) #define UC_e UC(0x0065) #define UC_f UC(0x0066) #define UC_g UC(0x0067) #define UC_h UC(0x0068) #define UC_i UC(0x0069) #define UC_j UC(0x006A) #define UC_k UC(0x006B) #define UC_l UC(0x006C) #define UC_m UC(0x006D) #define UC_n UC(0x006E) #define UC_o UC(0x006F) #define UC_p UC(0x0070) #define UC_q UC(0x0071) #define UC_r UC(0x0072) #define UC_s UC(0x0073) #define UC_t UC(0x0074) #define UC_u UC(0x0075) #define UC_v UC(0x0076) #define UC_w UC(0x0077) #define UC_x UC(0x0078) #define UC_y UC(0x0079) #define UC_z UC(0x007A) #define UC_LCBR UC(0x007B) #define UC_PIPE UC(0x007C) #define UC_RCBR UC(0x007D) #define UC_TILD UC(0x007E) #define UC_DEL UC(0x007F) #endif ='n25' href='#n25'>25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
# How to Customize Your Keyboard's Behavior

For a lot of people a custom keyboard is about more than sending button presses to your computer. You want to be able to do things that are more complex than simple button presses and macros. QMK has hooks that allow you to inject code, override functionality, and otherwise customize how your keyboard behaves in different situations.

This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level.

## A Word on Core vs Keyboards vs Keymap

We have structured QMK as a hierarchy:

* Core (`_quantum`)
  * Keyboard/Revision (`_kb`)
    * Keymap (`_user`)

Each of the functions described below can be defined with a `_kb()` suffix or a `_user()` suffix. We intend for you to use the `_kb()` suffix at the Keyboard/Revision level, while the `_user()` suffix should be used at the Keymap level.

When defining functions at the Keyboard/Revision level it is important that your `_kb()` implementation call `_user()` before executing anything else- otherwise the keymap level function will never be called.

# Custom Keycodes

By far the most common task is to change the behavior of an existing keycode or to create a new keycode. From a code standpoint the mechanism for each is very similar.

## Defining a New Keycode

The first step to creating your own custom keycode(s) is to enumerate them. This means both naming them and assigning a unique number to that keycode. Rather than limit custom keycodes to a fixed range of numbers QMK provides the `SAFE_RANGE` macro. You can use `SAFE_RANGE` when enumerating your custom keycodes to guarantee that you get a unique number.


Here is an example of enumerating 2 keycodes. After adding this block to your `keymap.c` you will be able to use `FOO` and `BAR` inside your keymap.

```c
enum my_keycodes {
  FOO = SAFE_RANGE,
  BAR
};
```

## Programming the Behavior of Any Keycode

When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required.

These function are called every time a key is pressed or released.

### Example `process_record_user()` Implementation

This example does two things. It defines the behavior for a custom keycode called `FOO`, and it supplements our Enter key by playing a tone whenever it is pressed.

```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case FOO:
      if (record->event.pressed) {
        // Do something when pressed
      } else {
        // Do something else when release
      }
      return false; // Skip all further processing of this key
    case KC_ENTER:
      // Play a tone when enter is pressed
      if (record->event.pressed) {
        PLAY_NOTE_ARRAY(tone_qwerty);
      }
      return true; // Let QMK send the enter press/release events
    default:
      return true; // Process all other keycodes normally
  }
}
```

### `process_record_*` Function Documentation

* Keyboard/Revision: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)`
* Keymap: `bool process_record_user(uint16_t keycode, keyrecord_t *record)`

The `keycode` argument is whatever is defined in your keymap, eg `MO(1)`, `KC_L`, etc. You should use a `switch...case` block to handle these events.

The `record` argument contains information about the actual press:

```c
keyrecord_t record {
  keyevent_t event {
    keypos_t key {
      uint8_t col
      uint8_t row
    }
    bool     pressed
    uint16_t time
  }
}
```

# LED Control

This allows you to control the 5 LED's defined as part of the USB Keyboard spec. It will be called when the state of one of those 5 LEDs changes.

* `USB_LED_NUM_LOCK`
* `USB_LED_CAPS_LOCK`
* `USB_LED_SCROLL_LOCK`
* `USB_LED_COMPOSE`
* `USB_LED_KANA`

### Example `led_set_user()` Implementation

```c
void led_set_user(uint8_t usb_led) {
    if (usb_led & (1<<USB_LED_NUM_LOCK)) {
        PORTB |= (1<<0);
    } else {
        PORTB &= ~(1<<0);
    }
    if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
        PORTB |= (1<<1);
    } else {
        PORTB &= ~(1<<1);
    }
    if (usb_led & (1<<USB_LED_SCROLL_LOCK)) {
        PORTB |= (1<<2);
    } else {
        PORTB &= ~(1<<2);
    }
    if (usb_led & (1<<USB_LED_COMPOSE)) {
        PORTB |= (1<<3);
    } else {
        PORTB &= ~(1<<3);
    }
    if (usb_led & (1<<USB_LED_KANA)) {
        PORTB |= (1<<4);