mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2025-12-20 06:50:07 +01:00
When using evdev support the XKB keymap name (with variant) for Dvorak users will be e.g. "US (Dvorak)". The Dvorak layouts are not described in /usr/share/X11/xkb/rules/evdev.xml, so these are not added to ply-keymap-metadata.h / keymap-render.png . For the console-keymap case dvorak is handled specially in: keymap-render.py:normalize_keymaps() ply-keymap-icon.c:ply_keymap_normalize_keymap() mapping all keymap-names with a lowercase dvorak in there to "dvorak", change this special handling to be case-insensitive so that it also works for the xkb-keymap case. Note the keymap-render.py change really is a no-op since keymap-render.py only calls normalize_keymaps() on console-keymaps which are always lower-case. normalize_keymaps() should still be updated though to keep the 2 functions in sync. Link: https://bugzilla.redhat.com/show_bug.cgi?id=2341810 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
119 lines
3.9 KiB
Python
Executable file
119 lines
3.9 KiB
Python
Executable file
#!/usr/bin/python3
|
|
# coding: utf-8
|
|
import cairo
|
|
import subprocess
|
|
import math
|
|
import lxml
|
|
from lxml import etree
|
|
|
|
|
|
FONT_SIZE = 30
|
|
MARGIN = int(FONT_SIZE / 3)
|
|
|
|
#python3-lxml utility is required
|
|
|
|
def get_keymaps():
|
|
xml = etree.XML(bytes(open('/usr/share/X11/xkb/rules/evdev.xml', 'r').read(), encoding="utf-8"))
|
|
keymaps_x11 = xml.xpath('//layout/configItem/description/text()')
|
|
keymaps = subprocess.check_output(["localectl", "list-keymaps"]).decode("utf-8").strip().split()
|
|
|
|
# Note when changing this you MUST keep ply_keymap_normalize_keymap()
|
|
# from src/libply-splash-graphics/ply-keymap-icon.c in sync
|
|
def normalize_keymaps(keymap):
|
|
parts = keymap.replace("_", "-").replace(".", "-").split("-")
|
|
|
|
# Special case for dvorak, E.g. when mixing "us" and "us-dvorak"
|
|
# on machines returning "us" for both is not useful.
|
|
# Presumably users using dvorak now which variant they use
|
|
# so we just describe all dvorak layouts as "dvorak".
|
|
if "dvorak" in keymap.lower():
|
|
return "dvorak"
|
|
|
|
# mac / sun keymaps are prefixes with mac / sun / sun[4-6]t
|
|
for prefix in ["mac", "sun" ]:
|
|
if keymap.startswith(prefix) and len(parts) > 1:
|
|
return parts[1]
|
|
|
|
return parts[0]
|
|
|
|
keymaps = list(map(normalize_keymaps ,keymaps))
|
|
#Remove duplicates
|
|
keymaps_dedupe = []
|
|
for k in keymaps:
|
|
if k not in keymaps_dedupe:
|
|
keymaps_dedupe.append(k)
|
|
|
|
ret = []
|
|
for k in keymaps_dedupe:
|
|
ret.append((k, "PLY_LAYOUT_TERMINAL"))
|
|
for k in keymaps_x11:
|
|
ret.append((k, "PLY_LAYOUT_XKB"))
|
|
return ret
|
|
|
|
|
|
# Calculate size
|
|
sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
|
|
ct = cairo.Context(sf)
|
|
ct.select_font_face("Cantarell", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
|
|
ct.set_font_size(FONT_SIZE)
|
|
|
|
max_height = 0.0
|
|
total_width = 0.0
|
|
for i in get_keymaps():
|
|
text=i[0]
|
|
extents = ct.text_extents(text)
|
|
h = extents.height
|
|
if h > max_height:
|
|
max_height = h
|
|
total_width += extents.width
|
|
total_width += MARGIN * 2
|
|
ascent, descent, _h, _max_x, max_y = ct.font_extents()
|
|
|
|
# Create image
|
|
sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(total_width), int(max_height + MARGIN * 2))
|
|
ct = cairo.Context(sf)
|
|
ct.save()
|
|
ct.set_source_rgba(0, 0, 0, 0)
|
|
ct.set_operator (cairo.OPERATOR_SOURCE)
|
|
ct.paint()
|
|
ct.restore()
|
|
ct.select_font_face("Cantarell", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
|
|
ct.set_font_size(FONT_SIZE)
|
|
ct.set_source_rgba(0.75, 0.75, 0.75, 1.0)
|
|
|
|
ct.move_to(MARGIN, MARGIN + max_height - descent)
|
|
current_x, current_y = (MARGIN, MARGIN + max_height - descent)
|
|
metadata = []
|
|
for km in get_keymaps():
|
|
km_text=km[0]
|
|
km_type=km[1]
|
|
extents = ct.text_extents(km_text)
|
|
ct.show_text(km_text)
|
|
metadata.append((km_text, current_x, extents.width + MARGIN * 2, km_type))
|
|
current_x += extents.width + (MARGIN * 2)
|
|
ct.move_to(current_x, current_y)
|
|
|
|
sf.write_to_png("keymap-render.png")
|
|
|
|
print("/* This file is autogenerated by running:")
|
|
print(" * scripts/keymap-render.py > src/libply-splash-graphics/ply-keymap-metadata.h")
|
|
print(" */")
|
|
print("typedef struct {")
|
|
print(" const char *name;")
|
|
print(" int offset;")
|
|
print(" int width;")
|
|
print(" int type;")
|
|
print("} ply_keymap_metadata_t;")
|
|
print("")
|
|
print("typedef enum {")
|
|
print(" PLY_LAYOUT_TERMINAL,")
|
|
print(" PLY_LAYOUT_XKB,")
|
|
print("} ply_layout_types_t;")
|
|
print("")
|
|
print("static ply_keymap_metadata_t ply_keymap_metadata[] = {")
|
|
|
|
for i in metadata:
|
|
print((" { \"%s\", %d, %d, %s}," % (i[0],i[1],i[2],i[3])))
|
|
|
|
print(" { NULL, } /* End of array marker */ ")
|
|
print("};")
|