{"id":20128976,"url":"https://github.com/gurkenlabs/input4j","last_synced_at":"2026-03-07T00:04:02.390Z","repository":{"id":189313547,"uuid":"600372745","full_name":"gurkenlabs/input4j","owner":"gurkenlabs","description":"Input4j 🎮 The pure java input library. Cross-plattform, high performance, future proof","archived":false,"fork":false,"pushed_at":"2026-03-02T21:43:19.000Z","size":634,"stargazers_count":12,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-02T22:55:56.411Z","etag":null,"topics":["cross-platform","dependency-free","directinput","evdev","ffm-api","foreign-function-and-memory-api","input","iokit","java","jni-alternative","linux","macos","panama","performance","polling","rumble","windows","xinput"],"latest_commit_sha":null,"homepage":"https://gurkenlabs.github.io/input4j/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gurkenlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2023-02-11T09:36:06.000Z","updated_at":"2026-03-02T21:43:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"775d5a10-ee20-4021-ac56-6f0fed8c72c9","html_url":"https://github.com/gurkenlabs/input4j","commit_stats":{"total_commits":30,"total_committers":1,"mean_commits":30.0,"dds":0.0,"last_synced_commit":"970a424eebd56c4381418cb8dcf1512f4dd4457f"},"previous_names":["steffen-wilke/panama-input","gurkenlabs/input4j"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/gurkenlabs/input4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gurkenlabs%2Finput4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gurkenlabs%2Finput4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gurkenlabs%2Finput4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gurkenlabs%2Finput4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gurkenlabs","download_url":"https://codeload.github.com/gurkenlabs/input4j/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gurkenlabs%2Finput4j/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30204114,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cross-platform","dependency-free","directinput","evdev","ffm-api","foreign-function-and-memory-api","input","iokit","java","jni-alternative","linux","macos","panama","performance","polling","rumble","windows","xinput"],"created_at":"2024-11-13T20:31:01.492Z","updated_at":"2026-03-07T00:04:02.383Z","avatar_url":"https://github.com/gurkenlabs.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎮 Input4j - The pure Java input library\n[![Maven Central](https://img.shields.io/maven-central/v/de.gurkenlabs/input4j)](https://search.maven.org/artifact/de.gurkenlabs/input4j)\n[![Build](https://img.shields.io/github/actions/workflow/status/gurkenlabs/input4j/build.yml)](https://github.com/gurkenlabs/input4j/actions)\n[![License](https://img.shields.io/github/license/gurkenlabs/input4j)](LICENSE)\n[![Java](https://img.shields.io/badge/java-22+-orange)]()\n\n**Input4j** is a modern Java input library built on the **Foreign Function \u0026 Memory API (FFM)**.  \nIt provides fast, cross-platform controller and gamepad input without requiring JNI or native binaries.\n\n## 🚀 Features\n- 🎮 Game controller input support\n- ⚡ Native performance via Java FFM API\n- 🧩 No JNI required\n- 🖥 Cross-platform (Windows / Linux / macOS)\n- 📦 Available on Maven Central\n- 🧪 Lightweight and dependency-free\n\n## Why input4j?\n- **Cross-Platform Input handling**: Fully compatible with Windows, Linux, and OSX.\n- **Performance**: Optimized for high performance with minimal overhead.\n- **Flexible Input Handling**: Supports both polling and event-based input mechanisms.\n- **Simplicity**: Easy to integrate and use with straightforward APIs.\n- **Future-Proof**: Built on the latest Java technologies, ensuring long-term support and compatibility.\n\n### 🆚 Advantages over traditional java input libraries\nInput4j offers several advantages over traditional libraries like JInput by leveraging the new Foreign Function \u0026 Memory API (FFM API) instead of using Java Native Interface (JNI).\nIt is a more modern and efficient JNI alternative and an easy way to interact with native input libraries, providing the following benefits:\n\n- No Native Artifacts \u0026 No Dependencies: Direct interaction with native libraries without the need for additional native artifacts simplifies the build and deployment process.\n- Performance: Based on the FFM API, this library reduces the overhead associated with native calls, resulting in significantly faster performance then Java JNI.\n- Safety: Safer memory management and access patterns reduce the risk of memory leaks and buffer overflows.\n- Ease of Use: A more straightforward and modern API makes it easier to write and maintain code.\n- Future-Proof: Built on the latest Java technologies, ensuring long-term support and compatibility with future Java versions.\n\n## 📦️ Installation\n\n### Gradle\nAdd the following dependency to your `build.gradle` file to start using Input4j:\n\n```groovy\ndependencies {\n  implementation 'de.gurkenlabs:input4j:1.0.0'\n}\n```\n### Maven\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ede.gurkenlabs\u003c/groupId\u003e\n  \u003cartifactId\u003einput4j\u003c/artifactId\u003e\n  \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## 💻 Quick start guide\n\n### Manually Polling and Reading Input Data\n```java\ntry (var inputDevices = InputDevices.init()) {\n  while (!inputDevices.getAll().isEmpty()) {\n    // iterate all available input devices and poll their data every second\n    for (var inputDevice : inputDevices.getAll()) {\n      inputDevice.poll();\n      System.out.println(inputDevice.getInstanceName() + \":\" + inputDevice.getComponents());\n    }\n\n    Thread.sleep(1000);\n  }\n}\n```\n### Event-Based Input Handling\n```java\ntry (var devices = InputDevices.init()) {\n  var device = devices.getAll().stream().findFirst().orElse(null);\n  if (device == null) {\n    System.out.println(\"No input devices found.\");\n    return;\n  }\n\n  device.onInputValueChanged(e -\u003e System.out.println(\"Value changed: \" + e.component() + \" -\u003e \" + e.newValue()));\n  device.onButtonPressed(XInput.X, () -\u003e System.out.println(\"X button pressed\"));\n  device.onAxisChanged(Axis.AXIS_X, value -\u003e System.out.println(\"X axis: \" + value));\n\n  // simulate external polling loop\n  while (true) {\n    device.poll();\n    Thread.sleep(1000);\n  }\n}\n```\n\n### Used By\n\ninput4j is the input system used by the\n[LITIENGINE](https://litiengine.com) Java game engine.\n\n\n## 🔌 Technical Details\n\n### Platform-Specific Input APIs\n- **Windows: DirectInput  ✅**\n    - Full implementation using `dinput.h`\n    - Supports legacy and modern input devices\n\n- **Windows: XInput ✅**\n    - Modern gamepad support via `xinput.h`\n    - Xbox controller compatibility\n\n- **Linux: evdev ✅**\n    - Event interface via `/dev/input`\n\n- **macOS: IOKit ✅**\n    - HID device provisioning via `IOHIDManager`\n\n### System Requirements\n- Java Runtime: 22+\n\n### Linux Permissions\n\nOn Linux, Input4j uses the modern **evdev** API (`/dev/input/event*`) which provides detailed input information. This is the same approach used by SDL2 and other modern gamepad libraries.\n\nThe `/dev/input/event*` devices are owned by `root:input` with restricted access (640).\n\n**Quick fix - Add user to input group:**\n```bash\nsudo usermod -a -G input $USER\n# Log out and log back in for changes to take effect\n```\n\n**Permanent solution - Create udev rules:**\nCreate `/etc/udev/rules.d/99-input4j.rules`:\n```rules\nSUBSYSTEM==\"input\", ENV{ID_INPUT_JOYSTICK}==\"1\", MODE=\"0666\"\n```\nThen reload the rules:\n```bash\nsudo udevadm control --reload-rules\n# Reconnect your gamepad\n```\n\n**Verify your setup:**\n```bash\n# Check device permissions\nls -la /dev/input/event*\n\n# Check if user is in input group\ngetent group input\n```\n\n\u003e **Note:** Input4j uses the modern evdev API (`/dev/input/event*`) rather than the legacy joystick API (`/dev/input/js*`). Both require the same permissions, but evdev provides more detailed input information. This is the standard approach used by SDL2 and other modern Linux input libraries.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgurkenlabs%2Finput4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgurkenlabs%2Finput4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgurkenlabs%2Finput4j/lists"}