HID Keyboard Layouts
How layouts work
The device sends HID keycodes — physical key positions, not characters. The host OS driver decides what character appears on screen based on its configured keyboard layout. This means the device must know: "to type @ on a host configured with layout X, which physical key do I press?"
That mapping is different for every layout, and must be implemented manually.
Current implementation
Each layout is a dedicated function with a switch over every character:
void hid_layouts_type_string_us(const char *str);
void hid_layouts_type_string_abnt2(const char *str);
Adding a new layout requires writing a new function with its own switch block — code is duplicated across layouts.
Proposed approach: ASCII lookup table
Each layout becomes a 128-entry array indexed directly by the character value. A single generic function handles all layouts.
typedef struct {
uint8_t keycode;
uint8_t modifier;
} hid_key_entry_t;
// One array per layout — pure data, no code duplication
static const hid_key_entry_t s_layout_us[128] = { ... };
static const hid_key_entry_t s_layout_de[128] = { ... };
static const hid_key_entry_t s_layout_fr[128] = { ... };
// Single generic function handles all layouts
void hid_layouts_type_string(const hid_key_entry_t *layout, const char *str);
Lookup is a direct array index (layout[(uint8_t)c]): O(1), branch-free. Each layout costs 256 bytes in flash.
Extended characters outside ASCII (e.g. UTF-8 accented sequences for ABNT2) stay as a small supplemental table searched linearly, since they are few in number.
Registering a new layout
- Add the enum value to
ducky_layout_t in ducky_parser.h.
- Declare the 128-entry
hid_key_entry_t array in hid_layouts.c.
- Add a supplemental table for characters outside ASCII if needed.
- Add the dispatch case in
ducky_parser.c → process_line().
Supported layouts
| Layout |
Enum |
Notes |
| US (QWERTY) |
DUCKY_LAYOUT_US |
Default. Standard ASCII mapping. |
| ABNT2 (Brazil) |
DUCKY_LAYOUT_ABNT2 |
Dead-key accent support, remapped punctuation. |
HID Keyboard Layouts
How layouts work
The device sends HID keycodes — physical key positions, not characters. The host OS driver decides what character appears on screen based on its configured keyboard layout. This means the device must know: "to type
@on a host configured with layout X, which physical key do I press?"That mapping is different for every layout, and must be implemented manually.
Current implementation
Each layout is a dedicated function with a
switchover every character:Adding a new layout requires writing a new function with its own
switchblock — code is duplicated across layouts.Proposed approach: ASCII lookup table
Each layout becomes a 128-entry array indexed directly by the character value. A single generic function handles all layouts.
Lookup is a direct array index (
layout[(uint8_t)c]): O(1), branch-free. Each layout costs 256 bytes in flash.Extended characters outside ASCII (e.g. UTF-8 accented sequences for ABNT2) stay as a small supplemental table searched linearly, since they are few in number.
Registering a new layout
ducky_layout_tinducky_parser.h.hid_key_entry_tarray inhid_layouts.c.ducky_parser.c→process_line().Supported layouts
DUCKY_LAYOUT_USDUCKY_LAYOUT_ABNT2