diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2021-03-24 11:25:57 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2021-04-06 10:31:25 +1000 |
commit | 327f1258057c45c4f6fbb2133842c30f1969b3ea (patch) | |
tree | ea7ffe807846c20a975bbb02a4c0df4bc343155a | |
parent | 53ab70655064dab0783a2f45c61661e1ded6ac44 (diff) | |
download | libwacom-327f1258057c45c4f6fbb2133842c30f1969b3ea.tar.gz |
tool: change the hwdb generator to the libwacom-update-db tool
Previously, the tool generated the hwdb and the rest was left to the user,
requiring more hand-holding in bug reports and more extensive documentation.
Change this to be a one-stop tool that takes care of all steps required by a
user, so a user can just run this tool with /etc/libwacom as argument and the
hwdb will be updated. Notably: the default invocation with /etc/libwacom an
*auxilary* hwdb based on the user's files rather than writing
out the whole one, overwriting the system one.
This is the 99%-case version of the tool, custom prefixes etc. will not be
handled as well as they can be but that's a niche case anyway and not worth
the effort. The vast majority of users will put the new file in to
/etc/libwacom and have the system installation in /usr/share/libwacom.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | README.md | 64 | ||||
-rw-r--r-- | meson.build | 10 | ||||
-rw-r--r-- | tools/Makefile.am | 10 | ||||
-rwxr-xr-x | tools/libwacom-update-db.py (renamed from tools/generate-hwdb.py) | 109 |
4 files changed, 136 insertions, 57 deletions
@@ -33,46 +33,52 @@ the tablet is not in that list. You must update udev after installing the file, see below. -## To add support for a tablet to an older libwacom +## To add support for a tablet to an installed libwacom If the system-provided libwacom does not include a `.tablet` file, it is possible to "backport" that `.tablet` file to the system-provided libwacom. -Simply copy the `.tablet` file from the upstream git tree into the local -directory `/etc/libwacom/`. Create that directory if necessary. -For versions of libwacom older than 1.9, the file should be copied to -`/usr/share/libwacom`. It may be overwritten on updates. - -You must update udev after installing the file, see below. - -## Updating udev's hwdb - -The new device must be added to the udev hwdb to ensure all required udev -properties are set. Without a hwdb entry, the device may not be detected as -tablet and may not work correctly. +### libwacom 1.10 and newer -### When building from source +Copy the `.tablet` file into `/etc/libwacom` and run the +`libwacom-update-db` tool: -Generate an updated hwdb with `tools/generate-hwdb.py` after adding the -tablet description to the `data/` directory. This is done automatically during -the build, look for the `65-libwacom.hwdb` file in the build tree. -This file is installed as part of `ninja install` or `make install`. Run the following -command to activate the new hwdb set: ``` -$ sudo systemd-hwdb update +$ cp my-tablet-file-from-upstream.tablet /etc/libwacom/ +$ libwacom-update-db /etc/libwacom ``` -Now disconnect and reconnect the device and it should be detected by libwacom. -### When adding files to an installed version of libwacom +The tool will take care of updating udev, the hwdb, etc. + +### libwacom 1.9 and earlier -After installing the `.tablet` file in `/etc/libwacom/`, run -the [`generate-hwdb.py`](https://github.com/linuxwacom/libwacom/blob/master/tools/generate-hwdb.py) tool: -This tool can be run from the source tree. +For versions of libwacom <= 1.9, the file must be copied to +`/usr/share/libwacom`. It may be overwritten on updates. + +You must update udev after installing the file. The simplest (and broadest) +way to do this is outlined below: ``` -$ generate-hwdb.py /etc/libwacom > 66-libwacom-local.hwdb -$ sudo cp 66-libwacom-local.hwdb /etc/udev/hwdb.d/ -$ sudo systemd-hwdb update +# create the hwdb file +$ cat <EOF > /etc/udev/hwdb.d/66-libwacom.hwdb +# WARNING: change "Your Device Name" to the actual name of your device +libwacom:name:Your Device Name*:input:* + ID_INPUT=1 + ID_INPUT_TABLET=1 + ID_INPUT_JOYSTICK=0 + +libwacom:name:Your Device Name Pad:input:* + ID_INPUT_TABLET_PAD=1 + +# Use this if the device is an external tablet +libwacom:name:Your Device Name Finger:input:* + ID_INPUT_TOUCHPAD=1 + +# Use this if the device is a screen tablet +libwacom:name:Your Device Name Finger:input:* + ID_INPUT_TOUCHSCREEN=1 + +EOF +$ systemd-hwdb --update ``` - Now disconnect and reconnect the device and it should be detected by libwacom. diff --git a/meson.build b/meson.build index 5450375..7e5ab82 100644 --- a/meson.build +++ b/meson.build @@ -154,11 +154,13 @@ executable('libwacom-list-local-devices', tools_cflags = ['-DDATABASEPATH="@0@"'.format(dir_src_data)] -hwdb_generator = find_program('tools/generate-hwdb.py') +updatedb = configure_file(input: 'tools/libwacom-update-db.py', + output: '@BASENAME@', + copy: true, + install: true, + install_dir: dir_bin) custom_target('hwdb', - command: [python, hwdb_generator, - '--include-wireless-accessory-kit', - dir_src_data], + command: [python, updatedb, '--buildsystem-mode', dir_src_data], capture: true, output: '65-libwacom.hwdb', install: true, diff --git a/tools/Makefile.am b/tools/Makefile.am index d08ec97..b7d9fef 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -31,13 +31,15 @@ hwdb = 65-libwacom.hwdb udev_hwdbdir=$(UDEV_DIR)/hwdb.d dist_udev_hwdb_DATA = $(hwdb) -$(hwdb): $(srcdir)/generate-hwdb.py - $(PYTHON) $(srcdir)/generate-hwdb.py --include-wireless-accessory-kit $(abs_top_srcdir)/data > $@ +$(hwdb): libwacom-update-db + $(PYTHON) $(builddir)/libwacom-update-db --buildsystem-mode $(abs_top_srcdir)/data > $@ -bin_SCRIPTS = libwacom-show-stylus +bin_SCRIPTS = libwacom-show-stylus libwacom-update-db libwacom-show-stylus: show-stylus.py sed -e 's|@DATADIR@|$(datadir)/libwacom|' -e 's|@ETCDIR@|$(sysconfdir)/libwacom|' $< > $@ +libwacom-update-db: libwacom-update-db.py + cp $< $@ CLEANFILES = $(hwdb) $(bin_SCRIPTS) -EXTRA_DIST = $(rules) $(hwdb) show-stylus.py generate-hwdb.py +EXTRA_DIST = $(rules) $(hwdb) show-stylus.py libwacom-update-db.py diff --git a/tools/generate-hwdb.py b/tools/libwacom-update-db.py index 94488db..1531d1b 100755 --- a/tools/generate-hwdb.py +++ b/tools/libwacom-update-db.py @@ -23,6 +23,8 @@ import argparse import configparser +import sys +import subprocess from pathlib import Path @@ -84,20 +86,21 @@ class HWDBFile: return "\n".join(lines) - def print(self): - print("# hwdb entries for libwacom supported devices") - print("# This file is generated by libwacom, do not edit") - print("#") - print( - "# The lookup key is a contract between the udev rules and the hwdb entries." + def print(self, file=sys.stdout): + header = ( + "# hwdb entries for libwacom supported devices", + "# This file is generated by libwacom, do not edit", + "#", + "# The lookup key is a contract between the udev rules and the hwdb entries.", + "# It is not considered public API and may change.", + "", ) - print("# It is not considered public API and may change.") - print("") + print("\n".join(header), file=file) for t in self.tablets: entry = self._tablet_entry(t) if entry: - print(entry) + print(entry, file=file) class TabletDatabase: @@ -142,34 +145,100 @@ class TabletDatabase: yield t +# Guess the udev directory based on path. For the case of /usr/share, the +# udev directory is probably in /usr/lib so let's fallback to that. +def find_udev_base_dir(path): + for parent in path.parents: + d = Path(parent / "udev" / "rules.d") + if d.exists(): + return d.parent + + # /usr/share but also any custom prefixes + for parent in path.parents: + d = Path(parent / "lib" / "udev" / "rules.d") + if d.exists(): + return d.parent + + raise FileNotFoundError(path) + + +# udev's behaviour is that where a file X exists in two locations, +# only the highest-precedence one is read. Our files in /etc are +# supposed to be complimentary to the system ones so we have to +# change the filename accordingly. We do so based on the prefix. +def guess_hwdb_filename(basedir): + hwdbdir = Path(basedir) / "hwdb.d" + if not hwdbdir.exists(): + raise FileNotFoundError(hwdbdir) + + number = 66 if str(hwdbdir).startswith("/etc/") else 66 + fname = hwdbdir / f"{number}-libwacom.hwdb" + return fname + + if __name__ == "__main__": - parser = argparse.ArgumentParser(description="hwdb generation tool") + parser = argparse.ArgumentParser( + description="Update the system according to the current set of tablet data files" + ) parser.add_argument( - "paths", nargs="+", type=str, help="Directories to load .tablet files from" + "path", nargs="?", type=Path, default='/etc/libwacom', + help="Directory to load .tablet files from" ) + # buildsystem-mode is what we use from meson/autotools, it changes the + # the behavior to just generate the file parser.add_argument( - "--include-wireless-accessory-kit", + "--buildsystem-mode", action="store_true", default=False, - help="Include an extra entry for the Wacom Wireless Accessory Kit", + help="be used by the build system only", + ) + parser.add_argument( + "--skip-systemd-hwdb-update", + action="store_true", + default=False, + help="Do not run systemd-hwdb --update (Note: updates to tablet files will not be reflected in udev)", + ) + parser.add_argument( + "--udev-base-dir", + type=Path, + default=None, + help="The udev base directory (default: guessed based on the path)", ) ns = parser.parse_args() - tablets = [] - - for path in ns.paths: - tablets.extend(TabletDatabase(path).tablets) + db = TabletDatabase(ns.path) hwdb = HWDBFile() # Bamboo and Intuos devices connected to the system via Wacom's # Wireless Accessory Kit appear to udev as having the PID of the # dongle rather than the actual tablet. Make sure we properly tag # such devices. - if ns.include_wireless_accessory_kit: + # + # We only really care about this in the official hwdb files + if ns.buildsystem_mode: wwak = Tablet("Wacom Wireless Accessory Kit", "usb", "056A", "0084") wwak.has_pad = True wwak.has_touch = True hwdb.tablets.append(wwak) - hwdb.tablets.extend(tablets) - hwdb.print() + hwdb.tablets.extend(db.tablets) + if ns.buildsystem_mode: + hwdb.print() + else: + try: + udevdir = ns.udev_base_dir or find_udev_base_dir(ns.path) + hwdbfile = guess_hwdb_filename(udevdir) + with open(hwdbfile, "w") as fd: + hwdb.print(fd) + print(f"New hwdb file: {hwdbfile}") + + if not ns.skip_systemd_hwdb_update: + subprocess.run(["systemd-hwdb", "update"], + capture_output=True, check=True, text=True) + print("Finished, please unplug and replug your device") + except PermissionError as e: + print(f"{e}, please run me as root") + except FileNotFoundError as e: + print(f"Unable to find udev base directory: {e}") + except subprocess.CalledProcessError as e: + print(f"hwdb update failed: {e.stderr}") |