|
diff --git a/common_features.mk b/common_features.mk |
|
index 8c593024f0..d70f360470 100644 |
|
--- a/common_features.mk |
|
+++ b/common_features.mk |
|
@@ -658,40 +658,44 @@ endif |
|
JOYSTICK_ENABLE ?= no |
|
VALID_JOYSTICK_TYPES := analog digital |
|
JOYSTICK_DRIVER ?= analog |
|
ifeq ($(strip $(JOYSTICK_ENABLE)), yes) |
|
ifeq ($(filter $(JOYSTICK_DRIVER),$(VALID_JOYSTICK_TYPES)),) |
|
$(error "$(JOYSTICK_DRIVER)" is not a valid joystick driver) |
|
endif |
|
OPT_DEFS += -DJOYSTICK_ENABLE |
|
SRC += $(QUANTUM_DIR)/process_keycode/process_joystick.c |
|
SRC += $(QUANTUM_DIR)/joystick.c |
|
|
|
ifeq ($(strip $(JOYSTICK_DRIVER)), analog) |
|
OPT_DEFS += -DANALOG_JOYSTICK_ENABLE |
|
SRC += analog.c |
|
endif |
|
ifeq ($(strip $(JOYSTICK_DRIVER)), digital) |
|
OPT_DEFS += -DDIGITAL_JOYSTICK_ENABLE |
|
endif |
|
endif |
|
|
|
+ifeq ($(strip $(APPLE_FN_ENABLE)), yes) |
|
+ OPT_DEFS += -DAPPLE_FN_ENABLE |
|
+endif |
|
+ |
|
USBPD_ENABLE ?= no |
|
VALID_USBPD_DRIVER_TYPES = custom vendor |
|
USBPD_DRIVER ?= vendor |
|
ifeq ($(strip $(USBPD_ENABLE)), yes) |
|
ifeq ($(filter $(strip $(USBPD_DRIVER)),$(VALID_USBPD_DRIVER_TYPES)),) |
|
$(error USBPD_DRIVER="$(USBPD_DRIVER)" is not a valid USBPD driver) |
|
else |
|
OPT_DEFS += -DUSBPD_ENABLE |
|
ifeq ($(strip $(USBPD_DRIVER)), vendor) |
|
# Vendor-specific implementations |
|
OPT_DEFS += -DUSBPD_VENDOR |
|
ifeq ($(strip $(MCU_SERIES)), STM32G4xx) |
|
OPT_DEFS += -DUSBPD_STM32G4 |
|
SRC += usbpd_stm32g4.c |
|
else |
|
$(error There is no vendor-provided USBPD driver available) |
|
endif |
|
else ifeq ($(strip $(USBPD_DRIVER)), custom) |
|
OPT_DEFS += -DUSBPD_CUSTOM |
|
# Board designers can add their own driver to $(SRC) |
|
diff --git a/quantum/action.c b/quantum/action.c |
|
index 5e81efb671..c44eb5cd60 100644 |
|
--- a/quantum/action.c |
|
+++ b/quantum/action.c |
|
@@ -438,40 +438,50 @@ void process_action(keyrecord_t *record, action_t action) { |
|
/* other HID usage */ |
|
case ACT_USAGE: |
|
switch (action.usage.page) { |
|
case PAGE_SYSTEM: |
|
if (event.pressed) { |
|
host_system_send(action.usage.code); |
|
} else { |
|
host_system_send(0); |
|
} |
|
break; |
|
case PAGE_CONSUMER: |
|
if (event.pressed) { |
|
host_consumer_send(action.usage.code); |
|
} else { |
|
host_consumer_send(0); |
|
} |
|
break; |
|
} |
|
break; |
|
#endif |
|
+#ifdef APPLE_FN_ENABLE |
|
+ /* Apple Fn */ |
|
+ case ACT_APPLE_FN: |
|
+ if (event.pressed) { |
|
+ register_code(KC_APPLE_FN); |
|
+ } else { |
|
+ unregister_code(KC_APPLE_FN); |
|
+ } |
|
+ break; |
|
+#endif |
|
#ifdef MOUSEKEY_ENABLE |
|
/* Mouse key */ |
|
case ACT_MOUSEKEY: |
|
if (event.pressed) { |
|
mousekey_on(action.key.code); |
|
} else { |
|
mousekey_off(action.key.code); |
|
} |
|
switch (action.key.code) { |
|
# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) |
|
# ifdef POINTING_DEVICE_ENABLE |
|
case KC_MS_BTN1 ... KC_MS_BTN8: |
|
# else |
|
case KC_MS_BTN1 ... KC_MS_BTN3: |
|
# endif |
|
register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1)); |
|
break; |
|
# endif |
|
default: |
|
mousekey_send(); |
|
@@ -860,40 +870,47 @@ void register_code(uint8_t code) { |
|
// modifiers will be reported incorrectly, see issue #1708 |
|
if (is_key_pressed(keyboard_report, code)) { |
|
del_key(code); |
|
send_keyboard_report(); |
|
} |
|
add_key(code); |
|
send_keyboard_report(); |
|
} |
|
} |
|
else if |
|
IS_MOD(code) { |
|
add_mods(MOD_BIT(code)); |
|
send_keyboard_report(); |
|
} |
|
#ifdef EXTRAKEY_ENABLE |
|
else if |
|
IS_SYSTEM(code) { host_system_send(KEYCODE2SYSTEM(code)); } |
|
else if |
|
IS_CONSUMER(code) { host_consumer_send(KEYCODE2CONSUMER(code)); } |
|
#endif |
|
+#ifdef APPLE_FN_ENABLE |
|
+ else if |
|
+ IS_APPLE_FN(code) { |
|
+ add_key(code); |
|
+ send_keyboard_report(); |
|
+ } |
|
+#endif |
|
#ifdef MOUSEKEY_ENABLE |
|
else if |
|
IS_MOUSEKEY(code) { |
|
mousekey_on(code); |
|
mousekey_send(); |
|
} |
|
#endif |
|
} |
|
|
|
/** \brief Utilities for actions. (FIXME: Needs better description) |
|
* |
|
* FIXME: Needs documentation. |
|
*/ |
|
void unregister_code(uint8_t code) { |
|
if (code == KC_NO) { |
|
return; |
|
} |
|
#ifdef LOCKING_SUPPORT_ENABLE |
|
else if (KC_LOCKING_CAPS_LOCK == code) { |
|
# ifdef LOCKING_RESYNC_ENABLE |
|
@@ -924,40 +941,47 @@ void unregister_code(uint8_t code) { |
|
send_keyboard_report(); |
|
del_key(KC_SCROLL_LOCK); |
|
send_keyboard_report(); |
|
} |
|
#endif |
|
|
|
else if |
|
IS_KEY(code) { |
|
del_key(code); |
|
send_keyboard_report(); |
|
} |
|
else if |
|
IS_MOD(code) { |
|
del_mods(MOD_BIT(code)); |
|
send_keyboard_report(); |
|
} |
|
else if |
|
IS_SYSTEM(code) { host_system_send(0); } |
|
else if |
|
IS_CONSUMER(code) { host_consumer_send(0); } |
|
+#ifdef APPLE_FN_ENABLE |
|
+ else if |
|
+ IS_APPLE_FN(code) { |
|
+ del_key(code); |
|
+ send_keyboard_report(); |
|
+ } |
|
+#endif |
|
#ifdef MOUSEKEY_ENABLE |
|
else if |
|
IS_MOUSEKEY(code) { |
|
mousekey_off(code); |
|
mousekey_send(); |
|
} |
|
#endif |
|
} |
|
|
|
/** \brief Tap a keycode with a delay. |
|
* |
|
* \param code The basic keycode to tap. |
|
* \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it. |
|
*/ |
|
void tap_code_delay(uint8_t code, uint16_t delay) { |
|
register_code(code); |
|
for (uint16_t i = delay; i > 0; i--) { |
|
wait_ms(1); |
|
} |
|
unregister_code(code); |
|
@@ -1134,40 +1158,43 @@ void debug_record(keyrecord_t record) { |
|
* |
|
* FIXME: Needs documentation. |
|
*/ |
|
void debug_action(action_t action) { |
|
switch (action.kind.id) { |
|
case ACT_LMODS: |
|
dprint("ACT_LMODS"); |
|
break; |
|
case ACT_RMODS: |
|
dprint("ACT_RMODS"); |
|
break; |
|
case ACT_LMODS_TAP: |
|
dprint("ACT_LMODS_TAP"); |
|
break; |
|
case ACT_RMODS_TAP: |
|
dprint("ACT_RMODS_TAP"); |
|
break; |
|
case ACT_USAGE: |
|
dprint("ACT_USAGE"); |
|
break; |
|
+ case ACT_APPLE_FN: |
|
+ dprint("ACT_APPLE_FN"); |
|
+ break; |
|
case ACT_MOUSEKEY: |
|
dprint("ACT_MOUSEKEY"); |
|
break; |
|
case ACT_LAYER: |
|
dprint("ACT_LAYER"); |
|
break; |
|
case ACT_LAYER_MODS: |
|
dprint("ACT_LAYER_MODS"); |
|
break; |
|
case ACT_LAYER_TAP: |
|
dprint("ACT_LAYER_TAP"); |
|
break; |
|
case ACT_LAYER_TAP_EXT: |
|
dprint("ACT_LAYER_TAP_EXT"); |
|
break; |
|
case ACT_MACRO: |
|
dprint("ACT_MACRO"); |
|
break; |
|
case ACT_FUNCTION: |
|
dprint("ACT_FUNCTION"); |
|
diff --git a/quantum/action_code.h b/quantum/action_code.h |
|
index eb18c36ae8..f6ffc0d68a 100644 |
|
--- a/quantum/action_code.h |
|
+++ b/quantum/action_code.h |
|
@@ -34,41 +34,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* ACT_MODS_TAP(001r): |
|
* 001r|mods|0000 0000 Modifiers with OneShot |
|
* 001r|mods|0000 0001 Modifiers with tap toggle |
|
* 001r|mods|0000 00xx (reserved) |
|
* 001r|mods| keycode Modifiers with Tap Key(Dual role) |
|
* |
|
* Other Keys(01xx) |
|
* ---------------- |
|
* ACT_USAGE(0100): TODO: Not needed? |
|
* 0100|00| usage(10) System control(0x80) - General Desktop page(0x01) |
|
* 0100|01| usage(10) Consumer control(0x01) - Consumer page(0x0C) |
|
* 0100|10| usage(10) (reserved) |
|
* 0100|11| usage(10) (reserved) |
|
* |
|
* ACT_MOUSEKEY(0101): TODO: Merge these two actions to conserve space? |
|
* 0101|xxxx| keycode Mouse key |
|
* |
|
* ACT_SWAP_HANDS(0110): |
|
* 0110|xxxx| keycode Swap hands (keycode on tap, or options) |
|
* |
|
- * 0111|xxxx xxxx xxxx (reserved) |
|
+ * ACT_APPLE_FN(0111): |
|
+ * 0111|0000|0000|0000 Apple Fn |
|
* |
|
* Layer Actions(10xx) |
|
* ------------------- |
|
* ACT_LAYER(1000): |
|
* 1000|oo00|pppE BBBB Default Layer Bitwise operation |
|
* oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) |
|
* ppp: 4-bit chunk part(0-7) |
|
* EBBBB: bits and extra bit |
|
* 1000|ooee|pppE BBBB Layer Bitwise Operation |
|
* oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) |
|
* ppp: 4-bit chunk part(0-7) |
|
* EBBBB: bits and extra bit |
|
* ee: on event(01:press, 10:release, 11:both) |
|
* |
|
* ACT_LAYER_MODS(1001): |
|
* 1001|LLLL| mods Layer with modifiers held |
|
* |
|
* ACT_LAYER_TAP(101x): |
|
* 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP] |
|
* 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP] |
|
@@ -89,40 +90,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* 1101|xxxx xxxx xxxx (reserved) |
|
* 1110|xxxx xxxx xxxx (reserved) |
|
* |
|
* ACT_FUNCTION(1111): |
|
* 1111| address(12) Function? |
|
* 1111|opt | id(8) Function? |
|
*/ |
|
enum action_kind_id { |
|
/* Key Actions */ |
|
ACT_MODS = 0b0000, |
|
ACT_LMODS = 0b0000, |
|
ACT_RMODS = 0b0001, |
|
ACT_MODS_TAP = 0b0010, |
|
ACT_LMODS_TAP = 0b0010, |
|
ACT_RMODS_TAP = 0b0011, |
|
/* Other Keys */ |
|
ACT_USAGE = 0b0100, |
|
ACT_MOUSEKEY = 0b0101, |
|
/* One-hand Support */ |
|
ACT_SWAP_HANDS = 0b0110, |
|
+ /* Apple Fn */ |
|
+ ACT_APPLE_FN = 0b0111, |
|
/* Layer Actions */ |
|
ACT_LAYER = 0b1000, |
|
ACT_LAYER_MODS = 0b1001, |
|
ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ |
|
ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */ |
|
/* Extensions */ |
|
ACT_MACRO = 0b1100, |
|
ACT_FUNCTION = 0b1111 |
|
}; |
|
|
|
/** \brief Action Code Struct |
|
* |
|
* NOTE: |
|
* In avr-gcc bit field seems to be assigned from LSB(bit0) to MSB(bit15). |
|
* AVR looks like a little endian in avr-gcc. |
|
* Not portable across compiler/endianness? |
|
* |
|
* Byte order and bit order of 0x1234: |
|
* Big endian: Little endian: |
|
* -------------------- -------------------- |
|
@@ -199,40 +202,41 @@ enum mods_bit { |
|
MOD_RSFT = 0x12, |
|
MOD_RALT = 0x14, |
|
MOD_RGUI = 0x18, |
|
}; |
|
enum mods_codes { |
|
MODS_ONESHOT = 0x00, |
|
MODS_TAP_TOGGLE = 0x01, |
|
}; |
|
#define ACTION_KEY(key) ACTION(ACT_MODS, (key)) |
|
#define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | 0) |
|
#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | (key)) |
|
#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | (key)) |
|
#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_ONESHOT) |
|
#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_TAP_TOGGLE) |
|
|
|
/** \brief Other Keys |
|
*/ |
|
enum usage_pages { PAGE_SYSTEM, PAGE_CONSUMER }; |
|
#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id)) |
|
#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id)) |
|
+#define ACTION_APPLE_FN() ACTION(ACT_APPLE_FN, 0) |
|
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key) |
|
|
|
/** \brief Layer Actions |
|
*/ |
|
enum layer_param_on { |
|
ON_PRESS = 1, |
|
ON_RELEASE = 2, |
|
ON_BOTH = 3, |
|
}; |
|
|
|
/** \brief Layer Actions |
|
*/ |
|
enum layer_param_bit_op { |
|
OP_BIT_AND = 0, |
|
OP_BIT_OR = 1, |
|
OP_BIT_XOR = 2, |
|
OP_BIT_SET = 3, |
|
}; |
|
|
|
/** \brief Layer Actions |
|
diff --git a/quantum/keycode.h b/quantum/keycode.h |
|
index 38a29b439b..50699e8d48 100644 |
|
--- a/quantum/keycode.h |
|
+++ b/quantum/keycode.h |
|
@@ -17,40 +17,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
/* |
|
* Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C) |
|
* |
|
* See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf |
|
* or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older) |
|
*/ |
|
|
|
#pragma once |
|
|
|
/* FIXME: Add doxygen comments here */ |
|
|
|
#define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED) |
|
#define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF) |
|
#define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL) |
|
#define IS_MOD(code) (KC_LEFT_CTRL <= (code) && (code) <= KC_RIGHT_GUI) |
|
|
|
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF)) |
|
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) |
|
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID) |
|
+#define IS_APPLE_FN(code) (KC_APFN == (code)) |
|
|
|
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) |
|
|
|
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) |
|
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) |
|
#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) |
|
#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) |
|
#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) |
|
|
|
#define MOD_BIT(code) (1 << MOD_INDEX(code)) |
|
#define MOD_INDEX(code) ((code)&0x07) |
|
|
|
#define MOD_MASK_CTRL (MOD_BIT(KC_LEFT_CTRL) | MOD_BIT(KC_RIGHT_CTRL)) |
|
#define MOD_MASK_SHIFT (MOD_BIT(KC_LEFT_SHIFT) | MOD_BIT(KC_RIGHT_SHIFT)) |
|
#define MOD_MASK_ALT (MOD_BIT(KC_LEFT_ALT) | MOD_BIT(KC_RIGHT_ALT)) |
|
#define MOD_MASK_GUI (MOD_BIT(KC_LEFT_GUI) | MOD_BIT(KC_RIGHT_GUI)) |
|
#define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT) |
|
#define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT) |
|
#define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI) |
|
#define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT) |
|
@@ -196,40 +197,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
#define KC_MNXT KC_MEDIA_NEXT_TRACK |
|
#define KC_MPRV KC_MEDIA_PREV_TRACK |
|
#define KC_MSTP KC_MEDIA_STOP |
|
#define KC_MPLY KC_MEDIA_PLAY_PAUSE |
|
#define KC_MSEL KC_MEDIA_SELECT |
|
#define KC_EJCT KC_MEDIA_EJECT |
|
#define KC_CALC KC_CALCULATOR |
|
#define KC_MYCM KC_MY_COMPUTER |
|
#define KC_WSCH KC_WWW_SEARCH |
|
#define KC_WHOM KC_WWW_HOME |
|
#define KC_WBAK KC_WWW_BACK |
|
#define KC_WFWD KC_WWW_FORWARD |
|
#define KC_WSTP KC_WWW_STOP |
|
#define KC_WREF KC_WWW_REFRESH |
|
#define KC_WFAV KC_WWW_FAVORITES |
|
#define KC_MFFD KC_MEDIA_FAST_FORWARD |
|
#define KC_MRWD KC_MEDIA_REWIND |
|
#define KC_BRIU KC_BRIGHTNESS_UP |
|
#define KC_BRID KC_BRIGHTNESS_DOWN |
|
|
|
+/* Apple Fn */ |
|
+#define KC_APFN KC_APPLE_FN |
|
+ |
|
/* System Specific */ |
|
#define KC_BRMU KC_PAUSE |
|
#define KC_BRMD KC_SCROLL_LOCK |
|
|
|
/* Mouse Keys */ |
|
#define KC_MS_U KC_MS_UP |
|
#define KC_MS_D KC_MS_DOWN |
|
#define KC_MS_L KC_MS_LEFT |
|
#define KC_MS_R KC_MS_RIGHT |
|
#define KC_BTN1 KC_MS_BTN1 |
|
#define KC_BTN2 KC_MS_BTN2 |
|
#define KC_BTN3 KC_MS_BTN3 |
|
#define KC_BTN4 KC_MS_BTN4 |
|
#define KC_BTN5 KC_MS_BTN5 |
|
#define KC_BTN6 KC_MS_BTN6 |
|
#define KC_BTN7 KC_MS_BTN7 |
|
#define KC_BTN8 KC_MS_BTN8 |
|
#define KC_WH_U KC_MS_WH_UP |
|
#define KC_WH_D KC_MS_WH_DOWN |
|
#define KC_WH_L KC_MS_WH_LEFT |
|
@@ -494,40 +498,43 @@ enum internal_special_keycodes { |
|
KC_MEDIA_PREV_TRACK, |
|
KC_MEDIA_STOP, |
|
KC_MEDIA_PLAY_PAUSE, |
|
KC_MEDIA_SELECT, |
|
KC_MEDIA_EJECT, // 0xB0 |
|
KC_MAIL, |
|
KC_CALCULATOR, |
|
KC_MY_COMPUTER, |
|
KC_WWW_SEARCH, |
|
KC_WWW_HOME, |
|
KC_WWW_BACK, |
|
KC_WWW_FORWARD, |
|
KC_WWW_STOP, |
|
KC_WWW_REFRESH, |
|
KC_WWW_FAVORITES, |
|
KC_MEDIA_FAST_FORWARD, |
|
KC_MEDIA_REWIND, |
|
KC_BRIGHTNESS_UP, |
|
KC_BRIGHTNESS_DOWN, |
|
|
|
+ /* Apple Fn */ |
|
+ KC_APPLE_FN, |
|
+ |
|
/* Fn keys */ |
|
KC_FN0 = 0xC0, |
|
KC_FN1, |
|
KC_FN2, |
|
KC_FN3, |
|
KC_FN4, |
|
KC_FN5, |
|
KC_FN6, |
|
KC_FN7, |
|
KC_FN8, |
|
KC_FN9, |
|
KC_FN10, |
|
KC_FN11, |
|
KC_FN12, |
|
KC_FN13, |
|
KC_FN14, |
|
KC_FN15, |
|
KC_FN16, // 0xD0 |
|
KC_FN17, |
|
KC_FN18, |
|
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c |
|
index 5007f15f11..901989790d 100644 |
|
--- a/quantum/keymap_common.c |
|
+++ b/quantum/keymap_common.c |
|
@@ -50,40 +50,45 @@ action_t action_for_keycode(uint16_t keycode) { |
|
action_t action = {}; |
|
uint8_t action_layer, when, mod; |
|
|
|
(void)action_layer; |
|
(void)when; |
|
(void)mod; |
|
|
|
switch (keycode) { |
|
case KC_A ... KC_EXSEL: |
|
case KC_LEFT_CTRL ... KC_RIGHT_GUI: |
|
action.code = ACTION_KEY(keycode); |
|
break; |
|
#ifdef EXTRAKEY_ENABLE |
|
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: |
|
action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); |
|
break; |
|
case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN: |
|
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); |
|
break; |
|
#endif |
|
+#ifdef APPLE_FN_ENABLE |
|
+ case KC_APPLE_FN: |
|
+ action.code = ACTION_APPLE_FN(); |
|
+ break; |
|
+#endif |
|
#ifdef MOUSEKEY_ENABLE |
|
case KC_MS_UP ... KC_MS_ACCEL2: |
|
action.code = ACTION_MOUSEKEY(keycode); |
|
break; |
|
#endif |
|
case KC_TRANSPARENT: |
|
action.code = ACTION_TRANSPARENT; |
|
break; |
|
case QK_MODS ... QK_MODS_MAX:; |
|
// Has a modifier |
|
// Split it up |
|
action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key |
|
break; |
|
#ifndef NO_ACTION_FUNCTION |
|
case KC_FN0 ... KC_FN31: |
|
action.code = keymap_function_id_to_action(FN_INDEX(keycode)); |
|
break; |
|
case QK_FUNCTION ... QK_FUNCTION_MAX:; |
|
// Is a shortcut for function action_layer, pull last 12bits |
|
// This means we have 4,096 FN macros at our disposal |
|
diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c |
|
index 854b59ae48..ed9659f56d 100644 |
|
--- a/tmk_core/protocol/report.c |
|
+++ b/tmk_core/protocol/report.c |
|
@@ -224,54 +224,66 @@ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { |
|
} |
|
|
|
/** \brief del key bit |
|
* |
|
* FIXME: Needs doc |
|
*/ |
|
void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { |
|
if ((code >> 3) < KEYBOARD_REPORT_BITS) { |
|
keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7)); |
|
} else { |
|
dprintf("del_key_bit: can't del: %02X\n", code); |
|
} |
|
} |
|
#endif |
|
|
|
/** \brief add key to report |
|
* |
|
* FIXME: Needs doc |
|
*/ |
|
void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { |
|
+#ifdef APPLE_FN_ENABLE |
|
+ if IS_APPLE_FN(key) { |
|
+ keyboard_report->reserved = 1; |
|
+ return; |
|
+ } |
|
+#endif |
|
#ifdef NKRO_ENABLE |
|
if (keyboard_protocol && keymap_config.nkro) { |
|
add_key_bit(keyboard_report, key); |
|
return; |
|
} |
|
#endif |
|
add_key_byte(keyboard_report, key); |
|
} |
|
|
|
/** \brief del key from report |
|
* |
|
* FIXME: Needs doc |
|
*/ |
|
void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { |
|
+#ifdef APPLE_FN_ENABLE |
|
+ if IS_APPLE_FN(key) { |
|
+ keyboard_report->reserved = 0; |
|
+ return; |
|
+ } |
|
+#endif |
|
#ifdef NKRO_ENABLE |
|
if (keyboard_protocol && keymap_config.nkro) { |
|
del_key_bit(keyboard_report, key); |
|
return; |
|
} |
|
#endif |
|
del_key_byte(keyboard_report, key); |
|
} |
|
|
|
/** \brief clear key from report |
|
* |
|
* FIXME: Needs doc |
|
*/ |
|
void clear_keys_from_report(report_keyboard_t* keyboard_report) { |
|
// not clear mods |
|
#ifdef NKRO_ENABLE |
|
if (keyboard_protocol && keymap_config.nkro) { |
|
memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits)); |
|
return; |
|
} |
|
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c |
|
index a43755f899..116b057ae6 100644 |
|
--- a/tmk_core/protocol/usb_descriptor.c |
|
+++ b/tmk_core/protocol/usb_descriptor.c |
|
@@ -54,44 +54,56 @@ |
|
const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { |
|
# define SHARED_REPORT_STARTED |
|
#else |
|
const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { |
|
#endif |
|
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop |
|
HID_RI_USAGE(8, 0x06), // Keyboard |
|
HID_RI_COLLECTION(8, 0x01), // Application |
|
#ifdef KEYBOARD_SHARED_EP |
|
HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD), |
|
#endif |
|
// Modifiers (8 bits) |
|
HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad |
|
HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control |
|
HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI |
|
HID_RI_LOGICAL_MINIMUM(8, 0x00), |
|
HID_RI_LOGICAL_MAXIMUM(8, 0x01), |
|
HID_RI_REPORT_COUNT(8, 0x08), |
|
HID_RI_REPORT_SIZE(8, 0x01), |
|
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), |
|
+ |
|
+#ifdef APPLE_FN_ENABLE |
|
+ HID_RI_USAGE_PAGE(8, 0xFF), // AppleVendor Top Case |
|
+ HID_RI_USAGE(8, 0x03), // KeyboardFn |
|
+ HID_RI_LOGICAL_MINIMUM(8, 0x00), |
|
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01), |
|
+ HID_RI_REPORT_COUNT(8, 0x01), |
|
+ HID_RI_REPORT_SIZE(8, 0x08), |
|
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), |
|
+#else |
|
// Reserved (1 byte) |
|
HID_RI_REPORT_COUNT(8, 0x01), |
|
HID_RI_REPORT_SIZE(8, 0x08), |
|
HID_RI_INPUT(8, HID_IOF_CONSTANT), |
|
+#endif |
|
+ |
|
// Keycodes (6 bytes) |
|
HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad |
|
HID_RI_USAGE_MINIMUM(8, 0x00), |
|
HID_RI_USAGE_MAXIMUM(8, 0xFF), |
|
HID_RI_LOGICAL_MINIMUM(8, 0x00), |
|
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), |
|
HID_RI_REPORT_COUNT(8, 0x06), |
|
HID_RI_REPORT_SIZE(8, 0x08), |
|
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), |
|
|
|
// Status LEDs (5 bits) |
|
HID_RI_USAGE_PAGE(8, 0x08), // LED |
|
HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock |
|
HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana |
|
HID_RI_REPORT_COUNT(8, 0x05), |
|
HID_RI_REPORT_SIZE(8, 0x01), |
|
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), |
|
// LED padding (3 bits) |
|
HID_RI_REPORT_COUNT(8, 0x01), |
|
HID_RI_REPORT_SIZE(8, 0x03), |
|
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c |
|
index bd0f1c21aa..1f4554647f 100644 |
|
--- a/tmk_core/protocol/vusb/vusb.c |
|
+++ b/tmk_core/protocol/vusb/vusb.c |
|
@@ -408,44 +408,56 @@ void usbFunctionWriteOut(uchar *data, uchar len) { |
|
const PROGMEM uchar shared_hid_report[] = { |
|
# define SHARED_REPORT_STARTED |
|
#else |
|
const PROGMEM uchar keyboard_hid_report[] = { |
|
#endif |
|
0x05, 0x01, // Usage Page (Generic Desktop) |
|
0x09, 0x06, // Usage (Keyboard) |
|
0xA1, 0x01, // Collection (Application) |
|
#ifdef KEYBOARD_SHARED_EP |
|
0x85, REPORT_ID_KEYBOARD, // Report ID |
|
#endif |
|
// Modifiers (8 bits) |
|
0x05, 0x07, // Usage Page (Keyboard/Keypad) |
|
0x19, 0xE0, // Usage Minimum (Keyboard Left Control) |
|
0x29, 0xE7, // Usage Maximum (Keyboard Right GUI) |
|
0x15, 0x00, // Logical Minimum (0) |
|
0x25, 0x01, // Logical Maximum (1) |
|
0x95, 0x08, // Report Count (8) |
|
0x75, 0x01, // Report Size (1) |
|
0x81, 0x02, // Input (Data, Variable, Absolute) |
|
+ |
|
+#ifdef APPLE_FN_ENABLE |
|
+ 0x05, 0xFF, // Usage Page (AppleVendor Top Case) |
|
+ 0x09, 0x03, // Usage (KeyboardFn) |
|
+ 0x15, 0x00, // Logical Minimum (0) |
|
+ 0x25, 0x01, // Logical Maximum (1) |
|
+ 0x95, 0x01, // Report Count (1) |
|
+ 0x75, 0x08, // Report Size (8) |
|
+ 0x81, 0x02, // Input (Data, Variable, Absolute) |
|
+#else |
|
// Reserved (1 byte) |
|
0x95, 0x01, // Report Count (1) |
|
0x75, 0x08, // Report Size (8) |
|
0x81, 0x03, // Input (Constant) |
|
+#endif |
|
+ |
|
// Keycodes (6 bytes) |
|
0x05, 0x07, // Usage Page (Keyboard/Keypad) |
|
0x19, 0x00, // Usage Minimum (0) |
|
0x29, 0xFF, // Usage Maximum (255) |
|
0x15, 0x00, // Logical Minimum (0) |
|
0x26, 0xFF, 0x00, // Logical Maximum (255) |
|
0x95, 0x06, // Report Count (6) |
|
0x75, 0x08, // Report Size (8) |
|
0x81, 0x00, // Input (Data, Array, Absolute) |
|
|
|
// Status LEDs (5 bits) |
|
0x05, 0x08, // Usage Page (LED) |
|
0x19, 0x01, // Usage Minimum (Num Lock) |
|
0x29, 0x05, // Usage Maximum (Kana) |
|
0x95, 0x05, // Report Count (5) |
|
0x75, 0x01, // Report Size (1) |
|
0x91, 0x02, // Output (Data, Variable, Absolute) |
|
// LED padding (3 bits) |
|
0x95, 0x01, // Report Count (1) |
|
0x75, 0x03, // Report Size (3) |