A Scala Native application for intercepting and handling input events from programmable macro keyboards (macropads).
This project demonstrates how to use Scala Native to directly interact with Linux input devices at a low level, enabling custom keyboard shortcuts and device control without relying on proprietary manufacturer software.
- Direct Linux input device access using Scala Native and ioctl system calls
- Functional programming approach with Cats Effect and FS2
- Event-driven keyboard handling with exclusive device access
- Support for custom key mappings and actions
- Native executable for efficient performance
- Secure alternative to proprietary manufacturer software
The application:
- Opens a specified input device path (e.g.,
/dev/input/event11) - Uses
EVIOCGRABioctl to grab the device exclusively, preventing other programs from receiving input events - Processes input events in a streaming fashion using FS2
- Performs custom actions based on key presses (e.g. volume control)
- Linux system with access to input devices
- Scala Native 0.5.x
- Root privileges or udev rules for accessing input devices
- Scala installed https://www.scala-lang.org/download/
# Compile the project
scala compile
# Create a native executable
scala --power package
# Clean build artifacts
scala clean# Run the application (requires proper permissions to access input devices)
scala run main.scala
# Or run the pre-built native executable
./org.polyvariant.macropad4s.App
# Run with a specific input device path
./org.polyvariant.macropad4s.App /dev/input/event0By default, the application listens to events on /dev/input/event11 and handles:
- Key 1: Decreases volume
- Key 3: Increases volume
You can modify these mappings in main.scala to suit your needs.
To find your specific input device, you can use:
# Find your device by vendor and product ID
VENDOR="514c"; PRODUCT="8851"; for ev in /dev/input/event*; do udevadm info -q property -n "$ev" | grep -q "ID_VENDOR_ID=${VENDOR}" && udevadm info -q property -n "$ev" | grep -q "ID_MODEL_ID=${PRODUCT}" && echo "$ev"; doneThe application is built with:
- Scala Native - For low-level system access using ioctl calls
- Cats Effect - For functional effects and resource management
- FS2 - For streaming input processing
- Scala CLI - For dependency management and build