Added an abstract HID-Layer, this way we can change the actual HID-Backend easily

Currently Winows still uses purejavahidapi and Unix uses hid4java. This
is currently untested.
This commit is contained in:
Maschell 2017-04-05 11:44:21 +02:00
parent 25e8bc6faf
commit e71d760cde
16 changed files with 523 additions and 83 deletions

View File

@ -138,9 +138,14 @@
<version>1eb4087</version> <!-- JXInput 0.7 --> <version>1eb4087</version> <!-- JXInput 0.7 -->
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.Maschell</groupId> <groupId>com.github.QuarkTheAwesome</groupId>
<artifactId>purejavahidapi</artifactId> <artifactId>purejavahidapi</artifactId>
<version>cbf0588</version> <version>3591b7e</version>
</dependency>
<dependency>
<groupId>org.hid4java</groupId>
<artifactId>hid4java</artifactId>
<version>0.4.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -21,6 +21,8 @@
*******************************************************************************/ *******************************************************************************/
package net.ash.HIDToVPADNetworkClient.controller; package net.ash.HIDToVPADNetworkClient.controller;
import java.util.Arrays;
import lombok.Getter; import lombok.Getter;
import lombok.Synchronized; import lombok.Synchronized;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
@ -41,6 +43,8 @@ public abstract class Controller implements Runnable {
@Getter private final String identifier; @Getter private final String identifier;
private byte[] latestData = null; private byte[] latestData = null;
protected int MAX_PACKET_LENGTH = 64;
boolean shutdown = false; boolean shutdown = false;
boolean shutdownDone = false; boolean shutdownDone = false;
private final Object dataLock = new Object(); private final Object dataLock = new Object();
@ -66,6 +70,9 @@ public abstract class Controller implements Runnable {
while (isActive()) { while (isActive()) {
byte[] newData = pollLatestData(); byte[] newData = pollLatestData();
if (newData != null && newData.length != 0) { if (newData != null && newData.length != 0) {
if (newData.length > MAX_PACKET_LENGTH) {
newData = Arrays.copyOfRange(newData, 0, MAX_PACKET_LENGTH);
}
setLatestData(newData); setLatestData(newData);
} }
doSleepAfterPollingData(); doSleepAfterPollingData();
@ -202,7 +209,7 @@ public abstract class Controller implements Runnable {
} }
public enum ControllerType { public enum ControllerType {
PureJAVAHid, LINUX, XINPUT13, XINPUT14 HIDController, LINUX, XINPUT13, XINPUT14
} }
public abstract String getInfoText(); public abstract String getInfoText();

View File

@ -5,26 +5,26 @@ import java.util.Arrays;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.util.Settings; import net.ash.HIDToVPADNetworkClient.util.Settings;
public class DS4NewController extends PureJavaHidController { public class DS4NewController extends HidController {
public static final short DS4_NEW_CONTROLLER_VID = 0x54C; public static final short DS4_NEW_CONTROLLER_VID = 0x54C;
public static final short DS4_NEW_CONTROLLER_PID = 0x09CC; public static final short DS4_NEW_CONTROLLER_PID = 0x09CC;
public DS4NewController(String identifier) throws ControllerInitializationFailedException { public DS4NewController(String identifier) throws ControllerInitializationFailedException {
super(identifier); super(identifier);
if (Settings.isMacOSX()) { if (Settings.isMacOSX()) {
this.PACKET_LENGTH = 7; this.MAX_PACKET_LENGTH = 7;
} else { } else {
this.PACKET_LENGTH = 6; this.MAX_PACKET_LENGTH = 6;
} }
} }
@Override @Override
public byte[] pollLatestData() { public byte[] pollLatestData() {
byte[] currentData = super.getLatestData();
if (Settings.isMacOSX()) { // for some reason the controller has one extra byte at the beginning under OSX if (Settings.isMacOSX()) { // for some reason the controller has one extra byte at the beginning under OSX
return Arrays.copyOfRange(currentData, 1, 7); currentData = Arrays.copyOfRange(currentData, 1, 7);
} }
return currentData;
return currentData.clone();
} }
@Override @Override

View File

@ -22,63 +22,53 @@
package net.ash.HIDToVPADNetworkClient.controller; package net.ash.HIDToVPADNetworkClient.controller;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.Synchronized;
import lombok.extern.java.Log; import lombok.extern.java.Log;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.util.PureJavaHidApiManager; import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
import purejavahidapi.HidDevice; import net.ash.HIDToVPADNetworkClient.hid.HidManager;
import purejavahidapi.InputReportListener;
@Log @Log
public class PureJavaHidController extends Controller implements InputReportListener { public class HidController extends Controller {
private final Object dataLock = new Object();
protected byte[] currentData = new byte[1];
protected int PACKET_LENGTH = 64;
@Getter @Setter(AccessLevel.PRIVATE) private HidDevice hidDevice; @Getter @Setter(AccessLevel.PRIVATE) private HidDevice hidDevice;
public static Controller getInstance(String deviceIdentifier) throws IOException, ControllerInitializationFailedException { public static Controller getInstance(String deviceIdentifier) throws IOException, ControllerInitializationFailedException {
HidDevice device = PureJavaHidApiManager.getDeviceByPath(deviceIdentifier); HidDevice device = HidManager.getDeviceByPath(deviceIdentifier);
short vid = 0; short vid = 0;
short pid = 0; short pid = 0;
if (device != null) { if (device != null) {
vid = device.getHidDeviceInfo().getVendorId(); vid = device.getVendorId();
pid = device.getHidDeviceInfo().getProductId(); pid = device.getProductId();
device.close(); device.close();
} }
// We use a special version to optimize the data for the switch pro controller // We use a special version to optimize the data for the switch pro controller
if (vid == SwitchProController.SWITCH_PRO_CONTROLLER_VID && pid == SwitchProController.SWITCH_PRO_CONTROLLER_PID) { if (vid == SwitchProController.SWITCH_PRO_CONTROLLER_VID && pid == SwitchProController.SWITCH_PRO_CONTROLLER_PID) {
return new SwitchProController(deviceIdentifier); return new SwitchProController(deviceIdentifier);
} else if (vid == DS4NewController.DS4_NEW_CONTROLLER_VID && pid == DS4NewController.DS4_NEW_CONTROLLER_PID) { } else if (vid == DS4NewController.DS4_NEW_CONTROLLER_VID && pid == DS4NewController.DS4_NEW_CONTROLLER_PID) {
return new DS4NewController(deviceIdentifier); return new DS4NewController(deviceIdentifier);
} else { } else {
return new PureJavaHidController(deviceIdentifier); return new HidController(deviceIdentifier);
} }
} }
public PureJavaHidController(String identifier) throws ControllerInitializationFailedException { public HidController(String identifier) throws ControllerInitializationFailedException {
super(ControllerType.PureJAVAHid, identifier); super(ControllerType.HIDController, identifier);
} }
@Override @Override
public boolean initController(String identifier) { public boolean initController(String identifier) {
HidDevice device; HidDevice device;
try { try {
device = PureJavaHidApiManager.getDeviceByPath(identifier); device = HidManager.getDeviceByPath(identifier);
if (device == null) { if (device == null) {
return false; return false;
} }
device.setInputReportListener(this);
setHidDevice(device); setHidDevice(device);
return true; return true;
@ -89,9 +79,8 @@ public class PureJavaHidController extends Controller implements InputReportList
} }
@Override @Override
@Synchronized("dataLock")
public byte[] pollLatestData() { public byte[] pollLatestData() {
return currentData.clone(); return hidDevice.getLatestData();
} }
@Override @Override
@ -105,29 +94,16 @@ public class PureJavaHidController extends Controller implements InputReportList
throw e; throw e;
} }
} }
} }
@Override @Override
public short getVID() { public short getVID() {
return getHidDevice().getHidDeviceInfo().getVendorId(); return getHidDevice().getVendorId();
} }
@Override @Override
public short getPID() { public short getPID() {
return getHidDevice().getHidDeviceInfo().getProductId(); return getHidDevice().getProductId();
}
@Override
@Synchronized("dataLock")
public void onInputReport(HidDevice source, byte reportID, byte[] reportData, int reportLength) {
if (isActive()) {
int length = PACKET_LENGTH;
if (reportLength < length) {
length = reportLength;
}
currentData = Arrays.copyOfRange(reportData, 0, length);
}
} }
@Override @Override

View File

@ -23,18 +23,19 @@ package net.ash.HIDToVPADNetworkClient.controller;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
public class SwitchProController extends PureJavaHidController { public class SwitchProController extends HidController {
public static final short SWITCH_PRO_CONTROLLER_VID = 0x57e; public static final short SWITCH_PRO_CONTROLLER_VID = 0x57e;
public static final short SWITCH_PRO_CONTROLLER_PID = 0x2009; public static final short SWITCH_PRO_CONTROLLER_PID = 0x2009;
public SwitchProController(String identifier) throws ControllerInitializationFailedException { public SwitchProController(String identifier) throws ControllerInitializationFailedException {
super(identifier); super(identifier);
// truncate package to 11; // truncate package to 11;
this.PACKET_LENGTH = 11; this.MAX_PACKET_LENGTH = 11;
} }
@Override @Override
public byte[] pollLatestData() { public byte[] pollLatestData() {
byte[] currentData = super.pollLatestData();
if (currentData == null || currentData.length < 10) { if (currentData == null || currentData.length < 10) {
return new byte[0]; return new byte[0];
} }
@ -43,7 +44,7 @@ public class SwitchProController extends PureJavaHidController {
currentData[5] = 0; currentData[5] = 0;
currentData[7] = 0; currentData[7] = 0;
currentData[9] = 0; currentData[9] = 0;
return currentData.clone(); return currentData;
} }
@Override @Override

View File

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid;
public interface HidDevice {
short getVendorId();
short getProductId();
void close();
byte[] getLatestData();
}

View File

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid;
public interface HidDeviceInfo {
public short getUsagePage();
public int getVendorId();
public int getProductId();
public String getPath();
}

View File

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid;
import java.io.IOException;
import java.util.List;
import net.ash.HIDToVPADNetworkClient.hid.hid4java.Hid4JavaHidManagerBackend;
import net.ash.HIDToVPADNetworkClient.hid.purejavahid.PureJavaHidManagerBackend;
import net.ash.HIDToVPADNetworkClient.util.Settings;
public class HidManager {
private final static HidManagerBackend backend;
public static List<HidDeviceInfo> getAttachedController() {
return backend.getAttachedController();
}
public static HidDevice getDeviceByPath(String path) throws IOException {
return backend.getDeviceByPath(path);
}
static {
if (Settings.isMacOSX()) {
backend = new Hid4JavaHidManagerBackend();
} else if (Settings.isWindows()) {
backend = new PureJavaHidManagerBackend();
} else if (Settings.isLinux()) {
backend = new Hid4JavaHidManagerBackend();
} else
backend = null;
}
}

View File

@ -19,22 +19,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*******************************************************************************/ *******************************************************************************/
package net.ash.HIDToVPADNetworkClient.util; package net.ash.HIDToVPADNetworkClient.hid;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.ash.HIDToVPADNetworkClient.manager.ControllerManager; import net.ash.HIDToVPADNetworkClient.util.Settings;
import purejavahidapi.HidDevice;
import purejavahidapi.HidDeviceInfo;
import purejavahidapi.PureJavaHidApi;
public final class PureJavaHidApiManager {
private PureJavaHidApiManager() {
}
public abstract class HidManagerBackend {
/** /**
* Searches the corresponding HIDDevice for the given path * Searches the corresponding HIDDevice for the given path
* *
@ -43,25 +36,12 @@ public final class PureJavaHidApiManager {
* @return It the device is found, it will be returned. Otherwise null is returned. * @return It the device is found, it will be returned. Otherwise null is returned.
* @throws IOException * @throws IOException
*/ */
public static HidDevice getDeviceByPath(String path) throws IOException { public abstract HidDevice getDeviceByPath(String path) throws IOException;
HidDeviceInfo deviceinfo = ControllerManager.getDeviceInfoByPath(path);
if (deviceinfo != null) {
HidDevice result = PureJavaHidApi.openDevice(deviceinfo);
if (result != null) {
return result;
}
}
/*
* List<HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices(); HidDevice result = null; for (HidDeviceInfo info : devList) { String real_path =
* info.getPath(); if (real_path.equals(path)) { return PureJavaHidApi.openDevice(info); } }
*/
return null;
}
public static List<HidDeviceInfo> getAttachedController() { public List<HidDeviceInfo> getAttachedController() {
List<HidDeviceInfo> connectedGamepads = new ArrayList<HidDeviceInfo>(); List<HidDeviceInfo> connectedGamepads = new ArrayList<HidDeviceInfo>();
for (HidDeviceInfo info : PureJavaHidApi.enumerateDevices()) { for (HidDeviceInfo info : enumerateDevices()) {
if (isGamepad(info)) { if (isGamepad(info)) {
// Skip Xbox controller under windows. We should use XInput instead. // Skip Xbox controller under windows. We should use XInput instead.
if (isXboxController(info) && Settings.isWindows()) { if (isXboxController(info) && Settings.isWindows()) {
@ -93,4 +73,6 @@ public final class PureJavaHidApiManager {
if (info == null) return false; if (info == null) return false;
return (info.getVendorId() == 0x045e) && ((info.getProductId() == 0x02ff) || (info.getProductId() == 0x02a1)); return (info.getVendorId() == 0x045e) && ((info.getProductId() == 0x02ff) || (info.getProductId() == 0x02a1));
} }
public abstract List<HidDeviceInfo> enumerateDevices();
} }

View File

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid.hid4java;
import java.util.Arrays;
import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
class Hid4JavaHidDevice implements HidDevice {
private final org.hid4java.HidDevice myDevice;
private final byte[] data = new byte[64];
public Hid4JavaHidDevice(org.hid4java.HidDevice device) {
this.myDevice = device;
}
@Override
public short getVendorId() {
return myDevice.getVendorId();
}
@Override
public short getProductId() {
return myDevice.getProductId();
}
@Override
public void close() {
myDevice.close();
}
@Override
public byte[] getLatestData() {
int length = myDevice.read(data);
if (length <= 0) return null;
return Arrays.copyOf(data, length);
}
}

View File

@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid.hid4java;
import org.hid4java.HidDevice;
import net.ash.HIDToVPADNetworkClient.hid.HidDeviceInfo;
class Hid4JavaHidDeviceInfo implements HidDeviceInfo {
private final HidDevice myDevice;
public Hid4JavaHidDeviceInfo(HidDevice device) {
myDevice = device;
}
@Override
public short getUsagePage() {
return (short) myDevice.getUsagePage();
}
@Override
public int getVendorId() {
return myDevice.getVendorId();
}
@Override
public int getProductId() {
return myDevice.getProductId();
}
@Override
public String getPath() {
return myDevice.getPath();
}
}

View File

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid.hid4java;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.hid4java.HidManager;
import org.hid4java.HidServices;
import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
import net.ash.HIDToVPADNetworkClient.hid.HidDeviceInfo;
import net.ash.HIDToVPADNetworkClient.hid.HidManagerBackend;
public class Hid4JavaHidManagerBackend extends HidManagerBackend {
@Override
public HidDevice getDeviceByPath(String path) throws IOException {
HidDevice result = null;
HidServices services = HidManager.getHidServices();
if (services == null) return result;
for (org.hid4java.HidDevice device : services.getAttachedHidDevices()) {
if (device.getPath().equals(path)) {
result = new Hid4JavaHidDevice(device);
break;
}
}
return result;
}
@Override
public List<HidDeviceInfo> enumerateDevices() {
List<HidDeviceInfo> result = new ArrayList<HidDeviceInfo>();
for (org.hid4java.HidDevice info : HidManager.getHidServices().getAttachedHidDevices()) {
result.add(new Hid4JavaHidDeviceInfo(info));
}
return result;
}
}

View File

@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid.purejavahid;
import java.util.Arrays;
import lombok.Synchronized;
import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
import purejavahidapi.InputReportListener;
class PureJavaHidDevice implements HidDevice, InputReportListener {
private final purejavahidapi.HidDevice myDevice;
private final Object dataLock = new Object();
protected byte[] currentData = new byte[1];
public PureJavaHidDevice(purejavahidapi.HidDevice device) {
this.myDevice = device;
device.setInputReportListener(this);
}
@Override
@Synchronized("dataLock")
public void onInputReport(purejavahidapi.HidDevice source, byte reportID, byte[] reportData, int reportLength) {
currentData = Arrays.copyOfRange(reportData, 0, reportLength);
}
@Override
public short getVendorId() {
return myDevice.getHidDeviceInfo().getVendorId();
}
@Override
public short getProductId() {
return myDevice.getHidDeviceInfo().getProductId();
}
@Override
public void close() {
myDevice.close();
}
@Override
@Synchronized("dataLock")
public byte[] getLatestData() {
return currentData.clone();
}
}

View File

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid.purejavahid;
import net.ash.HIDToVPADNetworkClient.hid.HidDeviceInfo;
class PureJavaHidDeviceInfo implements HidDeviceInfo {
private final purejavahidapi.HidDeviceInfo myInfo;
public PureJavaHidDeviceInfo(purejavahidapi.HidDeviceInfo info) {
this.myInfo = info;
}
@Override
public short getUsagePage() {
return myInfo.getUsagePage();
}
@Override
public int getVendorId() {
return myInfo.getVendorId();
}
@Override
public int getProductId() {
return myInfo.getProductId();
}
@Override
public String getPath() {
return myInfo.getPath();
}
}

View File

@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2017 Ash (QuarkTheAwesome) & Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package net.ash.HIDToVPADNetworkClient.hid.purejavahid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.ash.HIDToVPADNetworkClient.hid.HidDevice;
import net.ash.HIDToVPADNetworkClient.hid.HidDeviceInfo;
import net.ash.HIDToVPADNetworkClient.hid.HidManagerBackend;
import purejavahidapi.PureJavaHidApi;
public class PureJavaHidManagerBackend extends HidManagerBackend {
@Override
public List<HidDeviceInfo> enumerateDevices() {
List<HidDeviceInfo> result = new ArrayList<HidDeviceInfo>();
for (purejavahidapi.HidDeviceInfo info : PureJavaHidApi.enumerateDevices()) {
result.add(new PureJavaHidDeviceInfo(info));
}
return result;
}
@Override
public HidDevice getDeviceByPath(String path) throws IOException {
List<purejavahidapi.HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices();
HidDevice result = null;
for (purejavahidapi.HidDeviceInfo info : devList) {
String real_path = info.getPath();
if (real_path.equals(path)) {
return new PureJavaHidDevice(PureJavaHidApi.openDevice(info));
}
}
return result;
}
}

View File

@ -38,17 +38,17 @@ import lombok.Synchronized;
import lombok.extern.java.Log; import lombok.extern.java.Log;
import net.ash.HIDToVPADNetworkClient.controller.Controller; import net.ash.HIDToVPADNetworkClient.controller.Controller;
import net.ash.HIDToVPADNetworkClient.controller.Controller.ControllerType; import net.ash.HIDToVPADNetworkClient.controller.Controller.ControllerType;
import net.ash.HIDToVPADNetworkClient.controller.HidController;
import net.ash.HIDToVPADNetworkClient.controller.LinuxDevInputController; import net.ash.HIDToVPADNetworkClient.controller.LinuxDevInputController;
import net.ash.HIDToVPADNetworkClient.controller.PureJavaHidController;
import net.ash.HIDToVPADNetworkClient.controller.XInput13Controller; import net.ash.HIDToVPADNetworkClient.controller.XInput13Controller;
import net.ash.HIDToVPADNetworkClient.controller.XInput14Controller; import net.ash.HIDToVPADNetworkClient.controller.XInput14Controller;
import net.ash.HIDToVPADNetworkClient.controller.XInputController; import net.ash.HIDToVPADNetworkClient.controller.XInputController;
import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException; import net.ash.HIDToVPADNetworkClient.exeption.ControllerInitializationFailedException;
import net.ash.HIDToVPADNetworkClient.hid.HidDeviceInfo;
import net.ash.HIDToVPADNetworkClient.hid.HidManager;
import net.ash.HIDToVPADNetworkClient.util.MessageBox; import net.ash.HIDToVPADNetworkClient.util.MessageBox;
import net.ash.HIDToVPADNetworkClient.util.MessageBoxManager; import net.ash.HIDToVPADNetworkClient.util.MessageBoxManager;
import net.ash.HIDToVPADNetworkClient.util.PureJavaHidApiManager;
import net.ash.HIDToVPADNetworkClient.util.Settings; import net.ash.HIDToVPADNetworkClient.util.Settings;
import purejavahidapi.HidDeviceInfo;
@Log @Log
public final class ControllerManager { public final class ControllerManager {
@ -104,9 +104,9 @@ public final class ControllerManager {
if (!contains) { if (!contains) {
Controller c = null; Controller c = null;
switch (entry.getValue()) { switch (entry.getValue()) {
case PureJAVAHid: case HIDController:
try { try {
c = PureJavaHidController.getInstance(deviceIdentifier); c = HidController.getInstance(deviceIdentifier);
} catch (ControllerInitializationFailedException e) { } catch (ControllerInitializationFailedException e) {
// e.printStackTrace(); // e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
@ -157,10 +157,9 @@ public final class ControllerManager {
private static Map<String, ControllerType> detectHIDDevices() { private static Map<String, ControllerType> detectHIDDevices() {
Map<String, ControllerType> connectedDevices = new HashMap<String, ControllerType>(); Map<String, ControllerType> connectedDevices = new HashMap<String, ControllerType>();
System.out.println("detectHIDDevices"); for (HidDeviceInfo info : HidManager.getAttachedController()) {
for (HidDeviceInfo info : PureJavaHidApiManager.getAttachedController()) {
String path = info.getPath(); String path = info.getPath();
connectedDevices.put(path, ControllerType.PureJAVAHid); connectedDevices.put(path, ControllerType.HIDController);
synchronized (connectedDevicesInfo) { synchronized (connectedDevicesInfo) {
connectedDevicesInfo.put(path, info); connectedDevicesInfo.put(path, info);
} }