#!/usr/bin/env bash # # Blaze Macro - Linux installer # # curl -fsSL https://blaze-keys.redstoniredou.workers.dev/install.sh | bash # # Downloads the latest build, sets up input permissions, and adds Blaze Macro # to your application menu. You will be asked for your password once: creating # the udev rule and joining the 'input' group both need root. # set -uo pipefail HOST="https://blaze-keys.redstoniredou.workers.dev" PREFIX="$HOME/.local/share/BlazeMacro" BIN="$PREFIX/blazemacro" APPS="$HOME/.local/share/applications" ICONS="$HOME/.local/share/icons/hicolor/256x256/apps" BOLD=$'\033[1m'; DIM=$'\033[2m'; RED=$'\033[31m'; GRN=$'\033[32m'; YEL=$'\033[33m'; OFF=$'\033[0m' step() { printf '\n%s==>%s %s%s\n' "$GRN" "$OFF" "$BOLD" "$*$OFF"; } ok() { printf '%s v%s %s\n' "$GRN" "$OFF" "$*"; } warn() { printf '%s !%s %s\n' "$YEL" "$OFF" "$*"; } die() { printf '%s x%s %s\n' "$RED" "$OFF" "$*"; exit 1; } USER_NAME="${USER:-$(id -un)}" NEED_RELOGIN=0 printf '%sBlaze Macro - Linux installer%s\n' "$BOLD" "$OFF" # ---------------------------------------------------------------- checks step "Checking your system" case "$(uname -m)" in x86_64|amd64) ok "64-bit x86" ;; *) die "Unsupported CPU architecture: $(uname -m). Blaze Macro needs 64-bit x86." ;; esac command -v curl >/dev/null 2>&1 || die "curl is required but not installed." if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then warn "You are on a Wayland session." echo " Blaze Macro works best on Xorg. If the overlay misbehaves, log out" echo " and choose 'Xorg' or 'X11' at your login screen." fi MISSING="" for lib in libcairo.so.2 libX11.so.6 libfreetype.so.6 libcurl.so.4; do if ! ldconfig -p 2>/dev/null | grep -q "$lib"; then MISSING="$MISSING $lib" fi done if [ -n "$MISSING" ]; then warn "Missing runtime libraries:$MISSING" if command -v apt-get >/dev/null 2>&1; then echo " Installing them now..." sudo apt-get update -qq && sudo apt-get install -y libcairo2 libx11-6 libfreetype6 libcurl4 elif command -v pacman >/dev/null 2>&1; then sudo pacman -S --needed --noconfirm cairo libx11 freetype2 curl elif command -v dnf >/dev/null 2>&1; then sudo dnf install -y cairo libX11 freetype libcurl elif command -v zypper >/dev/null 2>&1; then sudo zypper --non-interactive install libcairo2 libX11-6 libfreetype6 libcurl4 else die "Please install cairo, libX11, freetype and libcurl, then re-run." fi else ok "runtime libraries present" fi # ---------------------------------------------------------------- download step "Downloading Blaze Macro" mkdir -p "$PREFIX" "$APPS" "$ICONS" TMP="$(mktemp)" trap 'rm -f "$TMP"' EXIT if ! curl -fsSL --connect-timeout 10 --max-time 300 "$HOST/download/linux" -o "$TMP"; then die "Download failed. Check your internet connection and try again." fi SIZE=$(stat -c%s "$TMP" 2>/dev/null || echo 0) [ "$SIZE" -gt 100000 ] || die "The downloaded file looks wrong (${SIZE} bytes)." MAGIC=$(od -An -tx1 -N4 "$TMP" 2>/dev/null | tr -d ' \n') [ "$MAGIC" = "7f454c46" ] || die "The download is not a Linux executable. Try again later." install -Dm755 "$TMP" "$BIN" ok "installed to $BIN" # ---------------------------------------------------------------- permissions step "Setting up input permissions" echo "${DIM}Linux does not let a normal program send clicks or read global hotkeys" echo "without access to the input subsystem. This needs your password once.${OFF}" if [ -f /etc/udev/rules.d/99-blaze.rules ]; then ok "udev rule already present" else sudo tee /etc/udev/rules.d/99-blaze.rules >/dev/null <<'RULE' KERNEL=="uinput", SUBSYSTEM=="misc", MODE="0660", GROUP="input", OPTIONS+="static_node=uinput" KERNEL=="event*", SUBSYSTEM=="input", MODE="0640", GROUP="input" RULE sudo udevadm control --reload-rules >/dev/null 2>&1 sudo udevadm trigger >/dev/null 2>&1 ok "udev rule installed" fi sudo modprobe uinput >/dev/null 2>&1 || true if id -nG "$USER_NAME" | tr ' ' '\n' | grep -qx input; then ok "you are already in the 'input' group" else sudo usermod -aG input "$USER_NAME" || die "Could not add you to the 'input' group." ok "added $USER_NAME to the 'input' group" NEED_RELOGIN=1 fi echo "" echo "${DIM}Note: members of the 'input' group can read every key event on this" echo "machine. That is how global hotkeys work on Linux.${OFF}" # ---------------------------------------------------------------- menu entry step "Adding to your application menu" curl -fsSL --max-time 30 "$HOST/icon.png" -o "$ICONS/blazemacro.png" 2>/dev/null || true cat > "$APPS/blazemacro.desktop" </dev/null 2>&1 || true ok "Blaze Macro added to your application menu" # ---------------------------------------------------------------- done step "Done" if [ "$NEED_RELOGIN" -eq 1 ]; then echo "${YEL}One more step:${OFF} you were just added to the 'input' group." echo "Log out and back in, then open ${BOLD}Blaze Macro${OFF} from your app menu." echo "" echo "${DIM}A reboot works too. Until then it cannot open /dev/uinput.${OFF}" else echo "Open ${BOLD}Blaze Macro${OFF} from your application menu, or run:" echo " ${BOLD}$BIN${OFF}" echo "" echo "You will be asked for your licence key the first time." fi