Skip to content

Instantly share code, notes, and snippets.

@itspngu
Last active January 21, 2023 21:38
Show Gist options
  • Save itspngu/9159f06153b440a754b33c6d65c5f302 to your computer and use it in GitHub Desktop.
Save itspngu/9159f06153b440a754b33c6d65c5f302 to your computer and use it in GitHub Desktop.
keymap.c file for DZ60 PCB / Including code to facilitate sending nonstandard keys such as those used in some European languages from ANSI boards using "Alt Codes" which would usually be entered through the numpad.
#include "dz60.h"
#define MODS_SHIFT_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
enum custom_keycodes {
KX_UMLAUT_A = SAFE_RANGE,
KX_UMLAUT_O,
KX_UMLAUT_U,
KX_UMLAUT_S,
KX_EURO,
};
bool g_bOsNumLockOn = false;
void led_set_user(uint8_t usb_led) {
// Update saved numlock state
if (usb_led & (1<<USB_LED_NUM_LOCK))
{
g_bOsNumLockOn = true;
}
else
{
g_bOsNumLockOn = false;
}
}
void send_altcode(uint16_t mask, keyrecord_t *record) {
/* Sends the "alt code" defined in mask, i.e. send_altcode(1234)
holds left alt while sending KP_1, KP_2, KP_3 and KP_4 taps,
then releases left alt if it wasn't being held by the user.
NOTE: If your alt code starts with a 0, leave that out, else the
mask will be treated as octal and your firmware won't compile.
send_altcode(123) will output KP_0, KP_1, KP_2 and KP_3. */
// Check & save mod state
static uint8_t lalt_mask;
lalt_mask = keyboard_report->mods & KC_LALT;
// Check & save numlock state
bool bNumLockWasOn = g_bOsNumLockOn;
// Split up the mask into its 4 decimals
static uint16_t kp[4];
kp[0] = mask / 1000;
kp[1] = mask / 100 - kp[0] * 100;
kp[2] = mask / 10 - kp[0] * 1000 - kp[1] * 10;
kp[3] = mask - kp[0] * 1000 - kp[1] * 100 - kp[2] * 10;
// Convert to keycodes
for (uint8_t i=0; i<=3; i++) {
switch(kp[i]) {
case 0:
kp[i] = KC_KP_0; break;
case 1:
kp[i] = KC_KP_1; break;
case 2:
kp[i] = KC_KP_2; break;
case 3:
kp[i] = KC_KP_3; break;
case 4:
kp[i] = KC_KP_4; break;
case 5:
kp[i] = KC_KP_5; break;
case 6:
kp[i] = KC_KP_6; break;
case 7:
kp[i] = KC_KP_7; break;
case 8:
kp[i] = KC_KP_8; break;
case 9:
kp[i] = KC_KP_9; break;
}
}
// Put ALT into pressed state
if (!lalt_mask) {
register_code(KC_LALT);
send_keyboard_report();
}
// If not enabled, enable numlock
if (!bNumLockWasOn) {
register_code(KC_LNUM);
send_keyboard_report();
}
// The send_keyboard_report() spam is not pretty, but necessary.
add_key(kp[0]);
send_keyboard_report();
del_key(kp[0]);
send_keyboard_report();
add_key(kp[1]);
send_keyboard_report();
del_key(kp[1]);
send_keyboard_report();
add_key(kp[2]);
send_keyboard_report();
del_key(kp[2]);
send_keyboard_report();
add_key(kp[3]);
send_keyboard_report();
del_key(kp[3]);
send_keyboard_report();
// If user wasn't pressing ALT, release it
if (!lalt_mask) {
unregister_code(KC_LALT);
}
send_keyboard_report();
// If it wasn't enabled before, disable numlock
if (!bNumLockWasOn) {
unregister_code(KC_LNUM);
send_keyboard_report();
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
static uint8_t shift_mask;
shift_mask = get_mods()&MODS_SHIFT_MASK;
if (record->event.pressed) {
switch(keycode) {
case KX_UMLAUT_A:
if (shift_mask) { // We want a capital version of the German A Umlaut 'cause shift is pressed
unregister_code(KC_LSFT); // Gotta temporarily disable both shift keys, else this whole thing may behave oddly
unregister_code(KC_RSFT);
send_keyboard_report();
send_altcode(196, record); // This is where the magic happens
if (shift_mask &MOD_BIT(KC_LSFT)) register_code(KC_LSFT); // Restore shift keys to previous state
if (shift_mask &MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
send_keyboard_report();
} else {
send_altcode(228, record); // ä
}
return false;
break;
case KX_UMLAUT_O:
if (shift_mask) {
unregister_code(KC_LSFT);
unregister_code(KC_RSFT);
send_keyboard_report();
send_altcode(214, record); // Ö
if (shift_mask &MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
if (shift_mask &MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
send_keyboard_report();
} else {
send_altcode(246, record); // ö
}
return false;
break;
case KX_UMLAUT_U:
if (shift_mask) {
unregister_code(KC_LSFT);
unregister_code(KC_RSFT);
send_keyboard_report();
send_altcode(220, record); // Ü
if (shift_mask &MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
if (shift_mask &MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
send_keyboard_report();
} else {
send_altcode(252, record); // ü
}
return false;
break;
case KX_UMLAUT_S:
send_altcode(223, record); // ß
return false;
break;
case KX_EURO:
send_altcode(128, record); // ß
return false;
break;
}
}
return true;
}
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KEYMAP_2_SHIFTS(
KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_PSCR, F(1),
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
KC_LSFT, KC_BSLS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, F(2), KC_LOCK,
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_SPC, KC_SPC, MO(2), MO(1), KC_LEFT, F(3), KC_RIGHT),
KEYMAP(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KX_EURO, KC_TRNS, KC_TRNS, KC_TRNS, KX_UMLAUT_U, KC_TRNS, KX_UMLAUT_O, KC_TRNS, KC_TRNS, KC_TRNS, RESET,
KC_TRNS, KX_UMLAUT_A, KX_UMLAUT_S, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_INC, RGB_MODE_FORWARD,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_BRTG, BL_DEC, RGB_TOG),
KEYMAP(
KC_TRNS, M(1), M(2), M(3), M(4), M(5), M(6), M(7), M(8), M(9), M(10), M(11), M(12), KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
};
enum function_id {
SHIFT_DEL,
SHIFT_UP,
SHIFT_DOWN,
};
const uint16_t PROGMEM fn_actions[] = {
[0] = 0,
[1] = ACTION_FUNCTION(SHIFT_DEL),
[2] = ACTION_FUNCTION(SHIFT_UP),
[3] = ACTION_FUNCTION(SHIFT_DOWN),
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t shift_esc_shift_mask;
switch (id) {
case SHIFT_DEL:
shift_esc_shift_mask = get_mods()&MODS_SHIFT_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_INS);
send_keyboard_report();
} else {
add_key(KC_DEL);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_INS);
send_keyboard_report();
} else {
del_key(KC_DEL);
send_keyboard_report();
}
}
break;
case SHIFT_UP:
shift_esc_shift_mask = get_mods()&MODS_SHIFT_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_PGUP);
send_keyboard_report();
} else {
add_key(KC_UP);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_PGUP);
send_keyboard_report();
} else {
del_key(KC_UP);
send_keyboard_report();
}
}
break;
case SHIFT_DOWN:
shift_esc_shift_mask = get_mods()&MODS_SHIFT_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_PGDN);
send_keyboard_report();
} else {
add_key(KC_DOWN);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_PGDN);
send_keyboard_report();
} else {
del_key(KC_DOWN);
send_keyboard_report();
}
}
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment