From 3ec5066b080b70d5fea4c9aa861afdeb3260b942 Mon Sep 17 00:00:00 2001 From: Iwan Timmer Date: Mon, 31 Mar 2014 16:52:06 +0200 Subject: [PATCH] Watch changes in connected inputs --- src/com/limelight/Limelight.java | 40 ++++------- src/com/limelight/input/EvdevLoader.java | 92 ++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 28 deletions(-) create mode 100644 src/com/limelight/input/EvdevLoader.java diff --git a/src/com/limelight/Limelight.java b/src/com/limelight/Limelight.java index cec99d0..a02d74c 100644 --- a/src/com/limelight/Limelight.java +++ b/src/com/limelight/Limelight.java @@ -5,7 +5,7 @@ import java.io.IOException; import com.limelight.binding.PlatformBinding; import com.limelight.binding.audio.FakeAudioRenderer; import com.limelight.binding.video.FakeVideoRenderer; -import com.limelight.input.EvdevHandler; +import com.limelight.input.EvdevLoader; import com.limelight.input.GamepadMapping; import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.NvConnectionListener; @@ -14,7 +14,6 @@ import com.limelight.nvstream.av.video.VideoDecoderRenderer; import com.limelight.nvstream.http.NvHTTP; import java.io.File; import java.io.FileNotFoundException; -import java.io.FilenameFilter; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; @@ -71,19 +70,6 @@ public class Limelight implements NvConnectionListener { conn = new NvConnection(host, this, streamConfig); - if (inputs.isEmpty()) { - File input = new File("/dev/input"); - String[] events = input.list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.startsWith("event"); - } - }); - - for (String event:events) - inputs.add(new File(input, event).getAbsolutePath()); - } - GamepadMapping mapping = null; if (mappingFile!=null) { try { @@ -94,20 +80,18 @@ public class Limelight implements NvConnectionListener { } } else mapping = new GamepadMapping(); - - for (String input:inputs) { - try { - new EvdevHandler(conn, input, mapping).start(); - } catch (FileNotFoundException ex) { - displayError("Input", "Input (" + input + ") could not be found"); - return; - } catch (IOException ex) { - displayError("Input", "Input (" + input + ") could not be read"); - displayError("Input", "Are you running as root?"); - return; - } - } + try { + new EvdevLoader(conn, mapping, inputs).start(); + } catch (FileNotFoundException ex) { + displayError("Input", "Input could not be found"); + return; + } catch (IOException ex) { + displayError("Input", "Input could not be read"); + displayError("Input", "Are you running as root?"); + return; + } + conn.start(PlatformBinding.getDeviceName(), null, VideoDecoderRenderer.FLAG_PREFER_QUALITY, PlatformBinding.getAudioRenderer(audioDevice), diff --git a/src/com/limelight/input/EvdevLoader.java b/src/com/limelight/input/EvdevLoader.java new file mode 100644 index 0000000..c4991c5 --- /dev/null +++ b/src/com/limelight/input/EvdevLoader.java @@ -0,0 +1,92 @@ +package com.limelight.input; + +import com.limelight.LimeLog; +import com.limelight.nvstream.NvConnection; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.List; + +/** + * Class that handles input devices and a new ones when connected + * @author Iwan Timmer + */ +public class EvdevLoader implements Runnable { + + private NvConnection conn; + + private GamepadMapping mapping; + + private List inputs; + + private File input; + private FilenameFilter filter; + + public EvdevLoader(NvConnection conn, GamepadMapping mapping, List inputs) { + this.conn = conn; + this.mapping = mapping; + this.inputs = inputs; + this.input = new File("/dev/input"); + this.filter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("event"); + } + }; + } + + public void start() throws FileNotFoundException, IOException { + boolean watcher = false; + + if (inputs.isEmpty()) { + watcher = true; + + String[] events = input.list(filter); + + for (String event:events) + inputs.add(new File(input, event).getAbsolutePath()); + } + + for (String input:inputs) + new EvdevHandler(conn, input, mapping).start(); + + if (watcher) { + Thread thread = new Thread(this); + thread.setDaemon(true); + thread.setName("Input - Search"); + thread.start(); + } + } + + @Override + public void run() { + try { + Path evdev = Paths.get("/dev/input"); + + WatchService watcher = evdev.getFileSystem().newWatchService(); + evdev.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); + + WatchKey watckKey = watcher.take(); + List> events = watckKey.pollEvents(); + for (WatchEvent event:events) { + if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) { + String name = event.context().toString(); + if (filter.accept(input, name)) { + LimeLog.info("Input " + name + " added"); + new EvdevHandler(conn, new File(input, name).getAbsolutePath(), mapping).start(); + } + } + } + } catch (IOException | InterruptedException ex) { + LimeLog.severe(ex.getMessage()); + } + } + +}