|
| 1 | +use crate::{Context, Error}; |
| 2 | + |
| 3 | +use std::fmt::Write; |
| 4 | + |
| 5 | +use poise::serenity_prelude::CreateAttachment; |
| 6 | +use poise::CreateReply; |
| 7 | + |
| 8 | +/// Generates udev rules for the given vendor and product Ids. |
| 9 | +#[poise::command( |
| 10 | + rename = "generate-udev", |
| 11 | + aliases("udev"), |
| 12 | + slash_command, |
| 13 | + prefix_command |
| 14 | +)] |
| 15 | +pub async fn generate_udev( |
| 16 | + ctx: Context<'_>, |
| 17 | + #[description = "The Vendor Id in decimal."] vendor_id: u64, |
| 18 | + #[description = "The Product Id in decimal."] product_id: u64, |
| 19 | + libinput_override: Option<bool>, |
| 20 | +) -> Result<(), Error> { |
| 21 | + let udev = gen_udev(vendor_id, product_id, libinput_override.unwrap_or(true)); |
| 22 | + |
| 23 | + let attachment = CreateAttachment::bytes(udev, "70-opentabletdriver.rules"); |
| 24 | + ctx.send( |
| 25 | + CreateReply::default() |
| 26 | + .content("place this file in `/etc/udev/rules.d/70-opentabletdriver.rules` then run the following:\n \ |
| 27 | + ```\nsudo udevadm control --reload-rules && sudo udevadm trigger\n```") |
| 28 | + .attachment(attachment), |
| 29 | + ) |
| 30 | + .await?; |
| 31 | + |
| 32 | + Ok(()) |
| 33 | +} |
| 34 | + |
| 35 | +const REQUIRED_UDEV_STR: &str = r#" |
| 36 | +KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess", TAG+="udev-acl" |
| 37 | +KERNEL=="js[0-9]*", SUBSYSTEM=="input", ATTRS{name}=="OpenTabletDriver Virtual Tablet", RUN+="/usr/bin/env rm %E{DEVNAME}" |
| 38 | +"#; |
| 39 | + |
| 40 | +fn gen_udev(id_vendor: u64, id_product: u64, libinput_override: bool) -> String { |
| 41 | + let mut udev_rules = format!( |
| 42 | + "KERNEL==\"hidraw*\", ATTRS{{idVendor}}==\"{id_vendor:X}\", ATTRS{{idProduct}}==\"{id_product:X}\", TAG+=\"uaccess\", TAG+=\"udev-acl\"\n\ |
| 43 | + SUBSYSTEM==\"usb\", ATTRS{{idVendor}}==\"{id_vendor:X}\", ATTRS{{idProduct}}==\"{id_product:X}\", TAG+=\"uaccess\", TAG+=\"udev-acl\"" |
| 44 | + ); |
| 45 | + |
| 46 | + if libinput_override { |
| 47 | + write!( |
| 48 | + udev_rules, |
| 49 | + "\nSUBSYSTEM==\"input\", ATTRS{{idVendor}}==\"{id_vendor:X}\", ATTRS{{idProduct}}==\"{id_product:X}\"" |
| 50 | + ).unwrap(); |
| 51 | + } |
| 52 | + |
| 53 | + format!("{REQUIRED_UDEV_STR}\n# Generated by TabletBot\n{udev_rules}") |
| 54 | +} |
0 commit comments