Implement the isSupported method and make plugins work again. There was an issue where accessing the static methods in DefaultControllerEnvironment and ControllerEnvironment would cause ploblems when the plugins were loaded using the PluginLoader class loader.

This commit is contained in:
endolf 2007-06-10 15:03:27 +00:00
parent d6368e8dc5
commit 083eee58ee
18 changed files with 455 additions and 154 deletions

View file

@ -83,6 +83,23 @@
<iterate target="javadoc"/> <iterate target="javadoc"/>
</target> </target>
<target name="pluginTest" depends="dist" description="Build plugin version">
<mkdir dir="dist"/>
<mkdir dir="dist/controller"/>
<copy todir="dist">
<fileset file="coreAPI/bin/jinput-core.jar"/>
<fileset file="coreAPI/bin/jinput-test.jar"/>
<fileset file="plugins/DX8/lib/jutils.jar"/>
</copy>
<copy todir="dist/controller">
<fileset dir="plugins/awt/bin"/>
<fileset dir="plugins/linux/bin"/>
<fileset dir="plugins/OSX/bin"/>
<fileset dir="plugins/windows/bin"/>
<fileset dir="plugins/wintab/bin"/>
</copy>
</target>
<target name="dist" depends="init" description="Build the distribution file for this system"> <target name="dist" depends="init" description="Build the distribution file for this system">
<iterate target="all"/> <iterate target="all"/>
<mkdir dir="dist"/> <mkdir dir="dist"/>

View file

@ -38,6 +38,9 @@
*****************************************************************************/ *****************************************************************************/
package net.java.games.input; package net.java.games.input;
import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@ -105,6 +108,13 @@ public abstract class ControllerEnvironment {
controllerListeners.add(l); controllerListeners.add(l);
} }
/**
* Returns the isSupported status of this environment.
* What makes an environment supported or not is up to the
* particular plugin, but may include OS or available hardware.
*/
public abstract boolean isSupported();
/** /**
* Removes a listener for controller state change events. * Removes a listener for controller state change events.
*/ */

View file

@ -41,6 +41,7 @@ package net.java.games.input;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
@ -57,18 +58,8 @@ import net.java.games.util.plugins.*;
* @author Michael Martak * @author Michael Martak
*/ */
class DefaultControllerEnvironment extends ControllerEnvironment { class DefaultControllerEnvironment extends ControllerEnvironment {
/** static String libPath;
* Location of the LIB directory.
*/
static String libPath;
/**
* List of all controllers in this environment
*/
private ArrayList controllers;
private Collection loadedPlugins = new ArrayList();
/** /**
* Static utility method for loading native libraries. * Static utility method for loading native libraries.
* It will try to load from either the path given by * It will try to load from either the path given by
@ -90,28 +81,36 @@ class DefaultControllerEnvironment extends ControllerEnvironment {
}); });
} }
/** static String getPrivilegedProperty(final String property) {
* Public no-arg constructor. return (String)AccessController.doPrivileged(new PrivilegedAction() {
*/ public Object run() {
public DefaultControllerEnvironment() { return System.getProperty(property);
} }
});
private static String getPrivilegedProperty(final String property) { }
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property); static String getPrivilegedProperty(final String property, final String default_value) {
}
});
}
private static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() { return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() { public Object run() {
return System.getProperty(property, default_value); return System.getProperty(property, default_value);
} }
}); });
} }
/**
* List of all controllers in this environment
*/
private ArrayList controllers;
private Collection loadedPlugins = new ArrayList();
/**
* Public no-arg constructor.
*/
public DefaultControllerEnvironment() {
}
/** /**
* Returns a list of all controllers available to this environment, * Returns a list of all controllers available to this environment,
* or an empty array if there are no controllers in this environment. * or an empty array if there are no controllers in this environment.
@ -147,15 +146,20 @@ class DefaultControllerEnvironment extends ControllerEnvironment {
System.out.println("Trying to use default plugin, OS name " + osName +" not recognised"); System.out.println("Trying to use default plugin, OS name " + osName +" not recognised");
} }
} }
ArrayList pluginClassList = new ArrayList();
StringTokenizer pluginClassTok = new StringTokenizer(pluginClasses, " \t\n\r\f,;:"); StringTokenizer pluginClassTok = new StringTokenizer(pluginClasses, " \t\n\r\f,;:");
while(pluginClassTok.hasMoreTokens()) { while(pluginClassTok.hasMoreTokens()) {
String className = pluginClassTok.nextToken(); String className = pluginClassTok.nextToken();
try { try {
if(!loadedPlugins.contains(className)) { if(!loadedPlugins.contains(className)) {
Class ceClass = Class.forName(className); Class ceClass = Class.forName(className);
ControllerEnvironment ce = (ControllerEnvironment) ceClass.newInstance(); ControllerEnvironment ce = (ControllerEnvironment) ceClass.newInstance();
addControllers(ce.getControllers()); if(ce.isSupported()) {
addControllers(ce.getControllers());
loadedPlugins.add(ce.getClass().getName());
} else {
logln(ceClass.getName() + " is not supported");
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@ -199,9 +203,13 @@ class DefaultControllerEnvironment extends ControllerEnvironment {
envClasses[i].getName() envClasses[i].getName()
+" loaded by "+envClasses[i].getClassLoader()); +" loaded by "+envClasses[i].getClassLoader());
ControllerEnvironment ce = (ControllerEnvironment) ControllerEnvironment ce = (ControllerEnvironment)
envClasses[i].newInstance(); envClasses[i].newInstance();
addControllers(ce.getControllers()); if(ce.isSupported()) {
loadedPlugins.add(ce.getClass().getName()); addControllers(ce.getControllers());
loadedPlugins.add(ce.getClass().getName());
} else {
logln(envClasses[i].getName() + " is not supported");
}
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -219,4 +227,8 @@ class DefaultControllerEnvironment extends ControllerEnvironment {
controllers.add(c[i]); controllers.add(c[i]);
} }
} }
public boolean isSupported() {
return true;
}
} }

View file

@ -38,6 +38,7 @@
*****************************************************************************/ *****************************************************************************/
package net.java.games.input; package net.java.games.input;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -55,8 +56,54 @@ import java.security.PrivilegedAction;
* @version 1.0 * @version 1.0
*/ */
public final class OSXEnvironmentPlugin extends ControllerEnvironment implements Plugin { public final class OSXEnvironmentPlugin extends ControllerEnvironment implements Plugin {
private static boolean supported = false;
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static { static {
DefaultControllerEnvironment.loadLibrary("jinput-osx"); String osName = getPrivilegedProperty("os.name", "").trim();
if(osName.equals("Mac OS X")) {
// Could check isMacOSXEqualsOrBetterThan in here too.
supported = true;
loadLibrary("jinput-osx");
}
} }
private final static boolean isMacOSXEqualsOrBetterThan(int major_required, int minor_required) { private final static boolean isMacOSXEqualsOrBetterThan(int major_required, int minor_required) {
@ -70,7 +117,7 @@ public final class OSXEnvironmentPlugin extends ControllerEnvironment implements
major = Integer.parseInt(major_str); major = Integer.parseInt(major_str);
minor = Integer.parseInt(minor_str); minor = Integer.parseInt(minor_str);
} catch (Exception e) { } catch (Exception e) {
ControllerEnvironment.logln("Exception occurred while trying to determine OS version: " + e); logln("Exception occurred while trying to determine OS version: " + e);
// Best guess, no // Best guess, no
return false; return false;
} }
@ -80,13 +127,21 @@ public final class OSXEnvironmentPlugin extends ControllerEnvironment implements
private final Controller[] controllers; private final Controller[] controllers;
public OSXEnvironmentPlugin() { public OSXEnvironmentPlugin() {
this.controllers = enumerateControllers(); if(isSupported()) {
this.controllers = enumerateControllers();
} else {
this.controllers = new Controller[0];
}
} }
public final Controller[] getControllers() { public final Controller[] getControllers() {
return controllers; return controllers;
} }
public boolean isSupported() {
return supported;
}
private final static void addElements(OSXHIDQueue queue, List elements, List components, boolean map_mouse_buttons) throws IOException { private final static void addElements(OSXHIDQueue queue, List elements, List components, boolean map_mouse_buttons) throws IOException {
Iterator it = elements.iterator(); Iterator it = elements.iterator();
while (it.hasNext()) { while (it.hasNext()) {
@ -202,19 +257,19 @@ public final class OSXEnvironmentPlugin extends ControllerEnvironment implements
createControllersFromDevice(device, controllers); createControllersFromDevice(device, controllers);
device_used = old_size != controllers.size(); device_used = old_size != controllers.size();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to create controllers from device: " + device.getProductName()); logln("Failed to create controllers from device: " + device.getProductName());
} }
if (!device_used) if (!device_used)
device.release(); device.release();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to enumerate device: " + e.getMessage()); logln("Failed to enumerate device: " + e.getMessage());
} }
} }
} finally { } finally {
it.close(); it.close();
} }
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.log("Failed to enumerate devices: " + e.getMessage()); log("Failed to enumerate devices: " + e.getMessage());
return new Controller[]{}; return new Controller[]{};
} }
Controller[] controllers_array = new Controller[controllers.size()]; Controller[] controllers_array = new Controller[controllers.size()];

View file

@ -34,7 +34,8 @@ import net.java.games.util.plugins.Plugin;
* @author elias * @author elias
*/ */
public class AWTEnvironmentPlugin extends ControllerEnvironment implements Plugin { public class AWTEnvironmentPlugin extends ControllerEnvironment implements Plugin {
private final Controller[] controllers;
private final Controller[] controllers;
public AWTEnvironmentPlugin() { public AWTEnvironmentPlugin() {
this.controllers = new Controller[]{new AWTKeyboard(), new AWTMouse()}; this.controllers = new Controller[]{new AWTKeyboard(), new AWTMouse()};
@ -43,4 +44,8 @@ public class AWTEnvironmentPlugin extends ControllerEnvironment implements Plugi
public Controller[] getControllers() { public Controller[] getControllers() {
return controllers; return controllers;
} }
public boolean isSupported() {
return true;
}
} }

View file

@ -41,21 +41,64 @@ import java.security.PrivilegedAction;
public final class LinuxEnvironmentPlugin extends ControllerEnvironment implements Plugin { public final class LinuxEnvironmentPlugin extends ControllerEnvironment implements Plugin {
private final static String LIBNAME = "jinput-linux"; private final static String LIBNAME = "jinput-linux";
private final static String POSTFIX64BIT = "64"; private final static String POSTFIX64BIT = "64";
private static boolean supported = false;
private final Controller[] controllers; private final Controller[] controllers;
private final List devices = new ArrayList(); private final List devices = new ArrayList();
private final static LinuxDeviceThread device_thread = new LinuxDeviceThread(); private final static LinuxDeviceThread device_thread = new LinuxDeviceThread();
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static { static {
try { String osName = getPrivilegedProperty("os.name", "").trim();
DefaultControllerEnvironment.loadLibrary(LIBNAME); if(osName.equals("Linux")) {
} catch (UnsatisfiedLinkError e) { supported = true;
try { try {
DefaultControllerEnvironment.loadLibrary(LIBNAME + POSTFIX64BIT); loadLibrary(LIBNAME);
} catch (UnsatisfiedLinkError e2) { } catch (UnsatisfiedLinkError e) {
ControllerEnvironment.logln("Failed to load 64 bit library: " + e2.getMessage()); try {
// throw original error loadLibrary(LIBNAME + POSTFIX64BIT);
throw e; } catch (UnsatisfiedLinkError e2) {
logln("Failed to load 64 bit library: " + e2.getMessage());
// throw original error
throw e;
}
} }
} }
} }
@ -65,15 +108,19 @@ public final class LinuxEnvironmentPlugin extends ControllerEnvironment implemen
} }
public LinuxEnvironmentPlugin() { public LinuxEnvironmentPlugin() {
this.controllers = enumerateControllers(); if(isSupported()) {
ControllerEnvironment.logln("Linux plugin claims to have found " + controllers.length + " controllers"); this.controllers = enumerateControllers();
AccessController.doPrivileged( logln("Linux plugin claims to have found " + controllers.length + " controllers");
new PrivilegedAction() { AccessController.doPrivileged(
public final Object run() { new PrivilegedAction() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook()); public final Object run() {
return null; Runtime.getRuntime().addShutdownHook(new ShutdownHook());
} return null;
}); }
});
} else {
controllers = new Controller[0];
}
} }
/** Returns a list of all controllers available to this environment, /** Returns a list of all controllers available to this environment,
@ -120,7 +167,7 @@ public final class LinuxEnvironmentPlugin extends ControllerEnvironment implemen
povs[3][1] = event_component; povs[3][1] = event_component;
break; break;
default: default:
ControllerEnvironment.logln("Unknown POV instance: " + native_code); logln("Unknown POV instance: " + native_code);
break; break;
} }
} else if (identifier != null) { } else if (identifier != null) {
@ -305,7 +352,7 @@ public final class LinuxEnvironmentPlugin extends ControllerEnvironment implemen
} else } else
device.close(); device.close();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to open device (" + event_file + "): " + e.getMessage()); logln("Failed to open device (" + event_file + "): " + e.getMessage());
} }
} }
} }
@ -357,11 +404,11 @@ public final class LinuxEnvironmentPlugin extends ControllerEnvironment implemen
} else } else
device.close(); device.close();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to create Controller: " + e.getMessage()); logln("Failed to create Controller: " + e.getMessage());
device.close(); device.close();
} }
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to open device (" + event_file + "): " + e.getMessage()); logln("Failed to open device (" + event_file + "): " + e.getMessage());
} }
} }
} }
@ -373,9 +420,13 @@ public final class LinuxEnvironmentPlugin extends ControllerEnvironment implemen
LinuxDevice device = (LinuxDevice)devices.get(i); LinuxDevice device = (LinuxDevice)devices.get(i);
device.close(); device.close();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to close device: " + e.getMessage()); logln("Failed to close device: " + e.getMessage());
} }
} }
} }
} }
public boolean isSupported() {
return supported;
}
} }

View file

@ -190,7 +190,7 @@ final class LinuxEventDevice implements LinuxDevice {
rumblers.add(new LinuxRumbleFF(this)); rumblers.add(new LinuxRumbleFF(this));
} }
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to enumerate rumblers: " + e.getMessage()); LinuxEnvironmentPlugin.logln("Failed to enumerate rumblers: " + e.getMessage());
} }
return (Rumbler[])rumblers.toArray(new Rumbler[]{}); return (Rumbler[])rumblers.toArray(new Rumbler[]{});
} }

View file

@ -56,7 +56,7 @@ abstract class LinuxForceFeedbackEffect implements Rumbler {
write_task.write(0); write_task.write(0);
} }
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to rumble: " + e); LinuxEnvironmentPlugin.logln("Failed to rumble: " + e);
} }
} }

View file

@ -88,7 +88,7 @@ final class LinuxPOV extends LinuxComponent {
else if (last_x == 1 && last_y == 1) else if (last_x == 1 && last_y == 1)
return Component.POV.DOWN_RIGHT; return Component.POV.DOWN_RIGHT;
else { else {
ControllerEnvironment.logln("Unknown values x = " + last_x + " | y = " + last_y); LinuxEnvironmentPlugin.logln("Unknown values x = " + last_x + " | y = " + last_y);
return Component.POV.OFF; return Component.POV.OFF;
} }
} }

View file

@ -42,6 +42,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import net.java.games.util.plugins.Plugin; import net.java.games.util.plugins.Plugin;
@ -52,8 +53,53 @@ import net.java.games.util.plugins.Plugin;
* @version 1.0 * @version 1.0
*/ */
public final class DirectInputEnvironmentPlugin extends ControllerEnvironment implements Plugin { public final class DirectInputEnvironmentPlugin extends ControllerEnvironment implements Plugin {
private static boolean supported = false;
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static { static {
DefaultControllerEnvironment.loadLibrary("jinput-dx8"); String osName = getPrivilegedProperty("os.name", "").trim();
if(osName.startsWith("Windows")) {
supported = true;
loadLibrary("jinput-dx8");
}
} }
private final Controller[] controllers; private final Controller[] controllers;
@ -61,29 +107,36 @@ public final class DirectInputEnvironmentPlugin extends ControllerEnvironment im
private final DummyWindow window; private final DummyWindow window;
/** Creates new DirectInputEnvironment */ /** Creates new DirectInputEnvironment */
public DirectInputEnvironmentPlugin() { public DirectInputEnvironmentPlugin() {
DummyWindow window = null; DummyWindow window = null;
Controller[] controllers = new Controller[]{}; Controller[] controllers = new Controller[]{};
try { if(isSupported()) {
window = new DummyWindow();
try { try {
controllers = enumControllers(window); window = new DummyWindow();
try {
controllers = enumControllers(window);
} catch (IOException e) {
window.destroy();
throw e;
}
} catch (IOException e) { } catch (IOException e) {
window.destroy(); logln("Failed to enumerate devices: " + e.getMessage());
throw e;
} }
} catch (IOException e) { this.window = window;
ControllerEnvironment.logln("Failed to enumerate devices: " + e.getMessage()); this.controllers = controllers;
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
return null;
}
});
} else {
// These are final fields, so can't set them, then over ride
// them if we are supported.
this.window = null;
this.controllers = controllers;
} }
this.window = window;
this.controllers = controllers;
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
return null;
}
});
} }
public final Controller[] getControllers() { public final Controller[] getControllers() {
@ -185,4 +238,8 @@ public final class DirectInputEnvironmentPlugin extends ControllerEnvironment im
*/ */
} }
} }
public boolean isSupported() {
return supported;
}
} // class DirectInputEnvironment } // class DirectInputEnvironment

View file

@ -82,7 +82,7 @@ final class IDirectInput {
IDirectInputDevice device = new IDirectInputDevice(window, address, instance_guid, product_guid, dev_type, dev_subtype, instance_name, product_name); IDirectInputDevice device = new IDirectInputDevice(window, address, instance_guid, product_guid, dev_type, dev_subtype, instance_name, product_name);
devices.add(device); devices.add(device);
} catch (IOException e) { } catch (IOException e) {
DefaultControllerEnvironment.logln("Failed to initialize device " + product_name + " because of: " + e); DirectInputEnvironmentPlugin.logln("Failed to initialize device " + product_name + " because of: " + e);
} }
} }

View file

@ -228,7 +228,7 @@ final class IDirectInputDevice {
enumEffects(); enumEffects();
createRumblers(); createRumblers();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to create rumblers: " + e.getMessage()); DirectInputEnvironmentPlugin.logln("Failed to create rumblers: " + e.getMessage());
} }
/* Some DirectInput lamer-designer made the device state /* Some DirectInput lamer-designer made the device state
* axis mode be per-device not per-axis, so I'll just * axis mode be per-device not per-axis, so I'll just

View file

@ -64,7 +64,7 @@ final class IDirectInputEffect implements Rumbler {
} else } else
stop(); stop();
} catch (IOException e) { } catch (IOException e) {
ControllerEnvironment.logln("Failed to set rumbler gain: " + e.getMessage()); DirectInputEnvironmentPlugin.logln("Failed to set rumbler gain: " + e.getMessage());
} }
} }

View file

@ -42,6 +42,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import net.java.games.util.plugins.Plugin; import net.java.games.util.plugins.Plugin;
@ -52,21 +53,68 @@ import net.java.games.util.plugins.Plugin;
* @version 1.0 * @version 1.0
*/ */
public final class RawInputEnvironmentPlugin extends ControllerEnvironment implements Plugin { public final class RawInputEnvironmentPlugin extends ControllerEnvironment implements Plugin {
private static boolean supported = false;
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static { static {
DefaultControllerEnvironment.loadLibrary("jinput-raw"); String osName = getPrivilegedProperty("os.name", "").trim();
if(osName.startsWith("Windows")) {
supported = true;
loadLibrary("jinput-raw");
}
} }
private final Controller[] controllers; private final Controller[] controllers;
/** Creates new DirectInputEnvironment */ /** Creates new DirectInputEnvironment */
public RawInputEnvironmentPlugin() { public RawInputEnvironmentPlugin() {
RawInputEventQueue queue; RawInputEventQueue queue;
Controller[] controllers = new Controller[]{}; Controller[] controllers = new Controller[]{};
try { if(isSupported()) {
queue = new RawInputEventQueue(); try {
controllers = enumControllers(queue); queue = new RawInputEventQueue();
} catch (IOException e) { controllers = enumControllers(queue);
ControllerEnvironment.logln("Failed to enumerate devices: " + e.getMessage()); } catch (IOException e) {
logln("Failed to enumerate devices: " + e.getMessage());
}
} }
this.controllers = controllers; this.controllers = controllers;
} }
@ -122,6 +170,10 @@ public final class RawInputEnvironmentPlugin extends ControllerEnvironment imple
return controllers_array; return controllers_array;
} }
public boolean isSupported() {
return supported;
}
/* /*
* The raw input API, while being able to access * The raw input API, while being able to access
* multiple mice and keyboards, is a bit raw (hah) * multiple mice and keyboards, is a bit raw (hah)
@ -151,4 +203,5 @@ public final class RawInputEnvironmentPlugin extends ControllerEnvironment imple
private final static native byte[] getKeyboardClassGUID(); private final static native byte[] getKeyboardClassGUID();
private final static native byte[] getMouseClassGUID(); private final static native byte[] getMouseClassGUID();
} // class DirectInputEnvironment } // class DirectInputEnvironment

View file

@ -3,10 +3,12 @@
<project name="JInput dx8 port, Native code" basedir="." default="compile"> <project name="JInput dx8 port, Native code" basedir="." default="compile">
<property environment="env"/> <property environment="env"/>
<property name="dxhome" location="${env.DXSDK_DIR}"/> <property name="dxhome" location="${env.DXSDK_DIR}"/>
<property name="sdkhome" location="${env.MSSDk}"/> <property name="sdkhome" location="c:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2"/>
<target name="compile_dir"> <target name="compile_dir">
<echo message="${compiledir}"/> <echo message="${compiledir}"/>
<echo message="sdkhome: ${sdkhome}"/>
<echo message="dxhome: ${dxhome}"/>
<apply dir="${compiledir}" failonerror="true" executable="cl" dest="${compiledir}" skipemptyfilesets="true"> <apply dir="${compiledir}" failonerror="true" executable="cl" dest="${compiledir}" skipemptyfilesets="true">
<arg line="/Ox /Wp64 /W2 /nologo /c"/> <arg line="/Ox /Wp64 /W2 /nologo /c"/>
<arg value="/I${sdkhome}\include"/> <arg value="/I${sdkhome}\include"/>
@ -28,7 +30,7 @@
<srcfile/> <srcfile/>
<arg line="/Fe${dllname} /link"/> <arg line="/Fe${dllname} /link"/>
<arg value="/LIBPATH:${java.home}\lib"/> <arg value="/LIBPATH:${java.home}\lib"/>
<arg value="/LIBPATH:${dxhome}\lib\x86"/> <arg value="/LIBPATH:${dxhome}\lib"/>
<arg value="/LIBPATH:${sdkhome}\lib"/> <arg value="/LIBPATH:${sdkhome}\lib"/>
<arg line="/DLL ${libs}"/> <arg line="/DLL ${libs}"/>
<fileset dir="${commonhome}/src/native" includes="*.obj"/> <fileset dir="${commonhome}/src/native" includes="*.obj"/>

View file

@ -21,12 +21,10 @@ public class WinTabContext {
} }
public synchronized void open() { public synchronized void open() {
ControllerEnvironment.logln("Opening context");
this.hCTX = nOpen(window.getHwnd()); this.hCTX = nOpen(window.getHwnd());
List devices = new ArrayList(); List devices = new ArrayList();
int numSupportedDevices = nGetNumberOfSupportedDevices(); int numSupportedDevices = nGetNumberOfSupportedDevices();
ControllerEnvironment.logln(numSupportedDevices + " devices maximum supported");
for(int i=0;i<numSupportedDevices;i++) { for(int i=0;i<numSupportedDevices;i++) {
WinTabDevice newDevice = WinTabDevice.createDevice(this,i); WinTabDevice newDevice = WinTabDevice.createDevice(this,i);
if(newDevice!=null) { if(newDevice!=null) {
@ -38,26 +36,12 @@ public class WinTabContext {
} }
public synchronized void close() { public synchronized void close() {
ControllerEnvironment.logln("Closing context");
nClose(hCTX); nClose(hCTX);
} }
public synchronized void processEvents() { public synchronized void processEvents() {
WinTabPacket[] packets = nGetPackets(hCTX); WinTabPacket[] packets = nGetPackets(hCTX);
//ControllerEnvironment.logln("Packets read: " + packets.length);
for(int i=0;i<packets.length;i++) { for(int i=0;i<packets.length;i++) {
//ControllerEnvironment.logln("Packet time: " + packets[i].PK_TIME);
//ControllerEnvironment.logln("Packet x: " + packets[i].PK_X);
//ControllerEnvironment.logln("Packet y: " + packets[i].PK_Y);
//ControllerEnvironment.logln("Packet z: " + packets[i].PK_Z);
//ControllerEnvironment.logln("Packet buttons: " + packets[i].PK_BUTTONS);
//ControllerEnvironment.logln("Packet cursor: " + packets[i].PK_CURSOR);
//ControllerEnvironment.logln("Packet Normal Pressure: " + packets[i].PK_NORMAL_PRESSURE);
//ControllerEnvironment.logln("Packet Tangent Pressure: " + packets[i].PK_TANGENT_PRESSURE);
//ControllerEnvironment.logln("Packet Alt: " + packets[i].PK_ORIENTATION_ALT);
//ControllerEnvironment.logln("Packet Az: " + packets[i].PK_ORIENTATION_AZ);
//ControllerEnvironment.logln("Packet Twist: " + packets[i].PK_ORIENTATION_TWIST);
// TODO I can't seem to find a way to identify which device the packet is for // TODO I can't seem to find a way to identify which device the packet is for
// This is not good. // This is not good.
// NASTY HACK based of assumptions that might very well be wrong // NASTY HACK based of assumptions that might very well be wrong

View file

@ -50,73 +50,73 @@ public class WinTabDevice extends AbstractController {
public static WinTabDevice createDevice(WinTabContext context, int deviceIndex) { public static WinTabDevice createDevice(WinTabContext context, int deviceIndex) {
String name = nGetName(deviceIndex); String name = nGetName(deviceIndex);
ControllerEnvironment.logln("Device " + deviceIndex + ", name: " + name); WinTabEnvironmentPlugin.logln("Device " + deviceIndex + ", name: " + name);
List componentsList = new ArrayList(); List componentsList = new ArrayList();
int[] axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.XAxis); int[] axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.XAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("ZAxis not supported"); WinTabEnvironmentPlugin.logln("ZAxis not supported");
} else { } else {
ControllerEnvironment.logln("Xmin: " + axisDetails[0] + ", Xmax: " + axisDetails[1]); WinTabEnvironmentPlugin.logln("Xmin: " + axisDetails[0] + ", Xmax: " + axisDetails[1]);
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.XAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.XAxis, axisDetails));
} }
axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.YAxis); axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.YAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("YAxis not supported"); WinTabEnvironmentPlugin.logln("YAxis not supported");
} else { } else {
ControllerEnvironment.logln("Ymin: " + axisDetails[0] + ", Ymax: " + axisDetails[1]); WinTabEnvironmentPlugin.logln("Ymin: " + axisDetails[0] + ", Ymax: " + axisDetails[1]);
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.YAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.YAxis, axisDetails));
} }
axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.ZAxis); axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.ZAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("ZAxis not supported"); WinTabEnvironmentPlugin.logln("ZAxis not supported");
} else { } else {
ControllerEnvironment.logln("Zmin: " + axisDetails[0] + ", Zmax: " + axisDetails[1]); WinTabEnvironmentPlugin.logln("Zmin: " + axisDetails[0] + ", Zmax: " + axisDetails[1]);
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.ZAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.ZAxis, axisDetails));
} }
axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.NPressureAxis); axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.NPressureAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("NPressureAxis not supported"); WinTabEnvironmentPlugin.logln("NPressureAxis not supported");
} else { } else {
ControllerEnvironment.logln("NPressMin: " + axisDetails[0] + ", NPressMax: " + axisDetails[1]); WinTabEnvironmentPlugin.logln("NPressMin: " + axisDetails[0] + ", NPressMax: " + axisDetails[1]);
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.NPressureAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.NPressureAxis, axisDetails));
} }
axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.TPressureAxis); axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.TPressureAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("TPressureAxis not supported"); WinTabEnvironmentPlugin.logln("TPressureAxis not supported");
} else { } else {
ControllerEnvironment.logln("TPressureAxismin: " + axisDetails[0] + ", TPressureAxismax: " + axisDetails[1]); WinTabEnvironmentPlugin.logln("TPressureAxismin: " + axisDetails[0] + ", TPressureAxismax: " + axisDetails[1]);
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.TPressureAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.TPressureAxis, axisDetails));
} }
axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.OrientationAxis); axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.OrientationAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("OrientationAxis not supported"); WinTabEnvironmentPlugin.logln("OrientationAxis not supported");
} else { } else {
ControllerEnvironment.logln("OrientationAxis mins/maxs: " + axisDetails[0] + "," + axisDetails[1] + ", " + axisDetails[2] + "," + axisDetails[3] + ", " + axisDetails[4] + "," + axisDetails[5]); WinTabEnvironmentPlugin.logln("OrientationAxis mins/maxs: " + axisDetails[0] + "," + axisDetails[1] + ", " + axisDetails[2] + "," + axisDetails[3] + ", " + axisDetails[4] + "," + axisDetails[5]);
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.OrientationAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.OrientationAxis, axisDetails));
} }
axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.RotationAxis); axisDetails = nGetAxisDetails(deviceIndex, WinTabComponent.RotationAxis);
if(axisDetails.length==0) { if(axisDetails.length==0) {
ControllerEnvironment.logln("RotationAxis not supported"); WinTabEnvironmentPlugin.logln("RotationAxis not supported");
} else { } else {
ControllerEnvironment.logln("RotationAxis is supported (by the device, not by this plugin)"); WinTabEnvironmentPlugin.logln("RotationAxis is supported (by the device, not by this plugin)");
componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.RotationAxis, axisDetails)); componentsList.addAll(WinTabComponent.createComponents(context, deviceIndex, WinTabComponent.RotationAxis, axisDetails));
} }
String[] cursorNames = nGetCursorNames(deviceIndex); String[] cursorNames = nGetCursorNames(deviceIndex);
componentsList.addAll(WinTabComponent.createCursors(context, deviceIndex, cursorNames)); componentsList.addAll(WinTabComponent.createCursors(context, deviceIndex, cursorNames));
for(int i=0;i<cursorNames.length;i++) { for(int i=0;i<cursorNames.length;i++) {
ControllerEnvironment.logln("Cursor " + i + "'s name: " + cursorNames[i]); WinTabEnvironmentPlugin.logln("Cursor " + i + "'s name: " + cursorNames[i]);
} }
int numberOfButtons = nGetMaxButtonCount(deviceIndex); int numberOfButtons = nGetMaxButtonCount(deviceIndex);
ControllerEnvironment.logln("Device has " + numberOfButtons + " buttons"); WinTabEnvironmentPlugin.logln("Device has " + numberOfButtons + " buttons");
componentsList.addAll(WinTabComponent.createButtons(context, deviceIndex, numberOfButtons)); componentsList.addAll(WinTabComponent.createButtons(context, deviceIndex, numberOfButtons));
Component[] components = (Component[])componentsList.toArray(new Component[0]); Component[] components = (Component[])componentsList.toArray(new Component[0]);

View file

@ -1,5 +1,6 @@
package net.java.games.input; package net.java.games.input;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
@ -9,8 +10,52 @@ import java.util.List;
import net.java.games.util.plugins.Plugin; import net.java.games.util.plugins.Plugin;
public class WinTabEnvironmentPlugin extends ControllerEnvironment implements Plugin { public class WinTabEnvironmentPlugin extends ControllerEnvironment implements Plugin {
static { private static boolean supported = false;
DefaultControllerEnvironment.loadLibrary("jinput-wintab");
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static {
String osName = getPrivilegedProperty("os.name", "").trim();
if(osName.startsWith("Windows")) {
supported = true;
loadLibrary("jinput-wintab");
}
} }
private final Controller[] controllers; private final Controller[] controllers;
@ -20,35 +65,45 @@ public class WinTabEnvironmentPlugin extends ControllerEnvironment implements Pl
/** Creates new DirectInputEnvironment */ /** Creates new DirectInputEnvironment */
public WinTabEnvironmentPlugin() { public WinTabEnvironmentPlugin() {
DummyWindow window = null; if(isSupported()) {
WinTabContext winTabContext = null; DummyWindow window = null;
Controller[] controllers = new Controller[]{}; WinTabContext winTabContext = null;
try { Controller[] controllers = new Controller[]{};
window = new DummyWindow();
winTabContext = new WinTabContext(window);
try { try {
winTabContext.open(); window = new DummyWindow();
controllers = winTabContext.getControllers(); winTabContext = new WinTabContext(window);
try {
winTabContext.open();
controllers = winTabContext.getControllers();
} catch (Exception e) {
window.destroy();
throw e;
}
} catch (Exception e) { } catch (Exception e) {
window.destroy(); logln("Failed to enumerate devices: " + e.getMessage());
throw e; e.printStackTrace();
} }
} catch (Exception e) { this.window = window;
ControllerEnvironment.logln("Failed to enumerate devices: " + e.getMessage()); this.controllers = controllers;
e.printStackTrace(); this.winTabContext = winTabContext;
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
return null;
}
});
} else {
winTabContext = null;
controllers = new Controller[]{};
window = null;
} }
this.window = window;
this.controllers = controllers;
this.winTabContext = winTabContext;
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
return null;
}
});
} }
public boolean isSupported() {
return supported;
}
public Controller[] getControllers() { public Controller[] getControllers() {
return controllers; return controllers;
} }