diff --git a/common_features.mk b/common_features.mk index 8ac53ec45a5f..558a32b33fb0 100644 --- a/common_features.mk +++ b/common_features.mk @@ -592,3 +592,7 @@ endif ifeq ($(strip $(JOYSTICK_ENABLE)), digital) OPT_DEFS += -DDIGITAL_JOYSTICK_ENABLE endif + +ifeq ($(strip $(APPLE_FN_ENABLE)), yes) + OPT_DEFS += -DAPPLE_FN_ENABLE +endif diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 570d4798debe..d58ed66ed46a 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -68,6 +68,11 @@ action_t action_for_key(uint8_t layer, keypos_t key) { 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); diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index a7432bae599a..ecb8634fe7fe 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -419,6 +419,16 @@ void process_action(keyrecord_t *record, action_t action) { } 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: @@ -863,6 +873,12 @@ void register_code(uint8_t 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) { @@ -927,6 +943,12 @@ void unregister_code(uint8_t code) { 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) { @@ -1110,6 +1132,9 @@ void debug_action(action_t action) { case ACT_USAGE: dprint("ACT_USAGE"); break; + case ACT_APPLE_FN: + dprint("ACT_APPLE_FN"); + break; case ACT_MOUSEKEY: dprint("ACT_MOUSEKEY"); break; diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index eb18c36ae809..f6ffc0d68a1b 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h @@ -51,7 +51,8 @@ along with this program. If not, see . * 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) * ------------------- @@ -106,6 +107,8 @@ enum action_kind_id { 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, @@ -216,6 +219,7 @@ enum mods_codes { 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 diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h index d35e44d8dc24..26eb55f52f7a 100644 --- a/tmk_core/common/keycode.h +++ b/tmk_core/common/keycode.h @@ -34,6 +34,7 @@ along with this program. If not, see . #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) @@ -191,6 +192,9 @@ along with this program. If not, see . #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_SCROLLLOCK @@ -484,6 +488,9 @@ enum internal_special_keycodes { KC_BRIGHTNESS_UP, KC_BRIGHTNESS_DOWN, + /* Apple Fn */ + KC_APPLE_FN, + /* Fn keys */ KC_FN0 = 0xC0, KC_FN1, diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c index 1bcb6f2adb94..3d41bf186246 100644 --- a/tmk_core/common/report.c +++ b/tmk_core/common/report.c @@ -231,6 +231,12 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { * 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); @@ -245,6 +251,12 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { * 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); diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 7ea4b2e37c4b..efc8f994cc7d 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -71,10 +71,22 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { 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), diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index a422903ccf2e..042aaef1865a 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -401,10 +401,22 @@ const PROGMEM uchar keyboard_hid_report[] = { 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)