keysyms: Add missing evdev keys

- Keys from Linux ≤ 2.6.11. Most are TODOs made explicit.
- Add `XF86XK_MonBrightnessAuto` and make `XF86XK_BrightnessAuto` its
  deprecated alias, for consistency with `XF86XK_BrightnessMin`
- Add `XF86XK_LinkPhone` from Linux 6.14
- Add `XF86XK_PerformanceMode" from Linux 6.17
- Fix and improve the keysym generator script

Co-authored-by: Pierre Le Marre <dev@wismill.eu>
Co-authored-by: Kai Uwe Broulik <kde@privat.broulik.de>
Part-of: <https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/merge_requests/103>
This commit is contained in:
Pierre Le Marre 2025-09-26 11:12:58 +02:00
parent 57a10982c1
commit 81931cc0fd
2 changed files with 108 additions and 17 deletions

View file

@ -295,10 +295,68 @@
*/
#define _EVDEVK(_v) (0x10081000 + _v)
/* Use: XF86XK_Eject _EVDEVK(0x0a2) KEY_EJECTCLOSECD */
/* TODO: Use XF86XK_AudioNext? _EVDEVK(0x0a3) KEY_NEXTSONG */
/* TODO: XF86XK_MediaPlayPause? _EVDEVK(0x0a4) KEY_PLAYPAUSE */
/* TODO: Use XF86XK_AudioPrev? _EVDEVK(0x0a5) KEY_PREVIOUSSONG */
/* TODO: Use XF86XK_AudioStop? _EVDEVK(0x0a6) KEY_STOPCD */
/* TODO: Use XF86XK_AudioRecord? _EVDEVK(0x0a7) KEY_RECORD */
/* TODO: Use XF86XK_AudioRewind? _EVDEVK(0x0a8) KEY_REWIND */
/* Use: XF86XK_Phone _EVDEVK(0x0a9) KEY_PHONE */
/* TODO: unclear function _EVDEVK(0x0aa) KEY_ISO */
/* TODO: unclear function _EVDEVK(0x0ab) KEY_CONFIG */
/* Use: XF86XK_HomePage _EVDEVK(0x0ac) KEY_HOMEPAGE */
/* Use: XF86XK_Refresh _EVDEVK(0x0ad) KEY_REFRESH */
/* TODO: unclear function _EVDEVK(0x0ae) KEY_EXIT */
/* TODO: unclear function _EVDEVK(0x0af) KEY_MOVE */
/* TODO: unclear function _EVDEVK(0x0b0) KEY_EDIT */
/* Use: XF86XK_ScrollUp _EVDEVK(0x0b1) KEY_SCROLLUP */
/* Use: XF86XK_ScrollDown _EVDEVK(0x0b2) KEY_SCROLLDOWN */
/* NOTE: Unless there are special actions bound to the keys KEY_KPLEFTPAREN and
* KEY_KPRIGHTPAREN, there is no reason to introduce keypad-specific keysyms */
/* Use: XK_parenleft _EVDEVK(0x0b3) KEY_KPLEFTPAREN */
/* Use: XK_parenright _EVDEVK(0x0b4) KEY_KPRIGHTPAREN */
/* Use: XF86XK_New _EVDEVK(0x0b5) v2.6.14 KEY_NEW */
/* Use: XK_Redo _EVDEVK(0x0b6) v2.6.14 KEY_REDO */
/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
/* Use: XK_F13 _EVDEVK(0x0b7) KEY_F13 */
/* Use: XK_F14 _EVDEVK(0x0b8) KEY_F14 */
/* Use: XK_F15 _EVDEVK(0x0b9) KEY_F15 */
/* Use: XK_F16 _EVDEVK(0x0ba) KEY_F16 */
/* Use: XK_F17 _EVDEVK(0x0bb) KEY_F17 */
/* Use: XK_F18 _EVDEVK(0x0bc) KEY_F18 */
/* Use: XK_F19 _EVDEVK(0x0bd) KEY_F19 */
/* Use: XK_F20 _EVDEVK(0x0be) KEY_F20 */
/* Use: XK_F21 _EVDEVK(0x0bf) KEY_F21 */
/* Use: XK_F22 _EVDEVK(0x0c0) KEY_F22 */
/* Use: XK_F23 _EVDEVK(0x0c1) KEY_F23 */
/* Use: XK_F24 _EVDEVK(0x0c2) KEY_F24 */
/* TODO: Use XF86XK_AudioPlay? _EVDEVK(0x0c8) KEY_PLAYCD */
/* TODO: Use XF86XK_AudioPause? _EVDEVK(0x0c9) KEY_PAUSECD */
/* Use: XF86XK_Launch3 _EVDEVK(0x0ca) KEY_PROG3 */
/* Use: XF86XK_Launch4 _EVDEVK(0x0cb) KEY_PROG4 */
/* NOTE: KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
/* Use: XF86XK_LaunchB _EVDEVK(0x0cc) v2.6.28 KEY_DASHBOARD */
/* Use: XF86XK_Suspend _EVDEVK(0x0cd) KEY_SUSPEND */
/* Use: XF86XK_Close _EVDEVK(0x0ce) KEY_CLOSE */
/* TODO: Use XF86XK_AudioPlay? _EVDEVK(0x0cf) KEY_PLAY */
/* TODO: Use XF86XK_AudioForward? _EVDEVK(0x0d0) KEY_FASTFORWARD */
/* TODO: XF86XK_AudioBassBoost? _EVDEVK(0x0d1) KEY_BASSBOOST */
/* Use: XK_Print _EVDEVK(0x0d2) KEY_PRINT */
/* TODO: headphone or vendor key? _EVDEVK(0x0d3) KEY_HP */
/* Use: XF86XK_WebCam _EVDEVK(0x0d4) KEY_CAMERA */
/* TODO: unclear function _EVDEVK(0x0d5) KEY_SOUND */
/* TODO: unclear function _EVDEVK(0x0d6) KEY_QUESTION */
/* Use: XF86XK_Mail _EVDEVK(0x0d7) KEY_EMAIL */
/* Use: XF86XK_Messenger _EVDEVK(0x0d8) KEY_CHAT */
/* Use: XF86XK_Search _EVDEVK(0x0d9) KEY_SEARCH */
/* TODO: unclear function _EVDEVK(0x0da) KEY_CONNECT */
/* Use: XF86XK_Finance _EVDEVK(0x0db) KEY_FINANCE */
#define XF86XK_Sport _EVDEVK(0x0dc) /* KEY_SPORT */
/* Use: XF86XK_Shop _EVDEVK(0x0dd) KEY_SHOP */
/* TODO: unclear function _EVDEVK(0x0de) KEY_ALTERASE */
/* Use: XK_Cancel _EVDEVK(0x0df) KEY_CANCEL */
/* Use: XF86XK_MonBrightnessDown _EVDEVK(0x0e0) KEY_BRIGHTNESSDOWN */
/* Use: XF86XK_MonBrightnessUp _EVDEVK(0x0e1) KEY_BRIGHTNESSUP */
/* Use: XF86XK_AudioMedia _EVDEVK(0x0e2) KEY_MEDIA */
/* Use: XF86XK_Display _EVDEVK(0x0e3) v2.6.12 KEY_SWITCHVIDEOMODE */
/* Use: XF86XK_KbdLightOnOff _EVDEVK(0x0e4) v2.6.12 KEY_KBDILLUMTOGGLE */
/* Use: XF86XK_KbdBrightnessDown _EVDEVK(0x0e5) v2.6.12 KEY_KBDILLUMDOWN */
@ -312,10 +370,12 @@
/* Use: XF86XK_Bluetooth _EVDEVK(0x0ed) v2.6.19 KEY_BLUETOOTH */
/* Use: XF86XK_WLAN _EVDEVK(0x0ee) v2.6.19 KEY_WLAN */
/* Use: XF86XK_UWB _EVDEVK(0x0ef) v2.6.24 KEY_UWB */
/* Use: NoSymbol _EVDEVK(0x0f0) KEY_UNKNOWN */
/* Use: XF86XK_Next_VMode _EVDEVK(0x0f1) v2.6.23 KEY_VIDEO_NEXT */
/* Use: XF86XK_Prev_VMode _EVDEVK(0x0f2) v2.6.23 KEY_VIDEO_PREV */
/* Use: XF86XK_MonBrightnessCycle _EVDEVK(0x0f3) v2.6.23 KEY_BRIGHTNESS_CYCLE */
#define XF86XK_BrightnessAuto _EVDEVK(0x0f4) /* v3.16 KEY_BRIGHTNESS_AUTO */
#define XF86XK_BrightnessAuto _EVDEVK(0x0f4) /* Deprecated alias for XF86XK_MonBrightnessAuto */
#define XF86XK_MonBrightnessAuto _EVDEVK(0x0f4) /* v3.16 KEY_BRIGHTNESS_AUTO */
#define XF86XK_DisplayOff _EVDEVK(0x0f5) /* v2.6.23 KEY_DISPLAY_OFF */
/* Use: XF86XK_WWAN _EVDEVK(0x0f6) v3.13 KEY_WWAN */
/* Use: XF86XK_RFKill _EVDEVK(0x0f7) v2.6.33 KEY_RFKILL */
@ -415,8 +475,32 @@
#define XF86XK_NotificationCenter _EVDEVK(0x1bc) /* v5.10 KEY_NOTIFICATION_CENTER */
#define XF86XK_PickupPhone _EVDEVK(0x1bd) /* v5.10 KEY_PICKUP_PHONE */
#define XF86XK_HangupPhone _EVDEVK(0x1be) /* v5.10 KEY_HANGUP_PHONE */
#define XF86XK_LinkPhone _EVDEVK(0x1bf) /* v6.14 KEY_LINK_PHONE */
/* TODO: XF86XK_DeleteToEndOfLine? _EVDEVK(0x1c0) KEY_DEL_EOL */
/* TODO: XF86XK_DeleteToEndOfScreen? _EVDEVK(0x1c1) KEY_DEL_EOS */
/* TODO: XF86XK_InsertLine? _EVDEVK(0x1c2) KEY_INS_LINE */
/* TODO: XF86XK_DeleteLine? _EVDEVK(0x1c3) KEY_DEL_LINE */
#define XF86XK_Fn _EVDEVK(0x1d0) /* KEY_FN */
#define XF86XK_Fn_Esc _EVDEVK(0x1d1) /* KEY_FN_ESC */
#define XF86XK_Fn_F1 _EVDEVK(0x1d2) /* KEY_FN_F1 */
#define XF86XK_Fn_F2 _EVDEVK(0x1d3) /* KEY_FN_F2 */
#define XF86XK_Fn_F3 _EVDEVK(0x1d4) /* KEY_FN_F3 */
#define XF86XK_Fn_F4 _EVDEVK(0x1d5) /* KEY_FN_F4 */
#define XF86XK_Fn_F5 _EVDEVK(0x1d6) /* KEY_FN_F5 */
#define XF86XK_Fn_F6 _EVDEVK(0x1d7) /* KEY_FN_F6 */
#define XF86XK_Fn_F7 _EVDEVK(0x1d8) /* KEY_FN_F7 */
#define XF86XK_Fn_F8 _EVDEVK(0x1d9) /* KEY_FN_F8 */
#define XF86XK_Fn_F9 _EVDEVK(0x1da) /* KEY_FN_F9 */
#define XF86XK_Fn_F10 _EVDEVK(0x1db) /* KEY_FN_F10 */
#define XF86XK_Fn_F11 _EVDEVK(0x1dc) /* KEY_FN_F11 */
#define XF86XK_Fn_F12 _EVDEVK(0x1dd) /* KEY_FN_F12 */
#define XF86XK_Fn_1 _EVDEVK(0x1de) /* KEY_FN_1 */
#define XF86XK_Fn_2 _EVDEVK(0x1df) /* KEY_FN_2 */
#define XF86XK_Fn_D _EVDEVK(0x1e0) /* KEY_FN_D */
#define XF86XK_Fn_E _EVDEVK(0x1e1) /* KEY_FN_E */
#define XF86XK_Fn_F _EVDEVK(0x1e2) /* KEY_FN_F */
#define XF86XK_Fn_S _EVDEVK(0x1e3) /* KEY_FN_S */
#define XF86XK_Fn_B _EVDEVK(0x1e4) /* KEY_FN_B */
#define XF86XK_FnRightShift _EVDEVK(0x1e5) /* v5.10 KEY_FN_RIGHT_SHIFT */
/* Use: XK_braille_dot_1 _EVDEVK(0x1f1) v2.6.17 KEY_BRL_DOT1 */
/* Use: XK_braille_dot_2 _EVDEVK(0x1f2) v2.6.17 KEY_BRL_DOT2 */
@ -563,4 +647,5 @@
#define XF86XK_KbdLcdMenu3 _EVDEVK(0x2ba) /* v5.5 KEY_KBD_LCD_MENU3 */
#define XF86XK_KbdLcdMenu4 _EVDEVK(0x2bb) /* v5.5 KEY_KBD_LCD_MENU4 */
#define XF86XK_KbdLcdMenu5 _EVDEVK(0x2bc) /* v5.5 KEY_KBD_LCD_MENU5 */
#define XF86XK_PerformanceMode _EVDEVK(0x2bd) /* v6.17 KEY_PERFORMANCE */
#undef _EVDEVK

View file

@ -42,12 +42,12 @@ def die(msg):
sys.exit(1)
def all_keysyms(directory):
def all_keysyms(directory) -> set[str]:
"""
Extract the key names for all keysyms we have in our repo and return
them as list.
"""
keysym_names = []
keysym_names: set[str] = set()
pattern = re.compile(
r"^#define\s+(?P<name>\w+)\s+(0x[0-9A-Fa-f]+|_EVDEVK\(0x([0-9A-Fa-f]{3}))"
)
@ -56,7 +56,7 @@ def all_keysyms(directory):
for line in fd:
match = re.match(pattern, line)
if match:
keysym_names.append(match.group("name"))
keysym_names.add(match.group("name"))
return keysym_names
@ -193,11 +193,12 @@ def verify(ns):
expected_pattern = re.compile(
r"#define XF86XK_\w+ +_EVDEVK\(0x([0-9A-Fa-f]{3})\) +"
r"/\* (?:(?P<kernel_version>v[2-6]\.[0-9]+(\.[0-9]+)?)? +KEY_\w+|"
r"(?P<alias>Alias for XF86XK_\w+)) \*/"
r"(?P<alias>(?:Deprecated a|A)lias for XF86XK_\w+)) \*/"
)
# This is the comment pattern we expect
expected_comment_pattern = re.compile(
r"/\* Use: (?P<name>\w+) +_EVDEVK\(0x(?P<value>[0-9A-Fa-f]{3})\) + "
r"/\* (?:Use: (?P<name>\w+)|NOTE.+|TODO.*) +"
r"_EVDEVK\(0x(?P<value>[0-9A-Fa-f]{3})\) + "
r"(v[2-6]\.[0-9]+(\.[0-9]+)?)? +KEY_\w+ \*/"
)
@ -206,9 +207,10 @@ def verify(ns):
name_pattern = re.compile(r"#define (XF86XK_[^\s]*)")
space_check = re.compile(r"#define \w+(\s+)[^\s]+(\s+)")
hex_pattern = re.compile(r".*0x([a-f0-9]+).*", re.I)
todo_pattern = re.compile(r"^/\* TODO.*\*/$")
todo_pattern = re.compile(r"^/\* (TODO|NOTE).*\*/$")
comment_format = re.compile(
r".*/\* (?:(?:Deprecated a|A)lias for (\w+)|([^\s]+)?\s+(\w+))"
r".*/\* (?:(?:Deprecated a|A)lias for (?P<alias>\w+)|"
r"(?P<version>[^\s]+)?\s+(?P<key>\w+))"
)
kver_format = re.compile(r"v[2-6]\.[0-9]+(\.[0-9]+)?")
alias_format = re.compile(r"(?:Deprecated a|A)lias for XF86XK_\w+")
@ -220,6 +222,8 @@ def verify(ns):
all_defines = []
all_keysym_names = all_keysyms(ns.header.parent)
# NoSymbol is define in another header
all_keysym_names.add("NoSymbol")
class ParserError(Exception):
pass
@ -228,6 +232,7 @@ def verify(ns):
raise ParserError(f"{msg} in '{line.strip()}'")
last_keycode = 0
last_alias = False
for line in open(ns.header):
try:
if not in_evdev_codes_section:
@ -263,9 +268,9 @@ def verify(ns):
error("Duplicate keycode", line)
last_keycode = keycode
name = match.group("name")
if name not in all_keysym_names:
error(f"Unknown keysym {name}", line)
if name := match.group("name"):
if name not in all_keysym_names:
error(f"Unknown keysym {name}", line)
elif re.match(hex_pattern, line) and not todo_pattern.match(line):
logger.warning(f"Unexpected hex code in {line}")
continue
@ -298,7 +303,7 @@ def verify(ns):
comment = re.match(comment_format, line)
if not comment:
error("Invalid comment format", line)
if alias_target := comment.group(1):
if alias_target := comment.group("alias"):
alias = True
else:
alias = False
@ -322,7 +327,7 @@ def verify(ns):
keycode = int(match.group(1), 16)
if keycode < last_keycode:
error("Keycode must be ascending", line)
if keycode == last_keycode and not alias:
if keycode == last_keycode and not (alias or last_keycode):
error("Duplicate keycode", line)
# May cause a false positive for old libevdev if KEY_MAX is bumped
@ -330,6 +335,7 @@ def verify(ns):
error("Keycode outside range", line)
last_keycode = keycode
last_alias = alias
except ParserError as e:
logger.error(e)
success = False
@ -359,13 +365,13 @@ def add_keysyms(ns):
# 3-digit hexcode in brackets and use that as keycode.
pattern = re.compile(r".*_EVDEVK\((0x[0-9A-Fa-f]{3})\).*")
max_code = max(
[
(
c.value
for c in libevdev.EV_KEY.codes
if c.is_defined
and c != libevdev.EV_KEY.KEY_MAX
and not c.name.startswith("BTN")
]
)
)
def defined_keycodes(path):
@ -386,7 +392,7 @@ def add_keysyms(ns):
else:
if re.match(r"#undef _EVDEVK\n", line):
in_evdev_codes_section = False
yield max_code
yield max_code + 1 # Upper bound of range()
else:
match = re.match(pattern, line)
if match: