Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keysyms: improve generator #364

Merged
merged 3 commits into from
Sep 20, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 63 additions & 25 deletions scripts/makeheader
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,63 @@ from __future__ import print_function
import re
import os

# expected format:
# #define XF86XK_FooBar _EVDEVK(0x123) /* some optional comment */
evdev_pattern = re.compile(r'^#define\s+XF86XK_(?P<name>\w+)\s+_EVDEVK\((?P<value>0x[0-9A-Fa-f]+)\)')
# Expected format:
# #define XF86XK_FooBar 0x1234 /* some optional comment */
# or:
# #define XF86XK_FooBar _EVDEVK(0x123) /* some optional comment */
# We also need to match commented evdev entries:
# /* Use: XF86XK_FooBar _EVDEVK(0x123) some optional comment */
keysym_entry_pattern = re.compile(
r"""^
(?P<define>\#define|/\*\s+Use:)\s+
(?P<prefix>\w*)XK_(?P<name>\w+)(?P<spacing>\s+)
(?P<evdev>_EVDEVK\()?(?P<value>0x[0-9A-Fa-f]+)(?(evdev)\))
""",
re.VERBOSE,
)

prefix = os.environ.get('X11_HEADERS_PREFIX', '/usr')
# Match remaining XK_ references in the comments, e.g we will replace:
# XF86XK_CamelCaseKernelName _EVDEVK(kernel value)
# #define XKB_KEY_SunCompose 0x0000FF20 /* Same as XK_Multi_key */
# with:
# XKB_KEY_XF86CamelCaseKernelName _EVDEVK(kernel value)
# #define XKB_KEY_SunCompose 0x0000FF20 /* Same as XKB_KEY_Multi_key */
xorgproto_keysym_prefix_pattern = re.compile(r"\b(?P<prefix>\w*)XK_(?!KOREAN\b)")


def make_keysym_entry(m: re.Match[str]) -> str:
"""
Perform the substitutions
"""
if m.group("evdev"):
if m.group("define").startswith("#"):
# Replace the xorgproto _EVDEVK macro with the actual value:
# 0x10081000 is the base, the evdev hex code is added to that.
# We replace to make parsing of the keys later easier.
whot marked this conversation as resolved.
Show resolved Hide resolved
value = 0x10081000 + int(m.group("value"), 16)
value_str = f"{value:#x} "
else:
value_str = f"""_EVDEVK({m.group('value')})"""
else:
value_str = m.group("value")
define = m.group("define")
prefix = m.group("prefix") or ""
name = m.group("name")
spacing = m.group("spacing")
return f"""{define} XKB_KEY_{prefix}{name}{spacing}{value_str}"""


prefix = os.environ.get("X11_HEADERS_PREFIX", "/usr")
HEADERS = [
prefix + '/include/X11/keysymdef.h',
prefix + '/include/X11/XF86keysym.h',
prefix + '/include/X11/Sunkeysym.h',
prefix + '/include/X11/DECkeysym.h',
prefix + '/include/X11/HPkeysym.h',
prefix + "/include/X11/keysymdef.h",
prefix + "/include/X11/XF86keysym.h",
prefix + "/include/X11/Sunkeysym.h",
prefix + "/include/X11/DECkeysym.h",
prefix + "/include/X11/HPkeysym.h",
]

print('''#ifndef _XKBCOMMON_KEYSYMS_H
print(
"""#ifndef _XKBCOMMON_KEYSYMS_H
#define _XKBCOMMON_KEYSYMS_H

/* This file is autogenerated; please do not commit directly. */
Expand All @@ -27,31 +70,26 @@ print('''#ifndef _XKBCOMMON_KEYSYMS_H
*/

#define XKB_KEY_NoSymbol 0x000000 /* Special KeySym */
''')
"""
)
for path in HEADERS:
with open(path) as header:
for line in header:
if '#ifdef' in line or '#ifndef' in line or '#endif' in line:
if "#ifdef" in line or "#ifndef" in line or "#endif" in line:
continue

# Remove #define _OSF_Keysyms and such.
if '#define _' in line:
if "#define _" in line:
continue

# Handle a duplicate definition in HPkeysyms.h which kicks in if
# it's not already defined.
if 'XK_Ydiaeresis' in line and '0x100000ee' in line:
if "XK_Ydiaeresis" in line and "0x100000ee" in line:
continue

# Replace the xorgproto _EVDEVK macro with the actual value
# 0x10081000 is the base, the evdev hex code is added to that.
# We replace to make parsing of the keys later easier.
match = re.match(evdev_pattern, line)
if match:
value = 0x10081000 + int(match.group('value'), 16)
line = re.sub(r'_EVDEVK\(0x([0-9A-Fa-f]+)\)', '{:#x}'.format(value), line)

line = re.sub(r'#define\s*(\w*)XK_', r'#define XKB_KEY_\1', line)
# Perform _EVDEV and XK_ substitutions
line = keysym_entry_pattern.sub(make_keysym_entry, line)
line = xorgproto_keysym_prefix_pattern.sub(r"XKB_KEY_\1", line)

print(line, end='')
print('\n\n#endif')
print(line, end="")
print("\n\n#endif")