diff options
148 files changed, 13069 insertions, 10843 deletions
@@ -0,0 +1,31 @@ +Major: + - Flattened Mouse so it isn't separated into child controllers (ball, buttons). + - Removed useless component members from Mouse and Keyboard. For example, Mouse.getX() is now simply getComponent(Component.Identifier.Axis.X). + - Removed StandardKeyboard. + - Removed Mouse.Button and Keyboard.Key since they only complicated plugins + - Added Keyboard.isKeyDown(Component.Identifier.Key) (with default false for non-existent keys). + - Removed Component.isPolling() and Component.setPolling(). + - Removed Component.isNormalized() since all plugins return normalized data for absolute axes anyway. + - Windows XP: Added RawInputEnvironmentPlugin to enable multiple mice and keyboards. DirectInput will only report one system mouse and one system keyboard where all mice and keyboard input are combined (in fact, Windows was the OS with the most complicated and confusing APIs, apart from the fact that I had to code two separate plugins for it). The RawInputEnvironment is not enabled per default, since it seems to exclude mouse and keybaord input to DirectInput which will probably confuse unsuspecting applications. But at least there is now a method to access multiple keyboards and mice on windows xp. + - DirectInput: Got rid of the nasty DataFormat special case handling. The DirectInput data format is now one large (java int) array which is a better match for the jinput abstraction than the builtin DirectInput data formats for mice, keyboards and joysticks. + - Added event queue support. An Event contains a Component, a value and a relative timestamp in nanoseconds. + - Basically rewrote all plugins from scratch, with focus on minimizing the amount of native code in general, and in particular for moving decisions from native to java, making the native code more general purpose and less likely to need changes. Additionally, all plugins support the new event queue interface. All plugins now have much better error handling (exceptions) and much tighter native code (no more global variables, helper functions declared static etc.). Additionally, all plugin internal java classes are package protected and final for added security. + - Mac OS X: Added missing features and fixed broken Mouse. + - Cleaned up build system and added option for a combined jinput.jar with all plugins as opposed to just the OS specific packages + - JInput should now be thread safe. + - Mac OS X intel mac support. The jinput-osx.jnilib library is for 10.4 or better (both ppc and i386), while libjinput-osx-legacy.jnilib is for 10.3 or earlier. + +Minor: + - Removed keyId from Component.Identifier.Key + - Made components, children and rumblers final in AbstractController + - Added Identifier->Component Map to AbstractController to avoid Keyboard special code and to speed up the Component.getComponent() method in general. + - Added exceptions to native code for accurate error messages (instead of the standard printf). I use the checked IOException exclusively, but since exceptions are not exposed to user code, that can easily be changed. + - Added printfJava(env, format, ...) to native code to avoid printfs altogether + +Issues not fixed: + - Linux plugin report buttons ids with semantic value (trigger button, thumb button etc.) while all other plugins use simple button indices (0, 1, 2, 3 etc.). This is a property of the underlying linux input API and will probably confuse some jinput programs. + - The Plugin architecture seems somewhat complex and IMHO unnecessary. It involves custom Classloaders to separate the each Plugin's namespaces, but since you can't use custom Classloaders in restricted environments (web start, applets) the plugins have to have manually separate namespaces anyway. I'm inclined to remove it, but since it was there originally, there is probably some use case it covers I don't know about. + +TODO: + - A utility for collecting events from multiple controller at once. An application then just needs to register all its devices to the utility and only call poll() and getEventQueue() in one place. Event will probably need to be extended with a getController() method. + @@ -1,26 +1,9 @@ <?xml version="1.0"?> -<!-- Written to assume that classpath is rooted in the current directory. --> -<!-- So this should be OK if you make this script in the root of a filesystem. --> -<!-- If not, you may prefer to adjust the basedir, or move some directories around. --> -<!-- The idea is that both Ant and NetBeans have to know what the package root is --> -<!-- for the classes in your application. --> <project name="Sun Games Initiative Client Technologies" basedir="." default="all"> - - <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! --> - <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. --> - <target name="init"> - <!-- You can set up any variables you want used throughout the script here. --> - <!-- <property name="hello" value="world"/ --> - <!-- To use e.g. Jikes, uncomment this line. --> - <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) --> - <!-- <property name="build.compiler" value="jikes"/> --> - <!-- You might like to set up some overridable paths, etc.: --> - <!-- <property name="mylib" value="../lib/mylib.jar"/> --> - <!-- If we are running in windows, set dx8 property to true --> - <condition property="dx8" > + <condition property="windows" > <os family="windows" /> </condition> @@ -39,142 +22,149 @@ </condition> </target> - <target name="core" depends="init"> - <!-- Both srcdir and destdir should be package roots. --> - <!-- They could be different of course; in that case NetBeans can also be set --> - <!-- up to compile to a different filesystem in the same way; see Compiler Types: --> - <ant dir="coreAPI" /> - </target> - - <target name="windows_plugin" depends="core" if="dx8" > - <!-- Both srcdir and destdir should be package roots. --> - <!-- They could be different of course; in that case NetBeans can also be set --> - <!-- up to compile to a different filesystem in the same way; see Compiler Types: --> - <ant dir="plugins/DX8" /> - </target> + <target name="runtest" depends="dist"> + <java classname="${mainclass}" + fork="true" failonerror="true" dir="."> + <classpath> + <pathelement location="dist/jinput.jar"/> + <pathelement location="dist/jinput-test.jar"/> + </classpath> + <jvmarg value="-Djava.library.path=dist"/> + </java> + </target> - <target name="linux_plugin" depends="core" if="linux" > - <!-- Both srcdir and destdir should be package roots. --> - <!-- They could be different of course; in that case NetBeans can also be set --> - <!-- up to compile to a different filesystem in the same way; see Compiler Types: --> - <ant dir="plugins/linux" /> - </target> - - <target name="OSX_plugin" depends="core" if="osx" > - <ant dir="plugins/OSX" /> - </target> + <target name="texttest"> + <antcall target="runtest"> + <param name="mainclass" value="net.java.games.input.test.ControllerTextTest"/> + </antcall> + </target> - <target name="javadoc" depends="init"> - <!-- Both srcdir and destdir should be package roots. --> - <!-- They could be different of course; in that case NetBeans can also be set --> - <!-- up to compile to a different filesystem in the same way; see Compiler Types: --> - <ant dir="coreAPI" target="javadoc"/> - <ant dir="plugins/DX8" target="javadoc"/> - <ant dir="plugins/linux" target="javadoc"/> - <ant dir="plugins/OSX" target="javadoc"/> - </target> - - <target name="compile" depends="core,windows_plugin,linux_plugin,OSX_plugin" /> - - <target name="all" depends="init,compile" description="Build everything."> - <echo message="Application built. Hello ${hello}!"/> - </target> - - <target name="clean" depends="init" description="Clean all build products."> - <ant dir="plugins/DX8" target="clean"/> - <ant dir="plugins/linux" target="clean"/> - <ant dir="plugins/OSX" target="clean"/> - <ant dir="plugins/awt" target="clean"/> - <ant dir="coreAPI" target="clean"/> - <delete failonerror="no"> - <fileset dir="dist"> - <include name="**/*"/> - </fileset> - </delete> - </target> - - <target name="dist" depends="init,compile" description="Build the distribution file for this system"> + <target name="readtest" depends="init,all" description="Try running it."> + <antcall target="runtest"> + <param name="mainclass" value="net.java.games.input.test.ControllerReadTest"/> + </antcall> + </target> + + <target name="rumbletest" depends="init,all" description="Try running it."> + <antcall target="runtest"> + <param name="mainclass" value="net.java.games.input.test.RumbleTest"/> + </antcall> + </target> + + <macrodef name="iterate"> + <attribute name="target"/> + <sequential> + <subant target="@{target}"> + <fileset file="coreAPI/build.xml"/> + <fileset file="plugins/linux/build.xml"/> + <fileset file="plugins/windows/build.xml"/> + <fileset file="plugins/OSX/build.xml"/> + <fileset file="plugins/awt/build.xml"/> + </subant> + </sequential> + </macrodef> + + <target name="clean"> + <iterate target="clean"/> + <delete dir="dist" failonerror="no"/> + </target> + + <target name="all" depends="dist"> + </target> + + <target name="javadoc" depends="init"> + <iterate target="javadoc"/> + </target> + + <target name="dist" depends="init" description="Build the distribution file for this system"> + <iterate target="all"/> <mkdir dir="dist"/> - <mkdir dir="dist/controller"/> - <copy file="coreAPI/bin/jinput.jar" todir="dist"/> - <copy file="coreAPI/lib/jutils.jar" todir="dist"/> - <copy todir="dist/controller"> - <fileset dir="coreAPI/src/tests/controller/"> - <include name="**/*"/> - </fileset> - </copy> - <zip destfile="dist/jinput_${os.name}_dist.zip" - basedir="dist" - excludes="*.zip" - /> + <jar jarfile="dist/jinput.jar" compress="true"> + <fileset dir="coreAPI/classes"> + <include name="**/*.class"/> + <exclude name="**/test/*.class"/> + </fileset> + <fileset dir="plugins/linux/classes"> + <include name="**/*.class"/> + </fileset> + <fileset dir="plugins/OSX/classes"> + <include name="**/*.class"/> + </fileset> + <fileset dir="plugins/awt/classes"> + <include name="**/*.class"/> + </fileset> + <fileset dir="plugins/windows/classes"> + <include name="**/*.class"/> + </fileset> + <zipfileset src="lib/jutils.jar" includes="**/*.class"/> + </jar> + <copy todir="dist"> + <fileset file="coreAPI/bin/jinput-test.jar"/> + <fileset dir="plugins/linux/bin" includes="*so"/> + <fileset dir="plugins/OSX/bin" includes="*jnilib"/> + <fileset dir="plugins/windows/bin" includes="*dll"/> + </copy> </target> - <target name="simple_dist" depends="init,compile,simple_windows,simple_linux,simple_osx" description="Build the simple jars for each platform"/> + <target name="simple_dist" depends="dist,simple_windows,simple_linux,simple_osx" description="Build the simple jars for each platform"/> - <target name="simple_linux" depends="init,compile" description="Build the simple linux jar" if="linux"> - <delete failonerror="no" file="jinput.jar"/> - <delete failonerror="no" file="jinput_linux.tgz"/> - <jar jarfile="jinput.jar" compress="true"> + <target name="simple_linux" depends="dist" description="Build the simple linux jar" if="linux"> + <jar jarfile="dist/jinput-linux.jar" compress="true"> <fileset dir="coreAPI/classes"> <include name="**/*.class"/> </fileset> <fileset dir="plugins/linux/classes"> <include name="**/*.class"/> </fileset> - <zipfileset src="coreAPI/lib/jutils.jar" includes="**/*.class"/> + <zipfileset src="lib/jutils.jar" includes="**/*.class"/> </jar> - <tar destfile="jinput_linux.tgz" compression="gzip"> + <tar destfile="dist/jinput_linux.tgz" compression="gzip"> <tarfileset dir="."> - <include name="jinput.jar"/> + <include name="dist/jinput-linux.jar"/> </tarfileset> - <tarfileset dir="plugins/linux/src/native"> + <tarfileset dir="plugins/linux/bin"> <include name="*.so"/> </tarfileset> </tar> - <delete failonerror="no" file="jinput.jar"/> </target> - <target name="simple_windows" depends="init,compile" description="Build the simple windows jar" if="dx8"> - <delete failonerror="no" file="jinput.jar"/> - <delete failonerror="no" file="jinput_windows.zip"/> - <jar jarfile="jinput.jar" compress="true"> + + <target name="simple_windows" depends="dist" description="Build the simple windows jar" if="windows"> + <jar jarfile="dist/jinput-windows.jar" compress="true"> <fileset dir="coreAPI/classes"> <include name="**/*.class"/> </fileset> - <fileset dir="plugins/DX8/classes"> + <fileset dir="plugins/windows/classes"> <include name="**/*.class"/> </fileset> - <zipfileset src="coreAPI/lib/jutils.jar" includes="**/*.class"/> + <zipfileset src="lib/jutils.jar" includes="**/*.class"/> </jar> - <zip destfile="jinput_windows.zip"> + <zip destfile="dist/jinput_windows.zip"> <zipfileset dir="."> - <include name="jinput.jar"/> + <include name="dist/jinput-windows.jar"/> </zipfileset> - <zipfileset dir="plugins/DX8/bin"> + <zipfileset dir="plugins/windows/bin"> <include name="*.dll"/> </zipfileset> </zip> - <delete failonerror="no" file="jinput.jar"/> </target> - <target name="simple_osx" depends="init,compile" description="Build the simple osx jar" if="osx"> - <delete failonerror="no" file="jinput.jar"/> - <delete failonerror="no" file="jinput_osx.tgz"/> - <jar jarfile="jinput.jar" compress="true"> + + <target name="simple_osx" depends="dist" description="Build the simple osx jar" if="osx"> + <jar jarfile="dist/jinput-osx.jar" compress="true"> <fileset dir="coreAPI/classes"> <include name="**/*.class"/> </fileset> <fileset dir="plugins/OSX/classes"> <include name="**/*.class"/> </fileset> - <zipfileset src="coreAPI/lib/jutils.jar" includes="**/*.class"/> + <zipfileset src="lib/jutils.jar" includes="**/*.class"/> </jar> - <tar destfile="jinput_osx.tgz" compression="gzip"> + <tar destfile="dist/jinput_osx.tgz" compression="gzip"> <tarfileset dir="."> - <include name="jinput.jar"/> + <include name="dist/jinput-osx.jar"/> </tarfileset> - <tarfileset dir="plugins/OSX/src/native"> + <tarfileset dir="plugins/OSX/bin"> <include name="*.jnilib"/> </tarfileset> </tar> - <delete failonerror="no" file="jinput.jar"/> </target> </project> diff --git a/coreAPI/build.xml b/coreAPI/build.xml index 8d747dc..a87fdd6 100644 --- a/coreAPI/build.xml +++ b/coreAPI/build.xml @@ -1,104 +1,32 @@ <?xml version="1.0"?> -<!-- Written to assume that classpath is rooted in the current directory. --> -<!-- So this should be OK if you make this script in the root of a filesystem. --> -<!-- If not, you may prefer to adjust the basedir, or move some directories around. --> -<!-- The idea is that both Ant and NetBeans have to know what the package root is --> -<!-- for the classes in your application. --> <project name="Game Input API" basedir="." default="all"> - - <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! --> - <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. --> - <target name="init"> - <!-- You can set up any variables you want used throughout the script here. --> - <!-- property name="hello" value="world" --> - <!-- To use e.g. Jikes, uncomment this line. --> - <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) --> - <!-- <property name="build.compiler" value="jikes"/> --> - <!-- You might like to set up some overridable paths, etc.: --> - <property name="utils" value="lib/jutils.jar"/> + <property name="utils" location="../lib/jutils.jar"/> <mkdir dir="apidocs"/> <mkdir dir="classes"/> <mkdir dir="bin"/> </target> <target name="compile" depends="init"> - <!-- Both srcdir and destdir should be package roots. --> - <!-- They could be different of course; in that case NetBeans can also be set --> - <!-- up to compile to a different filesystem in the same way; see Compiler Types: --> <javac srcdir="src/java" destdir="classes" debug="true" deprecation="true" source="1.4" target="1.4"> <include name="net/**"/> <!-- To add something to the classpath: --> <classpath> <pathelement location="${utils}"/> </classpath> - <!-- To exclude some files: --> - <!-- - <exclude name="com/foo/SomeFile.java"/> - <exclude name="com/foo/somepackage/"/> - --> </javac> </target> <target name="jar" depends="init,compile"> - <!-- To make a standalone app: --> - <!-- 1. Create a myapp.mf manifest somewhere. --> - <!-- 2. Put in it: --> - <!-- Manifest-Version: 1.0 --> - <!-- Main-Class: com.foo.Main --> - <!-- 3. Pass to <jar>: manifest="myapp.mf" --> - <jar jarfile="bin/jinput.jar" compress="true" basedir="classes"> - <include name="net/**"/> - <exclude name="**/*.java"/> - <exclude name="**/*.form"/> - <exclude name="myapp.mf"/> - <exclude name="myapp.jar"/> + <jar jarfile="bin/jinput-core.jar" compress="true" basedir="classes"> + <include name="net/java/games/input/*class"/> + </jar> + <jar jarfile="bin/jinput-test.jar" compress="true" basedir="classes"> + <include name="net/java/games/input/test/*class"/> </jar> - <copy file="bin/jinput.jar" todir="../plugins/DX8/lib" /> </target> - - <target name="texttest" depends="init,all" description="Try running it."> - <java classname="net.java.games.input.test.ControllerTextTest" - fork="true" failonerror="true" dir="src/tests"> - <classpath> - <pathelement location="bin/jinput.jar"/> - <pathelement location="${utils}"/> - </classpath> - <!-- Pass some args, perhaps: --> - <!-- <arg value="-myfile"/> --> - <!-- Will be given as an absolute path: --> - <!-- <arg file="myfile.txt"/> --> - </java> - </target> - <target name="readtest" depends="init,all" description="Try running it."> - <java classname="net.java.games.input.test.ControllerReadTest" - fork="true" failonerror="true" dir="src/tests"> - <classpath> - <pathelement location="bin/jinput.jar"/> - <pathelement location="${utils}"/> - </classpath> - <!-- Pass some args, perhaps: --> - <!-- <arg value="-myfile"/> --> - <!-- Will be given as an absolute path: --> - <!-- <arg file="myfile.txt"/> --> - </java> - </target> - <target name="rumbletest" depends="init,all" description="Try running it."> - <java classname="net.java.games.input.test.RumbleTest" - fork="true" failonerror="true" dir="src/tests"> - <classpath> - <pathelement location="bin/jinput.jar"/> - <pathelement location="${utils}"/> - </classpath> - <!-- Pass some args, perhaps: --> - <!-- <arg value="-myfile"/> --> - <!-- Will be given as an absolute path: --> - <!-- <arg file="myfile.txt"/> --> - </java> - </target> - <target name="javadoc" depends="init" description="Javadoc for my API."> <javadoc packagenames="net.java.games.input.*" destdir="apidocs" @@ -113,18 +41,12 @@ </target> <target name="clean" depends="init" description="Clean all build products."> - <delete> - <fileset dir="classes"> - <include name="**/*.class"/> - </fileset> - </delete> - <delete file="bin/jinput.jar"/> - <delete dir="apidocs"/> - <delete file="../plugins/DX8/lib/jinput.jar" /> + <delete dir="classes"/> + <delete dir="bin"/> + <delete dir="apidocs"/> </target> <target name="all" depends="init,jar" description="Build everything."> <echo message="JInput has been built and jinput.jar is located in the bin directory."/> - </target> - + </target> </project> diff --git a/coreAPI/src/java/net/java/games/input/AbstractComponent.java b/coreAPI/src/java/net/java/games/input/AbstractComponent.java index b829c1b..40a1750 100644 --- a/coreAPI/src/java/net/java/games/input/AbstractComponent.java +++ b/coreAPI/src/java/net/java/games/input/AbstractComponent.java @@ -38,6 +38,8 @@ *****************************************************************************/ package net.java.games.input; +import java.io.IOException; + /** * Skeleton implementation of a named axis. */ @@ -46,17 +48,12 @@ public abstract class AbstractComponent implements Component { /** * Human-readable name for this Axis */ - protected String name; - - /** - * Identifier for the axis - */ - protected Identifier id; + private final String name; - /** - * Whether this axis is ready to receive polling data - */ - private boolean polling; + private final Identifier id; + + private float value; + private float event_value; /** * Protected constructor @@ -65,7 +62,6 @@ public abstract class AbstractComponent implements Component { protected AbstractComponent(String name, Identifier id) { this.name = name; this.id = id; - this.polling = true; } /** @@ -84,30 +80,6 @@ public abstract class AbstractComponent implements Component { } /** - * Returns whether or not data polled from this axis is normalized - * between the values of -1.0f and 1.0f. - * @return true by default, can be overridden - */ - public boolean isNormalized() { - return true; - } - - /** - * Returns whether or not this axis is ready to receive polling data. - * By default, an abstract axis is set to receive polling data. - */ - public boolean isPolling() { - return polling; - } - - /** - * Sets whether or not the axis should receive polling data. - */ - public void setPolling(boolean polling) { - this.polling = polling; - } - - /** * Returns the suggested dead zone for this axis. Dead zone is the * amount polled data can vary before considered a significant change * in value. An application can safely ignore changes less than this @@ -125,10 +97,22 @@ public abstract class AbstractComponent implements Component { * 1.0f. * @return 0.0f by default, can be overridden */ - public float getPollData() { - return 0.0f; + public final float getPollData() { + return value; + } + + final void setPollData(float value) { + this.value = value; + } + + final float getEventValue() { + return event_value; } + final void setEventValue(float event_value) { + this.event_value = event_value; + } + /** * Returns a human-readable name for this axis. */ @@ -142,12 +126,7 @@ public abstract class AbstractComponent implements Component { public String toString() { return name; } + + protected abstract float poll() throws IOException; - /** - * Changes the name of this Axis. This should be done only during - * initialization of the axis so that its name remains immutable. - */ - public void setName(String name) { - this.name = name; - } } // AbstractAxis diff --git a/coreAPI/src/java/net/java/games/input/AbstractController.java b/coreAPI/src/java/net/java/games/input/AbstractController.java index 93475d2..266a303 100644 --- a/coreAPI/src/java/net/java/games/input/AbstractController.java +++ b/coreAPI/src/java/net/java/games/input/AbstractController.java @@ -38,27 +38,22 @@ *****************************************************************************/ package net.java.games.input; +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.ArrayList; + +import java.io.IOException; + /** * An AbstractController is a skeleton implementation of a controller that * contains a fixed number of axes, controllers, and rumblers. */ public abstract class AbstractController implements Controller { - - /** - * Null array representing no axes - */ - protected static final Component[] NO_COMPONENTS = {}; - - /** - * Null array representing no child controllers - */ - protected static final Controller[] NO_CONTROLLERS = {}; - - /** - * Null array representing no rumblers - */ - protected static final Rumbler[] NO_RUMBLERS = {}; - + final static int EVENT_QUEUE_DEPTH = 32; + + private final static Event event = new Event(); + /** * Human-readable name for this Controller */ @@ -67,26 +62,24 @@ public abstract class AbstractController implements Controller { /** * Array of components */ - protected Component[] components; + private final Component[] components; /** * Array of child controllers */ - protected Controller[] children; + private final Controller[] children; /** * Array of rumblers */ - protected Rumbler[] rumblers; - - /** - * Protected constructor for a controller; initially contains no axes, - * child controllers, or rumblers. - * @param name The name for the controller - */ - protected AbstractController(String name) { - this(name, NO_COMPONENTS, NO_CONTROLLERS, NO_RUMBLERS); - } + private final Rumbler[] rumblers; + + /** + * Map from Component.Identifiers to Components + */ + private final Map id_to_components = new HashMap(); + + private EventQueue event_queue = new EventQueue(EVENT_QUEUE_DEPTH); /** * Protected constructor for a controller containing the specified @@ -96,21 +89,24 @@ public abstract class AbstractController implements Controller { * @param children child controllers for the controller * @param rumblers rumblers for the controller */ - protected AbstractController(String name, Component[] components, - Controller[] children, Rumbler[] rumblers) { + protected AbstractController(String name, Component[] components, Controller[] children, Rumbler[] rumblers) { this.name = name; this.components = components; this.children = children; this.rumblers = rumblers; - } - + // process from last to first to let earlier listed Components get higher priority + for (int i = components.length - 1; i >= 0; i--) { + id_to_components.put(components[i].getIdentifier(), components[i]); + } + } + /** * Returns the controllers connected to make up this controller, or * an empty array if this controller contains no child controllers. * The objects in the array are returned in order of assignment priority * (primary stick, secondary buttons, etc.). */ - public Controller[] getControllers() { + public final Controller[] getControllers() { return children; } @@ -123,35 +119,23 @@ public abstract class AbstractController implements Controller { * The array returned is an empty array if this controller contains no components * (such as a logical grouping of child controllers). */ - public Component[] getComponents() { + public final Component[] getComponents() { return components; } /** * Returns a single component based on its identifier, or null * if no component with the specified type could be found. - * By default, AbstractController calls getComponents in this method so that - * subclasses may lazily initialize the array of components, if necessary. */ - public Component getComponent(Component.Identifier id) { - // Calls getAxes() so that subclasses may lazily set the array of axes. - Component[] components = getComponents(); - if (components.length == 0) { - return null; - } - for (int i = 0; i < components.length; i++) { - if (components[i].getIdentifier() == id) { - return components[i]; - } - } - return null; + public final Component getComponent(Component.Identifier id) { + return (Component)id_to_components.get(id); } /** * Returns the rumblers for sending feedback to this controller, or an * empty array if there are no rumblers on this controller. */ - public Rumbler[] getRumblers() { + public final Rumbler[] getRumblers() { return rumblers; } @@ -174,7 +158,7 @@ public abstract class AbstractController implements Controller { /** * Returns a human-readable name for this Controller. */ - public String getName() { + public final String getName() { return name; } @@ -190,5 +174,68 @@ public abstract class AbstractController implements Controller { public Type getType() { return Type.UNKNOWN; } - + + /** + * Creates a new EventQueue. Events in old queue are lost. + */ + public final void setEventQueueSize(int size) { + try { + setDeviceEventQueueSize(size); + event_queue = new EventQueue(size); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to create new event queue of size " + size + ": " + e); + } + } + + /** + * Plugins override this method to adjust their internal event queue size + */ + protected void setDeviceEventQueueSize(int size) throws IOException { + } + + public final EventQueue getEventQueue() { + return event_queue; + } + + protected abstract boolean getNextDeviceEvent(Event event) throws IOException; + + protected void pollDevice() throws IOException { + } + + /* poll() is synchronized to protect the static event */ + public synchronized boolean poll() { + Component[] components = getComponents(); + try { + pollDevice(); + for (int i = 0; i < components.length; i++) { + AbstractComponent component = (AbstractComponent)components[i]; + if (component.isRelative()) { + component.setPollData(0); + } else { + float value = component.poll(); + component.setPollData(value); + } + } + while (getNextDeviceEvent(event)) { + AbstractComponent component = (AbstractComponent)event.getComponent(); + float value = event.getValue(); + if (component.isRelative()) { + if (value == 0) + continue; + component.setPollData(component.getPollData() + value); + } else { + if (value == component.getEventValue()) + continue; + component.setEventValue(value); + } + if (!event_queue.isFull()) + event_queue.add(event); + } + return true; + } catch (IOException e) { + ControllerEnvironment.logln("Failed to poll device: " + e.getMessage()); + return false; + } + } + } // class AbstractController diff --git a/coreAPI/src/java/net/java/games/input/Component.java b/coreAPI/src/java/net/java/games/input/Component.java index 4f154d8..f3f9c9a 100644 --- a/coreAPI/src/java/net/java/games/input/Component.java +++ b/coreAPI/src/java/net/java/games/input/Component.java @@ -63,29 +63,6 @@ public interface Component { public abstract boolean isAnalog(); /** - * Returns whether or not data polled from this axis is normalized - * between the values of -1.0f and 1.0f. - * @see #getPollData - */ - public abstract boolean isNormalized(); - - /** - * Returns whether or not this axis is ready to receive polling data. - * @see #getPollData - * @see Controller#poll - * @see #setPolling - */ - public abstract boolean isPolling(); - - /** - * Sets whether or not the axis should receive polling data. - * @see #getPollData - * @see Controller#poll - * @see #isPolling - */ - public abstract void setPolling(boolean polling); - - /** * Returns the suggested dead zone for this axis. Dead zone is the * amount polled data can vary before considered a significant change * in value. An application can safely ignore changes less than this @@ -558,163 +535,148 @@ public interface Component { * Returns the side mouse button. */ public static final Button SIDE = new Button("Side"); - } /** * KeyIDs for standard PC (LATIN-1) keyboards */ public static class Key extends Identifier { - - private int keyID; - /** * Protected constructor */ - protected Key(String name, int keyID) { + protected Key(String name) { super(name); - this.keyID = keyID; - } - - protected Key(int keyID) { - this("Key " + keyID, keyID); - } - - public int getKeyIndex() { - return keyID; } /** * Standard keyboard (LATIN-1) keys * UNIX X11 keysym values are listed to the right */ - public static final Key VOID = new Key("Void", 0); // MS 0x00 UNIX 0xFFFFFF - public static final Key ESCAPE = new Key("Escape", 1); // MS 0x01 UNIX 0xFF1B - public static final Key _1 = new Key("1", 2); // MS 0x02 UNIX 0x031 EXCLAM 0x021 - public static final Key _2 = new Key("2", 3); // MS 0x03 UNIX 0x032 AT 0x040 - public static final Key _3 = new Key("3", 4); // MS 0x04 UNIX 0x033 NUMBERSIGN 0x023 - public static final Key _4 = new Key("4", 5); // MS 0x05 UNIX 0x034 DOLLAR 0x024 - public static final Key _5 = new Key("5", 6); // MS 0x06 UNIX 0x035 PERCENT 0x025 - public static final Key _6 = new Key("6", 7); // MS 0x07 UNIX 0x036 CIRCUMFLEX 0x05e - public static final Key _7 = new Key("7", 8); // MS 0x08 UNIX 0x037 AMPERSAND 0x026 - public static final Key _8 = new Key("8", 9); // MS 0x09 UNIX 0x038 ASTERISK 0x02a - public static final Key _9 = new Key("9", 10); // MS 0x0A UNIX 0x039 PARENLEFT 0x028 - public static final Key _0 = new Key("0", 11); // MS 0x0B UNIX 0x030 PARENRIGHT 0x029 - public static final Key MINUS = new Key("-", 12); // MS 0x0C UNIX 0x02d UNDERSCORE 0x05f - public static final Key EQUALS = new Key("=", 13); // MS 0x0D UNIX 0x03d PLUS 0x02b - public static final Key BACK = new Key("Back", 14); // MS 0x0E UNIX 0xFF08 - public static final Key TAB = new Key("Tab", 15); // MS 0x0F UNIX 0xFF09 - public static final Key Q = new Key("Q", 16); // MS 0x10 UNIX 0x071 UPPER 0x051 - public static final Key W = new Key("W", 17); // MS 0x11 UNIX 0x077 UPPER 0x057 - public static final Key E = new Key("E", 18); // MS 0x12 UNIX 0x065 UPPER 0x045 - public static final Key R = new Key("R", 19); // MS 0x13 UNIX 0x072 UPPER 0x052 - public static final Key T = new Key("T", 20); // MS 0x14 UNIX 0x074 UPPER 0x054 - public static final Key Y = new Key("Y", 21); // MS 0x15 UNIX 0x079 UPPER 0x059 - public static final Key U = new Key("U", 22); // MS 0x16 UNIX 0x075 UPPER 0x055 - public static final Key I = new Key("I", 23); // MS 0x17 UNIX 0x069 UPPER 0x049 - public static final Key O = new Key("O", 24); // MS 0x18 UNIX 0x06F UPPER 0x04F - public static final Key P = new Key("P", 25); // MS 0x19 UNIX 0x070 UPPER 0x050 - public static final Key LBRACKET = new Key("[", 26); // MS 0x1A UNIX 0x05b BRACE 0x07b - public static final Key RBRACKET = new Key("]", 27); // MS 0x1B UNIX 0x05d BRACE 0x07d - public static final Key RETURN = new Key("Return", 28); // MS 0x1C UNIX 0xFF0D - public static final Key LCONTROL = new Key("Left Control", 29); // MS 0x1D UNIX 0xFFE3 - public static final Key A = new Key("A", 30); // MS 0x1E UNIX 0x061 UPPER 0x041 - public static final Key S = new Key("S", 31); // MS 0x1F UNIX 0x073 UPPER 0x053 - public static final Key D = new Key("D", 32); // MS 0x20 UNIX 0x064 UPPER 0x044 - public static final Key F = new Key("F", 33); // MS 0x21 UNIX 0x066 UPPER 0x046 - public static final Key G = new Key("G", 34); // MS 0x22 UNIX 0x067 UPPER 0x047 - public static final Key H = new Key("H", 35); // MS 0x23 UNIX 0x068 UPPER 0x048 - public static final Key J = new Key("J", 36); // MS 0x24 UNIX 0x06A UPPER 0x04A - public static final Key K = new Key("K", 37); // MS 0x25 UNIX 0x06B UPPER 0x04B - public static final Key L = new Key("L", 38); // MS 0x26 UNIX 0x06C UPPER 0x04C - public static final Key SEMICOLON = new Key(";", 39); // MS 0x27 UNIX 0x03b COLON 0x03a - public static final Key APOSTROPHE = new Key("'", 40); // MS 0x28 UNIX 0x027 QUOTEDBL 0x022 - public static final Key GRAVE = new Key("~", 41); // MS 0x29 UNIX 0x060 TILDE 0x07e - public static final Key LSHIFT = new Key("Left Shift", 42); // MS 0x2A UNIX 0xFFE1 - public static final Key BACKSLASH = new Key("\\", 43); // MS 0x2B UNIX 0x05c BAR 0x07c - public static final Key Z = new Key("Z", 44); // MS 0x2C UNIX 0x07A UPPER 0x05A - public static final Key X = new Key("X", 45); // MS 0x2D UNIX 0x078 UPPER 0x058 - public static final Key C = new Key("C", 46); // MS 0x2E UNIX 0x063 UPPER 0x043 - public static final Key V = new Key("V", 47); // MS 0x2F UNIX 0x076 UPPER 0x056 - public static final Key B = new Key("B", 48); // MS 0x30 UNIX 0x062 UPPER 0x042 - public static final Key N = new Key("N", 49); // MS 0x31 UNIX 0x06E UPPER 0x04E - public static final Key M = new Key("M", 50); // MS 0x32 UNIX 0x06D UPPER 0x04D - public static final Key COMMA = new Key(",", 51); // MS 0x33 UNIX 0x02c LESS 0x03c - public static final Key PERIOD = new Key(".", 52); // MS 0x34 UNIX 0x02e GREATER 0x03e - public static final Key SLASH = new Key("/", 53); // MS 0x35 UNIX 0x02f QUESTION 0x03f - public static final Key RSHIFT = new Key("Right Shift", 54); // MS 0x36 UNIX 0xFFE2 - public static final Key MULTIPLY = new Key("Multiply", 55); // MS 0x37 UNIX 0xFFAA - public static final Key LALT = new Key("Left Alt", 56); // MS 0x38 UNIX 0xFFE9 - public static final Key SPACE = new Key(" ", 57); // MS 0x39 UNIX 0x020 - public static final Key CAPITAL = new Key("Caps Lock", 58); // MS 0x3A UNIX 0xFFE5 SHIFTLOCK 0xFFE6 - public static final Key F1 = new Key("F1", 59); // MS 0x3B UNIX 0xFFBE - public static final Key F2 = new Key("F2", 60); // MS 0x3C UNIX 0xFFBF - public static final Key F3 = new Key("F3", 61); // MS 0x3D UNIX 0xFFC0 - public static final Key F4 = new Key("F4", 62); // MS 0x3E UNIX 0xFFC1 - public static final Key F5 = new Key("F5", 63); // MS 0x3F UNIX 0xFFC2 - public static final Key F6 = new Key("F6", 64); // MS 0x40 UNIX 0xFFC3 - public static final Key F7 = new Key("F7", 65); // MS 0x41 UNIX 0xFFC4 - public static final Key F8 = new Key("F8", 66); // MS 0x42 UNIX 0xFFC5 - public static final Key F9 = new Key("F9", 67); // MS 0x43 UNIX 0xFFC6 - public static final Key F10 = new Key("F10", 68); // MS 0x44 UNIX 0xFFC7 - public static final Key NUMLOCK = new Key("Num Lock", 69); // MS 0x45 UNIX 0xFF7F - public static final Key SCROLL = new Key("Scroll Lock", 70); // MS 0x46 UNIX 0xFF14 - public static final Key NUMPAD7 = new Key("Num 7", 71); // MS 0x47 UNIX 0xFFB7 HOME 0xFF95 - public static final Key NUMPAD8 = new Key("Num 8", 72); // MS 0x48 UNIX 0xFFB8 UP 0xFF97 - public static final Key NUMPAD9 = new Key("Num 9", 73); // MS 0x49 UNIX 0xFFB9 PRIOR 0xFF9A - public static final Key SUBTRACT = new Key("Num -", 74); // MS 0x4A UNIX 0xFFAD - public static final Key NUMPAD4 = new Key("Num 4", 75); // MS 0x4B UNIX 0xFFB4 LEFT 0xFF96 - public static final Key NUMPAD5 = new Key("Num 5", 76); // MS 0x4C UNIX 0xFFB5 - public static final Key NUMPAD6 = new Key("Num 6", 77); // MS 0x4D UNIX 0xFFB6 RIGHT 0xFF98 - public static final Key ADD = new Key("Num +", 78); // MS 0x4E UNIX 0xFFAB - public static final Key NUMPAD1 = new Key("Num 1", 79); // MS 0x4F UNIX 0xFFB1 END 0xFF9C - public static final Key NUMPAD2 = new Key("Num 2", 80); // MS 0x50 UNIX 0xFFB2 DOWN 0xFF99 - public static final Key NUMPAD3 = new Key("Num 3", 81); // MS 0x51 UNIX 0xFFB3 NEXT 0xFF9B - public static final Key NUMPAD0 = new Key("Num 0", 82); // MS 0x52 UNIX 0xFFB0 INSERT 0xFF9E - public static final Key DECIMAL = new Key("Num .", 83); // MS 0x53 UNIX 0xFFAE DELETE 0xFF9F - public static final Key F11 = new Key("F11", 84); // MS 0x57 UNIX 0xFFC8 - public static final Key F12 = new Key("F12", 85); // MS 0x58 UNIX 0xFFC9 - public static final Key F13 = new Key("F13", 86); // MS 0x64 UNIX 0xFFCA - public static final Key F14 = new Key("F14", 87); // MS 0x65 UNIX 0xFFCB - public static final Key F15 = new Key("F15", 88); // MS 0x66 UNIX 0xFFCC - public static final Key KANA = new Key(89); // MS 0x70 UNIX 0xFF2D - public static final Key CONVERT = new Key(90); // MS 0x79 Japanese keyboard - public static final Key NOCONVERT = new Key(91); // MS 0x7B Japanese keyboard - public static final Key YEN = new Key(92); // MS 0x7D UNIX 0x0a5 - public static final Key NUMPADEQUAL = new Key("Num =", 93); // MS 0x8D UNIX 0xFFBD - public static final Key CIRCUMFLEX = new Key(94); // MS 0x90 Japanese keyboard - public static final Key AT = new Key(95); // MS 0x91 UNIX 0x040 - public static final Key COLON = new Key(96); // MS 0x92 UNIX 0x03a - public static final Key UNDERLINE = new Key(97); // MS 0x93 NEC PC98 - public static final Key KANJI = new Key(98); // MS 0x94 UNIX 0xFF21 - public static final Key STOP = new Key(99); // MS 0x95 UNIX 0xFF69 - public static final Key AX = new Key(100); // MS 0x96 Japan AX - public static final Key UNLABELED = new Key(101); // MS 0x97 J3100 - public static final Key NUMPADENTER = new Key("Num Enter", 102); // MS 0x9C UNIX 0xFF8D - public static final Key RCONTROL = new Key("Right Control", 103); // MS 0x9D UNIX 0xFFE4 - public static final Key NUMPADCOMMA = new Key("Num ,", 104); // MS 0xB3 UNIX 0xFFAC - public static final Key DIVIDE = new Key("Num /", 105); // MS 0xB5 UNIX 0xFFAF - public static final Key SYSRQ = new Key(106); // MS 0xB7 UNIX 0xFF15 PRINT 0xFF61 - public static final Key RALT = new Key("Right Alt", 107); // MS 0xB8 UNIX 0xFFEA - public static final Key PAUSE = new Key("Pause", 108); // MS 0xC5 UNIX 0xFF13 BREAK 0xFF6B - public static final Key HOME = new Key("Home", 109); // MS 0xC7 UNIX 0xFF50 - public static final Key UP = new Key("Up", 110); // MS 0xC8 UNIX 0xFF52 - public static final Key PAGEUP = new Key("Pg Up", 111); // MS 0xC9 UNIX 0xFF55 - public static final Key LEFT = new Key("Left", 112); // MS 0xCB UNIX 0xFF51 - public static final Key RIGHT = new Key("Right", 113); // MS 0xCD UNIX 0xFF53 - public static final Key END = new Key("End", 114); // MS 0xCF UNIX 0xFF57 - public static final Key DOWN = new Key("Down", 115); // MS 0xD0 UNIX 0xFF54 - public static final Key PAGEDOWN = new Key("Pg Down", 116); // MS 0xD1 UNIX 0xFF56 - public static final Key INSERT = new Key("Insert", 117); // MS 0xD2 UNIX 0xFF63 - public static final Key DELETE = new Key("Delete", 118); // MS 0xD3 UNIX 0xFFFF - public static final Key LWIN = new Key("Left Windows", 119); // MS 0xDB UNIX META 0xFFE7 SUPER 0xFFEB HYPER 0xFFED - public static final Key RWIN = new Key("Right Windows", 120); // MS 0xDC UNIX META 0xFFE8 SUPER 0xFFEC HYPER 0xFFEE - public static final Key APPS = new Key(121); // MS 0xDD UNIX 0xFF67 - public static final Key POWER = new Key("Power", 122); // MS 0xDE Sun 0x1005FF76 SHIFT 0x1005FF7D - public static final Key SLEEP = new Key("Sleep", 123); // MS 0xDF No UNIX keysym - public static final Key UNKNOWN = new Key("Unknown", 0); - protected static final Key FIRST = VOID; - protected static final Key LAST = SLEEP; + public static final Key VOID = new Key("Void"); // MS 0x00 UNIX 0xFFFFFF + public static final Key ESCAPE = new Key("Escape"); // MS 0x01 UNIX 0xFF1B + public static final Key _1 = new Key("1"); // MS 0x02 UNIX 0x031 EXCLAM 0x021 + public static final Key _2 = new Key("2"); // MS 0x03 UNIX 0x032 AT 0x040 + public static final Key _3 = new Key("3"); // MS 0x04 UNIX 0x033 NUMBERSIGN 0x023 + public static final Key _4 = new Key("4"); // MS 0x05 UNIX 0x034 DOLLAR 0x024 + public static final Key _5 = new Key("5"); // MS 0x06 UNIX 0x035 PERCENT 0x025 + public static final Key _6 = new Key("6"); // MS 0x07 UNIX 0x036 CIRCUMFLEX 0x05e + public static final Key _7 = new Key("7"); // MS 0x08 UNIX 0x037 AMPERSAND 0x026 + public static final Key _8 = new Key("8"); // MS 0x09 UNIX 0x038 ASTERISK 0x02a + public static final Key _9 = new Key("9"); // MS 0x0A UNIX 0x039 PARENLEFT 0x028 + public static final Key _0 = new Key("0"); // MS 0x0B UNIX 0x030 PARENRIGHT 0x029 + public static final Key MINUS = new Key("-"); // MS 0x0C UNIX 0x02d UNDERSCORE 0x05f + public static final Key EQUALS = new Key("="); // MS 0x0D UNIX 0x03d PLUS 0x02b + public static final Key BACK = new Key("Back"); // MS 0x0E UNIX 0xFF08 + public static final Key TAB = new Key("Tab"); // MS 0x0F UNIX 0xFF09 + public static final Key Q = new Key("Q"); // MS 0x10 UNIX 0x071 UPPER 0x051 + public static final Key W = new Key("W"); // MS 0x11 UNIX 0x077 UPPER 0x057 + public static final Key E = new Key("E"); // MS 0x12 UNIX 0x065 UPPER 0x045 + public static final Key R = new Key("R"); // MS 0x13 UNIX 0x072 UPPER 0x052 + public static final Key T = new Key("T"); // MS 0x14 UNIX 0x074 UPPER 0x054 + public static final Key Y = new Key("Y"); // MS 0x15 UNIX 0x079 UPPER 0x059 + public static final Key U = new Key("U"); // MS 0x16 UNIX 0x075 UPPER 0x055 + public static final Key I = new Key("I"); // MS 0x17 UNIX 0x069 UPPER 0x049 + public static final Key O = new Key("O"); // MS 0x18 UNIX 0x06F UPPER 0x04F + public static final Key P = new Key("P"); // MS 0x19 UNIX 0x070 UPPER 0x050 + public static final Key LBRACKET = new Key("["); // MS 0x1A UNIX 0x05b BRACE 0x07b + public static final Key RBRACKET = new Key("]"); // MS 0x1B UNIX 0x05d BRACE 0x07d + public static final Key RETURN = new Key("Return"); // MS 0x1C UNIX 0xFF0D + public static final Key LCONTROL = new Key("Left Control"); // MS 0x1D UNIX 0xFFE3 + public static final Key A = new Key("A"); // MS 0x1E UNIX 0x061 UPPER 0x041 + public static final Key S = new Key("S"); // MS 0x1F UNIX 0x073 UPPER 0x053 + public static final Key D = new Key("D"); // MS 0x20 UNIX 0x064 UPPER 0x044 + public static final Key F = new Key("F"); // MS 0x21 UNIX 0x066 UPPER 0x046 + public static final Key G = new Key("G"); // MS 0x22 UNIX 0x067 UPPER 0x047 + public static final Key H = new Key("H"); // MS 0x23 UNIX 0x068 UPPER 0x048 + public static final Key J = new Key("J"); // MS 0x24 UNIX 0x06A UPPER 0x04A + public static final Key K = new Key("K"); // MS 0x25 UNIX 0x06B UPPER 0x04B + public static final Key L = new Key("L"); // MS 0x26 UNIX 0x06C UPPER 0x04C + public static final Key SEMICOLON = new Key(";"); // MS 0x27 UNIX 0x03b COLON 0x03a + public static final Key APOSTROPHE = new Key("'"); // MS 0x28 UNIX 0x027 QUOTEDBL 0x022 + public static final Key GRAVE = new Key("~"); // MS 0x29 UNIX 0x060 TILDE 0x07e + public static final Key LSHIFT = new Key("Left Shift"); // MS 0x2A UNIX 0xFFE1 + public static final Key BACKSLASH = new Key("\\"); // MS 0x2B UNIX 0x05c BAR 0x07c + public static final Key Z = new Key("Z"); // MS 0x2C UNIX 0x07A UPPER 0x05A + public static final Key X = new Key("X"); // MS 0x2D UNIX 0x078 UPPER 0x058 + public static final Key C = new Key("C"); // MS 0x2E UNIX 0x063 UPPER 0x043 + public static final Key V = new Key("V"); // MS 0x2F UNIX 0x076 UPPER 0x056 + public static final Key B = new Key("B"); // MS 0x30 UNIX 0x062 UPPER 0x042 + public static final Key N = new Key("N"); // MS 0x31 UNIX 0x06E UPPER 0x04E + public static final Key M = new Key("M"); // MS 0x32 UNIX 0x06D UPPER 0x04D + public static final Key COMMA = new Key(","); // MS 0x33 UNIX 0x02c LESS 0x03c + public static final Key PERIOD = new Key("."); // MS 0x34 UNIX 0x02e GREATER 0x03e + public static final Key SLASH = new Key("/"); // MS 0x35 UNIX 0x02f QUESTION 0x03f + public static final Key RSHIFT = new Key("Right Shift"); // MS 0x36 UNIX 0xFFE2 + public static final Key MULTIPLY = new Key("Multiply"); // MS 0x37 UNIX 0xFFAA + public static final Key LALT = new Key("Left Alt"); // MS 0x38 UNIX 0xFFE9 + public static final Key SPACE = new Key(" "); // MS 0x39 UNIX 0x020 + public static final Key CAPITAL = new Key("Caps Lock"); // MS 0x3A UNIX 0xFFE5 SHIFTLOCK 0xFFE6 + public static final Key F1 = new Key("F1"); // MS 0x3B UNIX 0xFFBE + public static final Key F2 = new Key("F2"); // MS 0x3C UNIX 0xFFBF + public static final Key F3 = new Key("F3"); // MS 0x3D UNIX 0xFFC0 + public static final Key F4 = new Key("F4"); // MS 0x3E UNIX 0xFFC1 + public static final Key F5 = new Key("F5"); // MS 0x3F UNIX 0xFFC2 + public static final Key F6 = new Key("F6"); // MS 0x40 UNIX 0xFFC3 + public static final Key F7 = new Key("F7"); // MS 0x41 UNIX 0xFFC4 + public static final Key F8 = new Key("F8"); // MS 0x42 UNIX 0xFFC5 + public static final Key F9 = new Key("F9"); // MS 0x43 UNIX 0xFFC6 + public static final Key F10 = new Key("F10"); // MS 0x44 UNIX 0xFFC7 + public static final Key NUMLOCK = new Key("Num Lock"); // MS 0x45 UNIX 0xFF7F + public static final Key SCROLL = new Key("Scroll Lock"); // MS 0x46 UNIX 0xFF14 + public static final Key NUMPAD7 = new Key("Num 7"); // MS 0x47 UNIX 0xFFB7 HOME 0xFF95 + public static final Key NUMPAD8 = new Key("Num 8"); // MS 0x48 UNIX 0xFFB8 UP 0xFF97 + public static final Key NUMPAD9 = new Key("Num 9"); // MS 0x49 UNIX 0xFFB9 PRIOR 0xFF9A + public static final Key SUBTRACT = new Key("Num -"); // MS 0x4A UNIX 0xFFAD + public static final Key NUMPAD4 = new Key("Num 4"); // MS 0x4B UNIX 0xFFB4 LEFT 0xFF96 + public static final Key NUMPAD5 = new Key("Num 5"); // MS 0x4C UNIX 0xFFB5 + public static final Key NUMPAD6 = new Key("Num 6"); // MS 0x4D UNIX 0xFFB6 RIGHT 0xFF98 + public static final Key ADD = new Key("Num +"); // MS 0x4E UNIX 0xFFAB + public static final Key NUMPAD1 = new Key("Num 1"); // MS 0x4F UNIX 0xFFB1 END 0xFF9C + public static final Key NUMPAD2 = new Key("Num 2"); // MS 0x50 UNIX 0xFFB2 DOWN 0xFF99 + public static final Key NUMPAD3 = new Key("Num 3"); // MS 0x51 UNIX 0xFFB3 NEXT 0xFF9B + public static final Key NUMPAD0 = new Key("Num 0"); // MS 0x52 UNIX 0xFFB0 INSERT 0xFF9E + public static final Key DECIMAL = new Key("Num ."); // MS 0x53 UNIX 0xFFAE DELETE 0xFF9F + public static final Key F11 = new Key("F11"); // MS 0x57 UNIX 0xFFC8 + public static final Key F12 = new Key("F12"); // MS 0x58 UNIX 0xFFC9 + public static final Key F13 = new Key("F13"); // MS 0x64 UNIX 0xFFCA + public static final Key F14 = new Key("F14"); // MS 0x65 UNIX 0xFFCB + public static final Key F15 = new Key("F15"); // MS 0x66 UNIX 0xFFCC + public static final Key KANA = new Key("Kana"); // MS 0x70 UNIX 0xFF2D + public static final Key CONVERT = new Key("Convert"); // MS 0x79 Japanese keyboard + public static final Key NOCONVERT = new Key("Noconvert"); // MS 0x7B Japanese keyboard + public static final Key YEN = new Key("Yen"); // MS 0x7D UNIX 0x0a5 + public static final Key NUMPADEQUAL = new Key("Num ="); // MS 0x8D UNIX 0xFFBD + public static final Key CIRCUMFLEX = new Key("Circumflex"); // MS 0x90 Japanese keyboard + public static final Key AT = new Key("At"); // MS 0x91 UNIX 0x040 + public static final Key COLON = new Key("Colon"); // MS 0x92 UNIX 0x03a + public static final Key UNDERLINE = new Key("Underline"); // MS 0x93 NEC PC98 + public static final Key KANJI = new Key("Kanji"); // MS 0x94 UNIX 0xFF21 + public static final Key STOP = new Key("Stop"); // MS 0x95 UNIX 0xFF69 + public static final Key AX = new Key("Ax"); // MS 0x96 Japan AX + public static final Key UNLABELED = new Key("Unlabeled"); // MS 0x97 J3100 + public static final Key NUMPADENTER = new Key("Num Enter"); // MS 0x9C UNIX 0xFF8D + public static final Key RCONTROL = new Key("Right Control"); // MS 0x9D UNIX 0xFFE4 + public static final Key NUMPADCOMMA = new Key("Num ,"); // MS 0xB3 UNIX 0xFFAC + public static final Key DIVIDE = new Key("Num /"); // MS 0xB5 UNIX 0xFFAF + public static final Key SYSRQ = new Key("SysRq"); // MS 0xB7 UNIX 0xFF15 PRINT 0xFF61 + public static final Key RALT = new Key("Right Alt"); // MS 0xB8 UNIX 0xFFEA + public static final Key PAUSE = new Key("Pause"); // MS 0xC5 UNIX 0xFF13 BREAK 0xFF6B + public static final Key HOME = new Key("Home"); // MS 0xC7 UNIX 0xFF50 + public static final Key UP = new Key("Up"); // MS 0xC8 UNIX 0xFF52 + public static final Key PAGEUP = new Key("Pg Up"); // MS 0xC9 UNIX 0xFF55 + public static final Key LEFT = new Key("Left"); // MS 0xCB UNIX 0xFF51 + public static final Key RIGHT = new Key("Right"); // MS 0xCD UNIX 0xFF53 + public static final Key END = new Key("End"); // MS 0xCF UNIX 0xFF57 + public static final Key DOWN = new Key("Down"); // MS 0xD0 UNIX 0xFF54 + public static final Key PAGEDOWN = new Key("Pg Down"); // MS 0xD1 UNIX 0xFF56 + public static final Key INSERT = new Key("Insert"); // MS 0xD2 UNIX 0xFF63 + public static final Key DELETE = new Key("Delete"); // MS 0xD3 UNIX 0xFFFF + public static final Key LWIN = new Key("Left Windows"); // MS 0xDB UNIX META 0xFFE7 SUPER 0xFFEB HYPER 0xFFED + public static final Key RWIN = new Key("Right Windows"); // MS 0xDC UNIX META 0xFFE8 SUPER 0xFFEC HYPER 0xFFEE + public static final Key APPS = new Key("Apps"); // MS 0xDD UNIX 0xFF67 + public static final Key POWER = new Key("Power"); // MS 0xDE Sun 0x1005FF76 SHIFT 0x1005FF7D + public static final Key SLEEP = new Key("Sleep"); // MS 0xDF No UNIX keysym + public static final Key UNKNOWN = new Key("Unknown"); } // class StandardKeyboard.KeyID } // class Axis.Identifier diff --git a/coreAPI/src/java/net/java/games/input/Controller.java b/coreAPI/src/java/net/java/games/input/Controller.java index fc22cdd..61faaff 100644 --- a/coreAPI/src/java/net/java/games/input/Controller.java +++ b/coreAPI/src/java/net/java/games/input/Controller.java @@ -90,6 +90,17 @@ public interface Controller { public abstract boolean poll(); /** + * Initialized the controller event queue to a new size. Existing events + * in the queue are lost. + */ + public abstract void setEventQueueSize(int size); + + /** + * Get the device event queue + */ + public abstract EventQueue getEventQueue(); + + /** * Returns the port type for this Controller. */ public abstract PortType getPortType(); @@ -129,76 +140,65 @@ public interface Controller { } /** - * Mouse controller. + * Unkown controller type. */ - public static final Type UNKNOWN = new Type("unknown"); + public static final Type UNKNOWN = new Type("Unknown"); /** * Mouse controller. */ - public static final Type MOUSE = new Type("mouse"); + public static final Type MOUSE = new Type("Mouse"); /** - * A mouse ball or the ball part of a trackball controller. - * Note that a mouse wheel is considered part of a ball controller. - */ - public static final Type BALL = new Type("ball"); - - /** - * A group of buttons on a pad (mouse buttons, for - * example) or a keyboard. - */ - public static final Type BUTTONS = new Type("buttons"); - /** * A keyboard controller (same as BUTTONS) * @see #BUTTONS */ - public static final Type KEYBOARD = BUTTONS; + public static final Type KEYBOARD = new Type("Keyboard"); /** * Fingerstick controller; note that this may be sometimes treated as a * type of mouse or stick. */ - public static final Type FINGERSTICK = new Type("fingerstick"); + public static final Type FINGERSTICK = new Type("Fingerstick"); /** * Gamepad controller. */ - public static final Type GAMEPAD = new Type("gamepad"); + public static final Type GAMEPAD = new Type("Gamepad"); /** * Headtracker controller. */ - public static final Type HEADTRACKER = new Type("headtracker"); + public static final Type HEADTRACKER = new Type("Headtracker"); /** * Rudder controller. */ - public static final Type RUDDER = new Type("rudder"); + public static final Type RUDDER = new Type("Rudder"); /** * Stick controller, such as a joystick or flightstick. */ - public static final Type STICK = new Type("stick"); + public static final Type STICK = new Type("Stick"); /** * A trackball controller; note that this may sometimes be treated as a * type of mouse. */ - public static final Type TRACKBALL = new Type("trackball"); + public static final Type TRACKBALL = new Type("Trackball"); /** * A trackpad, such as a tablet, touchpad, or glidepad; * note that this may sometimes be treated as a type of mouse. */ - public static final Type TRACKPAD = new Type("trackpad"); + public static final Type TRACKPAD = new Type("Trackpad"); /** * A wheel controller, such as a steering wheel (note - * that a mouse wheel is considered part of a ball control, not a + * that a mouse wheel is considered part of a mouse, not a * wheel controller). */ - public static final Type WHEEL = new Type("wheel"); + public static final Type WHEEL = new Type("Wheel"); } // class Controller.Type /** diff --git a/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java b/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java index e68dde3..c7a4a42 100644 --- a/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java +++ b/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java @@ -66,7 +66,14 @@ import java.util.Iterator; * */ public abstract class ControllerEnvironment { - + static void logln(String msg) { + log(msg + "\n"); + } + + static void log(String msg) { + System.out.print(msg); + } + /** * The default controller environment */ diff --git a/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java b/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java index e94b769..3ce2b2e 100644 --- a/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java +++ b/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java @@ -123,35 +123,35 @@ class DefaultControllerEnvironment extends ControllerEnvironment { pluginClasses = pluginClasses + " net.java.games.input.OSXEnvironmentPlugin"; } else if(osName.equals("Windows 98") || osName.equals("Windows 2000") || osName.equals("Windows XP")) { pluginClasses = pluginClasses + " net.java.games.input.DirectInputEnvironmentPlugin"; - } else if(osName.startsWith("Windows")) { + pluginClasses = pluginClasses + " net.java.games.input.RawInputEnvironmentPlugin"; + } else if (osName.startsWith("Windows")) { System.out.println("WARNING: Found unknown Windows version: " + osName); System.out.println("Attempting to use default windows plug-in."); System.out.flush(); pluginClasses = pluginClasses + " net.java.games.input.DirectInputEnvironmentPlugin"; + pluginClasses = pluginClasses + " net.java.games.input.RawInputEnvironmentPlugin"; } else { System.out.println("Trying to use default plugin, OS name " + osName +" not recognised"); } } - if(!pluginClasses.equals("")) { - ArrayList pluginClassList = new ArrayList(); - StringTokenizer pluginClassTok = new StringTokenizer(pluginClasses, " \t\n\r\f,;:"); - while(pluginClassTok.hasMoreTokens()) { - String className = pluginClassTok.nextToken(); - try { - if(!loadedPlugins.contains(className)) { - Class ceClass = Class.forName(className); - ControllerEnvironment ce = (ControllerEnvironment) ceClass.newInstance(); - addControllers(ce.getControllers()); - } - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - } - } + ArrayList pluginClassList = new ArrayList(); + StringTokenizer pluginClassTok = new StringTokenizer(pluginClasses, " \t\n\r\f,;:"); + while(pluginClassTok.hasMoreTokens()) { + String className = pluginClassTok.nextToken(); + try { + if(!loadedPlugins.contains(className)) { + Class ceClass = Class.forName(className); + ControllerEnvironment ce = (ControllerEnvironment) ceClass.newInstance(); + addControllers(ce.getControllers()); + } + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } } Controller[] ret = new Controller[controllers.size()]; Iterator it = controllers.iterator(); @@ -232,7 +232,7 @@ class DefaultControllerEnvironment extends ControllerEnvironment { envClasses[i].newInstance(); addControllers(ce.getControllers()); loadedPlugins.add(ce.getClass().getName()); - } catch (Exception e) { + } catch (Throwable e) { e.printStackTrace(); } } diff --git a/coreAPI/src/java/net/java/games/input/Event.java b/coreAPI/src/java/net/java/games/input/Event.java new file mode 100644 index 0000000..c6bc5e9 --- /dev/null +++ b/coreAPI/src/java/net/java/games/input/Event.java @@ -0,0 +1,76 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +public final class Event { + private Component component; + private float value; + private long nanos; + + public final void set(Event other) { + this.set(other.getComponent(), other.getValue(), other.getNanos()); + } + + public final void set(Component component, float value, long nanos) { + this.component = component; + this.value = value; + this.nanos = nanos; + } + + public final Component getComponent() { + return component; + } + + public final float getValue() { + return value; + } + + /** + * Return the time the event happened, in nanoseconds. + * The time is relative and therefore can only be used + * to compare with other event times. + */ + public final long getNanos() { + return nanos; + } + + public final String toString() { + return "Event: component = " + component + " | value = " + value; + } +} diff --git a/coreAPI/src/java/net/java/games/input/EventQueue.java b/coreAPI/src/java/net/java/games/input/EventQueue.java new file mode 100644 index 0000000..960ed40 --- /dev/null +++ b/coreAPI/src/java/net/java/games/input/EventQueue.java @@ -0,0 +1,73 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +public final class EventQueue { + private final Event[] queue; + + private int head; + private int tail; + + public EventQueue(int size) { + queue = new Event[size + 1]; + for (int i = 0; i < queue.length; i++) + queue[i] = new Event(); + } + + final synchronized void add(Event event) { + queue[tail].set(event); + tail = increase(tail); + } + + final synchronized boolean isFull() { + return increase(tail) == head; + } + + private final int increase(int x) { + return (x + 1)%queue.length; + } + + public final synchronized boolean getNextEvent(Event event) { + if (head == tail) + return false; + event.set(queue[head]); + head = increase(head); + return true; + } +} diff --git a/coreAPI/src/java/net/java/games/input/Keyboard.java b/coreAPI/src/java/net/java/games/input/Keyboard.java index f01317d..e168869 100644 --- a/coreAPI/src/java/net/java/games/input/Keyboard.java +++ b/coreAPI/src/java/net/java/games/input/Keyboard.java @@ -44,14 +44,13 @@ package net.java.games.input; * are set to receive polling data. */ public abstract class Keyboard extends AbstractController { - /** * Protected constructor. * Subclasses should initialize the array of axes to an array of keys. * @param name The name of the keyboard */ - protected Keyboard(String name) { - super(name); + protected Keyboard(String name, Component[] keys, Controller[] children, Rumbler[] rumblers) { + super(name, keys, children, rumblers); } /** @@ -61,67 +60,10 @@ public abstract class Keyboard extends AbstractController { return Type.KEYBOARD; } - /** - * Returns the component corresponding to a particular key on the keypad, - * or null if a key with the specified ID could not be found. - */ - public Component getComponent(Component.Identifier id) { - assert components != null; - // Default implementation uses indices to lookup keys - // in the array of axes - if(id instanceof Component.Identifier.Key) { - int index = ((Component.Identifier.Key)id).getKeyIndex(); - assert components.length > index; - return components[index]; - } - return null; - } - - /** - * Returns whether or not the given key has been pressed since the last - * call to poll. This is called from a key's getPollData method. - */ - protected abstract boolean isKeyPressed(Key key); - - /** - * Axis representing a single key. By default, all keys are set to receive - * polling data. - */ - public class Key extends AbstractComponent { - - /** - * Key identifier - */ - private final Component.Identifier.Key keyID; - - /** - * Construct a new key object - */ - public Key(Component.Identifier.Key keyID) { - super(keyID.toString(), keyID); - this.keyID = keyID; - } - - /** - * Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return false by default, can be overridden - */ - public final boolean isRelative() { - return false; - } - - /** - * Returns the data from the last time the control has been polled. - * The value returned will be either 0.0f or 1.0f. The result is always - * 0.0f if polling is turned off. - */ - public float getPollData() { - if (!isPolling()) { - return 0.0f; - } - return (isKeyPressed(this) ? 1.0f : 0.0f); - } - } // class Keyboard.Key + public final boolean isKeyDown(Component.Identifier.Key key_id) { + Component key = getComponent(key_id); + if (key == null) + return false; + return key.getPollData() != 0; + } } // class Keyboard diff --git a/coreAPI/src/java/net/java/games/input/Mouse.java b/coreAPI/src/java/net/java/games/input/Mouse.java index 790a6a4..83676a4 100644 --- a/coreAPI/src/java/net/java/games/input/Mouse.java +++ b/coreAPI/src/java/net/java/games/input/Mouse.java @@ -38,56 +38,17 @@ *****************************************************************************/ package net.java.games.input; +import java.util.List; +import java.util.ArrayList; + /** * A Mouse is a type of controller consisting of two child controllers, * a ball and a button pad. This includes devices such as touch pads, * trackballs, and fingersticks. */ public abstract class Mouse extends AbstractController { - - /** - * Mouse ball; should be initialized by subclasses - */ - protected Ball ball; - - /** - * Mouse buttons; should be initialized by subclasses - */ - protected Buttons buttons; - - /** - * Protected constructor; - * Subclasses should initialize the ball and buttons - */ - protected Mouse(String name) { - super(name); - } - - /** - * Returns the controllers connected to make up this controller, or - * an empty array if this controller contains no child controllers. - * The objects in the array are returned in order of assignment priority - * (primary stick, secondary buttons, etc.). - */ - public Controller[] getControllers() { - if (children.length == 0 && ball != null && buttons != null) { - children = new Controller[] { ball, buttons }; - } - return children; - } - - /** - * Returns the control for the ball of the mouse, never null. - */ - public Ball getBall() { - return ball; - } - - /** - * Returns the control for the buttons of the mouse, never null. - */ - public Buttons getButtons() { - return buttons; + protected Mouse(String name, Component[] components, Controller[] children, Rumbler[] rumblers) { + super(name, components, children, rumblers); } /** @@ -97,249 +58,79 @@ public abstract class Mouse extends AbstractController { return Type.MOUSE; } - /** - * Mouse ball controller - */ - public abstract class Ball extends AbstractController { - - /** - * X-axis; should be initialized by subclasses - */ - protected Component x; - - /** - * Y-axis; should be initialized by subclasses - */ - protected Component y; - - /** - * Mouse wheel; should be initialized by subclasses - */ - protected Component wheel; - - /** - * Protected constructor - */ - protected Ball(String name) { - super(name); - } - - /** - * Returns the type of Controller. - */ - public Type getType() { - return Type.BALL; - } - - /** - * Returns the x-axis for the mouse ball, never null. - */ - public Component getX() { - return x; - } - - /** - * Returns the y-axis for the mouse ball, never null. - */ - public Component getY() { - return y; - } - - /** - * Returns the mouse wheel, or null if no mouse wheel is present. - */ - public Component getWheel() { - return wheel; - } - - /** - * Returns the components on this controller, in order of assignment priority. - * Overridden to return the x-axis, followed by the y-axes, followed by - * the wheel (if present). - * The array returned is an empty array if this controller contains no - * axes (such as a logical grouping of child controllers). - */ - public Component[] getComponents() { - if (components.length == 0 && x != null && y != null) { - if (wheel == null) { - components = new Component[] { x, y }; - } else { - components = new Component[] { x, y, wheel }; - } - } - return components; - } + /** + * Returns the x-axis for the mouse ball, never null. + */ + public Component getX() { + return getComponent(Component.Identifier.Axis.X); + } - /** - * Polls axes for data. Returns false if the controller is no longer - * valid. Polling reflects the current state of the device when polled. - * By default, polling a mouse ball or button polls the entire mouse - * control. - */ - public boolean poll() { - return Mouse.this.poll(); - } - } // class Mouse.Ball - - /** - * Mouse buttons controller - */ - public abstract class Buttons extends AbstractController { - - /** - * Left button; should be initialized by subclasses - */ - protected Button left; - - /** - * Right button; should be initialized by subclasses - */ - protected Button right; - - /** - * Middle button; should be initialized by subclasses - */ - protected Button middle; - - /** - * Side button; should be initialized by subclasses - */ - protected Button side; - - /** - * Extra button; should be initialized by subclasses - */ - protected Button extra; - - /** - * Forward button; should be initialized by subclasses - */ - protected Button forward; - - /** - * Back button; should be initialized by subclasses - */ - protected Button back; - - /** - * Protected constructor - */ - protected Buttons(String name) { - super(name); - } - - /** - * Returns the type or identifier of the Controller. - */ - public Type getType() { - return Type.BUTTONS; - } - - /** - * Returns the left or primary mouse button, never null. - */ - public Button getLeft() { - return left; - } - - /** - * Returns the right or secondary mouse button, null if the mouse is - * a single-button mouse. - */ - public Button getRight() { - return right; - } - - /** - * Returns the middle or tertiary mouse button, null if the mouse has - * fewer than three buttons. - */ - public Button getMiddle() { - return middle; - } - - /** - * Returns the side or 4th mouse button, null if the mouse has - * fewer than 4 buttons. - */ - public Button getSide() { - return side; - } - - /** - * Returns the extra or 5th mouse button, null if the mouse has - * fewer than 5 buttons. - */ - public Button getExtra() { - return extra; - } - - /** - * Returns the forward mouse button, null if the mouse hasn't - * got one. - */ - public Button getForward() { - return forward; - } - - /** - * Returns the back mouse button, null if the mouse hasn't - * got one. - */ - public Button getBack() { - return back; - } - - /** - * Returns the components on this controller, in order of assignment priority. - * Overridden to return the the primary or leftmost mouse button, - * followed by the secondary or rightmost mouse button (if present), - * followed by the middle mouse button (if present). - * The array returned is an empty array if this controller contains no - * axes (such as a logical grouping of child controllers). - */ - public Component[] getComponents() { - if (components.length == 0 && left != null) { - if (right == null) { - components = new Component[] { left }; - } else if (middle == null) { - components = new Component[] { left, right }; - } else if (side == null) { - components = new Component[] { left, right, middle }; - } else if (extra == null) { - components = new Component[] { left, right, middle, side }; - } else if (forward == null) { - components = new Component[] { left, right, middle, side, extra }; - } else if (back == null) { - components = new Component[] { left, right, middle, side, extra, forward }; - } else { - components = new Component[] { left, right, middle, side, extra, forward, back }; - } - } - return components; - } + /** + * Returns the y-axis for the mouse ball, never null. + */ + public Component getY() { + return getComponent(Component.Identifier.Axis.Y); + } - /** - * Polls axes for data. Returns false if the controller is no longer - * valid. Polling reflects the current state of the device when polled. - * By default, polling a mouse ball or button polls the entire mouse - * control. - */ - public boolean poll() { - return Mouse.this.poll(); - } - } // class Mouse.Buttons - - /** - * Mouse button axis - */ - public abstract class Button extends AbstractComponent { - - /** - * Protected constructor - */ - protected Button(String name, Component.Identifier.Button id) { - super(name, id); - } - } // class Mouse.Button + /** + * Returns the mouse wheel, or null if no mouse wheel is present. + */ + public Component getWheel() { + return getComponent(Component.Identifier.Axis.Z); + } + + /** + * Returns the left or primary mouse button, never null. + */ + public Component getLeft() { + return getComponent(Component.Identifier.Button.LEFT); + } + + /** + * Returns the right or secondary mouse button, null if the mouse is + * a single-button mouse. + */ + public Component getRight() { + return getComponent(Component.Identifier.Button.RIGHT); + } + + /** + * Returns the middle or tertiary mouse button, null if the mouse has + * fewer than three buttons. + */ + public Component getMiddle() { + return getComponent(Component.Identifier.Button.MIDDLE); + } + + /** + * Returns the side or 4th mouse button, null if the mouse has + * fewer than 4 buttons. + */ + public Component getSide() { + return getComponent(Component.Identifier.Button.SIDE); + } + + /** + * Returns the extra or 5th mouse button, null if the mouse has + * fewer than 5 buttons. + */ + public Component getExtra() { + return getComponent(Component.Identifier.Button.EXTRA); + } + + /** + * Returns the forward mouse button, null if the mouse hasn't + * got one. + */ + public Component getForward() { + return getComponent(Component.Identifier.Button.FORWARD); + } + + /** + * Returns the back mouse button, null if the mouse hasn't + * got one. + */ + public Component getBack() { + return getComponent(Component.Identifier.Button.BACK); + } } // class Mouse diff --git a/coreAPI/src/java/net/java/games/input/StandardKeyboard.java b/coreAPI/src/java/net/java/games/input/StandardKeyboard.java deleted file mode 100644 index e25ef9b..0000000 --- a/coreAPI/src/java/net/java/games/input/StandardKeyboard.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistribution of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materails provided with the distribution. - * - * Neither the name Sun Microsystems, Inc. or the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND - * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS - * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for us in - * the design, construction, operation or maintenance of any nuclear facility - * - *****************************************************************************/ -package net.java.games.input; - -/** - * Identifiers for physical keys for standard PC (LATIN-1) keyboards. - */ -public abstract class StandardKeyboard extends Keyboard { - - private Key[] standardKeys = { - new Key(Component.Identifier.Key.VOID ), new Key(Component.Identifier.Key.ESCAPE ), - new Key(Component.Identifier.Key._1 ), new Key(Component.Identifier.Key._2 ), - new Key(Component.Identifier.Key._3 ), new Key(Component.Identifier.Key._4 ), - new Key(Component.Identifier.Key._5 ), new Key(Component.Identifier.Key._6 ), - new Key(Component.Identifier.Key._7 ), new Key(Component.Identifier.Key._8 ), - new Key(Component.Identifier.Key._9 ), new Key(Component.Identifier.Key._0 ), - new Key(Component.Identifier.Key.MINUS ), new Key(Component.Identifier.Key.EQUALS ), - new Key(Component.Identifier.Key.BACK ), new Key(Component.Identifier.Key.TAB ), - new Key(Component.Identifier.Key.Q ), new Key(Component.Identifier.Key.W ), - new Key(Component.Identifier.Key.E ), new Key(Component.Identifier.Key.R ), - new Key(Component.Identifier.Key.T ), new Key(Component.Identifier.Key.Y ), - new Key(Component.Identifier.Key.U ), new Key(Component.Identifier.Key.I ), - new Key(Component.Identifier.Key.O ), new Key(Component.Identifier.Key.P ), - new Key(Component.Identifier.Key.LBRACKET ), new Key(Component.Identifier.Key.RBRACKET ), - new Key(Component.Identifier.Key.RETURN ), new Key(Component.Identifier.Key.LCONTROL ), - new Key(Component.Identifier.Key.A ), new Key(Component.Identifier.Key.S ), - new Key(Component.Identifier.Key.D ), new Key(Component.Identifier.Key.F ), - new Key(Component.Identifier.Key.G ), new Key(Component.Identifier.Key.H ), - new Key(Component.Identifier.Key.J ), new Key(Component.Identifier.Key.K ), - new Key(Component.Identifier.Key.L ), new Key(Component.Identifier.Key.SEMICOLON ), - new Key(Component.Identifier.Key.APOSTROPHE ), new Key(Component.Identifier.Key.GRAVE ), - new Key(Component.Identifier.Key.LSHIFT ), new Key(Component.Identifier.Key.BACKSLASH ), - new Key(Component.Identifier.Key.Z ), new Key(Component.Identifier.Key.X ), - new Key(Component.Identifier.Key.C ), new Key(Component.Identifier.Key.V ), - new Key(Component.Identifier.Key.B ), new Key(Component.Identifier.Key.N ), - new Key(Component.Identifier.Key.M ), new Key(Component.Identifier.Key.COMMA ), - new Key(Component.Identifier.Key.PERIOD ), new Key(Component.Identifier.Key.SLASH ), - new Key(Component.Identifier.Key.RSHIFT ), new Key(Component.Identifier.Key.MULTIPLY ), - new Key(Component.Identifier.Key.LALT ), new Key(Component.Identifier.Key.SPACE ), - new Key(Component.Identifier.Key.CAPITAL ), new Key(Component.Identifier.Key.F1 ), - new Key(Component.Identifier.Key.F2 ), new Key(Component.Identifier.Key.F3 ), - new Key(Component.Identifier.Key.F4 ), new Key(Component.Identifier.Key.F5 ), - new Key(Component.Identifier.Key.F6 ), new Key(Component.Identifier.Key.F7 ), - new Key(Component.Identifier.Key.F8 ), new Key(Component.Identifier.Key.F9 ), - new Key(Component.Identifier.Key.F10 ), new Key(Component.Identifier.Key.NUMLOCK ), - new Key(Component.Identifier.Key.SCROLL ), new Key(Component.Identifier.Key.NUMPAD7 ), - new Key(Component.Identifier.Key.NUMPAD8 ), new Key(Component.Identifier.Key.NUMPAD9 ), - new Key(Component.Identifier.Key.SUBTRACT ), new Key(Component.Identifier.Key.NUMPAD4 ), - new Key(Component.Identifier.Key.NUMPAD5 ), new Key(Component.Identifier.Key.NUMPAD6 ), - new Key(Component.Identifier.Key.ADD ), new Key(Component.Identifier.Key.NUMPAD1 ), - new Key(Component.Identifier.Key.NUMPAD2 ), new Key(Component.Identifier.Key.NUMPAD3 ), - new Key(Component.Identifier.Key.NUMPAD0 ), new Key(Component.Identifier.Key.DECIMAL ), - new Key(Component.Identifier.Key.F11 ), new Key(Component.Identifier.Key.F12 ), - new Key(Component.Identifier.Key.F13 ), new Key(Component.Identifier.Key.F14 ), - new Key(Component.Identifier.Key.F15 ), new Key(Component.Identifier.Key.KANA ), - new Key(Component.Identifier.Key.CONVERT ), new Key(Component.Identifier.Key.NOCONVERT ), - new Key(Component.Identifier.Key.YEN ), new Key(Component.Identifier.Key.NUMPADEQUAL), - new Key(Component.Identifier.Key.CIRCUMFLEX ), new Key(Component.Identifier.Key.AT ), - new Key(Component.Identifier.Key.COLON ), new Key(Component.Identifier.Key.UNDERLINE ), - new Key(Component.Identifier.Key.KANJI ), new Key(Component.Identifier.Key.STOP ), - new Key(Component.Identifier.Key.AX ), new Key(Component.Identifier.Key.UNLABELED ), - new Key(Component.Identifier.Key.NUMPADENTER), new Key(Component.Identifier.Key.RCONTROL ), - new Key(Component.Identifier.Key.NUMPADCOMMA), new Key(Component.Identifier.Key.DIVIDE ), - new Key(Component.Identifier.Key.SYSRQ ), new Key(Component.Identifier.Key.RALT ), - new Key(Component.Identifier.Key.PAUSE ), new Key(Component.Identifier.Key.HOME ), - new Key(Component.Identifier.Key.UP ), new Key(Component.Identifier.Key.PAGEUP ), - new Key(Component.Identifier.Key.LEFT ), new Key(Component.Identifier.Key.RIGHT ), - new Key(Component.Identifier.Key.END ), new Key(Component.Identifier.Key.DOWN ), - new Key(Component.Identifier.Key.PAGEDOWN ), new Key(Component.Identifier.Key.INSERT ), - new Key(Component.Identifier.Key.DELETE ), new Key(Component.Identifier.Key.LWIN ), - new Key(Component.Identifier.Key.RWIN ), new Key(Component.Identifier.Key.APPS ), - new Key(Component.Identifier.Key.POWER ), new Key(Component.Identifier.Key.SLEEP ), - }; - - /** - * Creates a new standard keyboard object with the default keys - * for a standard keyboard. - */ - protected StandardKeyboard(String name) { - super(name); - components = standardKeys; - } -} // class StandardKeyboard diff --git a/coreAPI/src/java/net/java/games/input/Version.java b/coreAPI/src/java/net/java/games/input/Version.java index 143f100..582e66a 100644 --- a/coreAPI/src/java/net/java/games/input/Version.java +++ b/coreAPI/src/java/net/java/games/input/Version.java @@ -89,7 +89,7 @@ public final class Version { /** * Version string of this build. */ - private static final String version = "1.0.0-b01"; + private static final String version = "2.0.0-b01"; /** * Returns the verison string and build number of diff --git a/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java b/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java index 0a41d54..a7c0e84 100644 --- a/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java +++ b/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java @@ -74,6 +74,10 @@ abstract class AxisPanel extends JPanel{ data = axis.getPollData(); renderData(); } + + public Component getAxis() { + return axis; + } protected abstract void renderData(); } @@ -153,7 +157,10 @@ class AnalogAxisPanel extends AxisPanel { } protected void renderData(){ - analogState.setText(""+data); + String extra = ""; + if (getAxis().getDeadZone() >= Math.abs(data)) + extra = " (DEADZONE)"; + analogState.setText(""+data+extra); analogState.repaint(); } } @@ -216,7 +223,7 @@ class ControllerWindow extends JFrame { } p.add(p2); axisList.add(p2); - ax.setPolling(true); + //ax.setPolling(true); } public void poll(){ diff --git a/plugins/DX8/build.xml b/plugins/DX8/build.xml deleted file mode 100644 index 30865f3..0000000 --- a/plugins/DX8/build.xml +++ /dev/null @@ -1,103 +0,0 @@ -<?xml version="1.0"?> - -<!-- Written to assume that classpath is rooted in the current directory. --> -<!-- So this should be OK if you make this script in the root of a filesystem. --> -<!-- If not, you may prefer to adjust the basedir, or move some directories around. --> -<!-- The idea is that both Ant and NetBeans have to know what the package root is --> -<!-- for the classes in your application. --> -<project name="Direct Input Plugin" basedir="." default="all"> - - <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! --> - <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. --> - - <target name="init"> - <!-- You can set up any variables you want used throughout the script here. --> - <property name="hello" value="world"/> - <mkdir dir="classes"/> - <mkdir dir="bin"/> - <!-- To use e.g. Jikes, uncomment this line. --> - <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) --> - <!-- <property name="build.compiler" value="jikes"/> --> - <!-- You might like to set up some overridable paths, etc.: --> - <!-- <property name="mylib" value="../lib/mylib.jar"/> --> - </target> - - <target name="compile" depends="init"> - <!-- Both srcdir and destdir should be package roots. --> - <!-- They could be different of course; in that case NetBeans can also be set --> - <!-- up to compile to a different filesystem in the same way; see Compiler Types: --> - <javac srcdir="src/java" destdir="classes" debug="true" deprecation="true" source="1.4" target="1.4"> - <!-- To add something to the classpath: --> - <classpath> - <pathelement location="lib/jinput.jar"/> - <pathelement location="lib/jutils.jar"/> - </classpath> - <!-- To exclude some files: --> - <!-- - <exclude name="com/foo/SomeFile.java"/> - <exclude name="com/foo/somepackage/"/> - --> - </javac> - <exec dir="." executable="g++" os="Windows 2000, Windows XP, Windows 98"> - <arg line=" -D_STRICT_ANSI -D_JNI_IMPLEMENTATION_"/> - <arg line=" -I'${java.home}/../include' -I'${java.home}/../include/win32' -Ic:/dx9/include"/> - <arg line=" -o bin/jinput-dxplugin.dll src/native/input.cpp -Wl,--export-all-symbols"/> - <arg line=" -shared -Wl,--kill-at -ldxguid -ldinput -ldinput8"/> - </exec> - <copy file="bin/jinput-dxplugin.dll" todir="../../coreAPI/src/tests/controller" /> - </target> - - <target name="jar" depends="init,compile"> - <!-- To make a standalone app: --> - <!-- 1. Create a myapp.mf manifest somewhere. --> - <!-- 2. Put in it: --> - <!-- Manifest-Version: 1.0 --> - <!-- Main-Class: com.foo.Main --> - <!-- 3. Pass to <jar>: manifest="myapp.mf" --> - <jar jarfile="bin/dxinput.jar" compress="true" basedir="classes"> - <exclude name="**/*.java"/> - <exclude name="**/*.form"/> - <exclude name="dxinput.mf"/> - <exclude name="dxinput.jar"/> - <exclude name="apidoc"/> - </jar> - <copy file="bin/dxinput.jar" todir="../../coreAPI/src/tests/controller" /> - </target> - - <target name="all" depends="compile,jar" description="Build everything."> - <echo message="Application built. Hello ${hello}!"/> - </target> - - <target name="test" depends="init,all" description="Try running it."> - <echo message="Test by running test on the build.xml for input"/> - </target> - - <target name="javadoc" depends="init" description="Javadoc for my API."> - <mkdir dir="apidocs"/> - <javadoc packagenames="net.*" - destdir="apidocs" - additionalparam="-source 1.4"> - <sourcepath> - <pathelement location="src/java"/> - </sourcepath> - <classpath> - <pathelement location="lib/jinput.jar"/> - <pathelement location="lib/jutils.jar"/> - </classpath> - </javadoc> - </target> - - <target name="clean" depends="init" description="Clean all build products."> - <delete> - <fileset dir="classes"> - <include name="**/*.class"/> - </fileset> - </delete> - <delete file="bin/dxinput.jar" failonerror="no"/> - <delete file="bin/jinput-dxplugin.dll" failonerror="no"/> - <delete file="../../coreAPI/src/tests/controller/dxinput.jar" failonerror="no" /> - <delete file="../../coreAPI/src/tests/controller/jinput-dxplugin.dll" failonerror="no"/> - <delete dir="../../docs/input/win32/apidoc" failonerror="no"/> - </target> - -</project> diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java b/plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java deleted file mode 100644 index 1312769..0000000 --- a/plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistribution of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materails provided with the distribution. - * - * Neither the name Sun Microsystems, Inc. or the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND - * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS - * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for us in - * the design, construction, operation or maintenance of any nuclear facility - * - *****************************************************************************/ -package net.java.games.input; - -import net.java.games.input.AbstractComponent; -import net.java.games.input.Component; - -/** - * - * @author martak - * @version - */ -class DirectInputAxis extends AbstractComponent { - - /** - * DIDFT_ constants and macros defined in dinput.h - */ - private static final int DIDFT_ALL = 0x00000000; - private static final int DIDFT_RELAXIS = 0x00000001; - private static final int DIDFT_ABSAXIS = 0x00000002; - private static final int DIDFT_AXIS = 0x00000003; - private static final int DIDFT_PSHBUTTON = 0x00000004; - private static final int DIDFT_TGLBUTTON = 0x00000008; - private static final int DIDFT_BUTTON = 0x0000000C; - private static final int DIDFT_POV = 0x00000010; - private static final int DIDFT_COLLECTION = 0x00000040; - private static final int DIDFT_NODATA = 0x00000080; - private static final int DIDFT_ANYINSTANCE = 0x00FFFF00; - private static final int DIDFT_INSTANCEMASK = DIDFT_ANYINSTANCE; - private static final int DIDFT_FFACTUATOR = 0x01000000; - private static final int DIDFT_FFEFFECTTRIGGER = 0x02000000; - private static final int DIDFT_OUTPUT = 0x10000000; - private static final int DIDFT_NOCOLLECTION = 0x00FFFF00; - private static int DIDFT_MAKEINSTANCE(int n) { - return ((n&0xffff) << 8); - } - private static int DIDFT_GETTYPE(int n) { - return (n&0xFF); - } - private static int DIDFT_GETINSTANCE(int n) { - return ((n >> 8)&0xffff); - } - private static int DIDFT_ENUMCOLLECTION(int n) { - return ((n&0xFFFF) << 8); - } - - private DirectInputDevice device; - /** - * DIJOYSTATE structure defined in dinput.h: - * - * <pre> - * typedef struct DIJOYSTATE { - * LONG lX; - * LONG lY; - * LONG lZ; - * LONG lRx; - * LONG lRy; - * LONG lRz; - * LONG rglSlider[2]; - * DWORD rgdwPOV[4]; - * BYTE rgbButtons[32]; - * } DIJOYSTATE, *LPDIJOYSTATE; - * - * 80 bytes total - * </pre> - */ - private int offset; - private int type; - private int instance; - private int bitmask = 0xffffffff; - private int bitshift = 0; - - private DirectInputAxis(DirectInputDevice device, Component.Identifier id, - int didft, String name) { - super(name, id); - this.device = device; - this.type = DIDFT_GETTYPE(didft); - this.instance = DIDFT_GETINSTANCE(didft); - if (id == Component.Identifier.Axis.X) { - offset = 0; - } else if (id == Component.Identifier.Axis.Y) { - offset = 1; - } else if (id == Component.Identifier.Axis.Z) { - offset = 2; - } else if (id == Component.Identifier.Axis.RX) { - offset = 3; - } else if (id == Component.Identifier.Axis.RY) { - offset = 4; - } else if (id == Component.Identifier.Axis.RZ) { - offset = 5; - } else if (id == Component.Identifier.Axis.SLIDER) { - //System.out.println("Slider on "+name+" instance = "+instance); - offset = 6 + (instance>>2); - } else if (id == Component.Identifier.Axis.POV) { - //System.out.println("POV on "+name+" instance = "+instance); - offset = 8 + instance; - } else if (id instanceof Component.Identifier.Button) { - //System.out.println("Button on "+name+" instance = "+instance); - offset = 12 + (instance/4); - bitshift = (instance%4)*8; - bitmask=0xff; - - //Nasty cludge to get some similarities across platforms. - if(name.contains("A Button")) { - this.id = Component.Identifier.Button.A; - } else if(name.contains("B Button")) { - this.id = Component.Identifier.Button.B; - } else if(name.contains("C Button")) { - this.id = Component.Identifier.Button.C; - } else if(name.contains("X Button")) { - this.id = Component.Identifier.Button.X; - } else if(name.contains("Y Button")) { - this.id = Component.Identifier.Button.Y; - } else if(name.contains("Z Button")) { - this.id = Component.Identifier.Button.Z; - } - } - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return A float between -1.0 and 1.0 - */ - public float getPollData() { - int data = 0; - try { - data = ((device.data[offset] >> bitshift)&bitmask); - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Tried to get data for axis: " + this.getName() + ", device.data[" + offset + "] does not exists as device.data is only " + device.data.length + " long."); - } - if ((type&DIDFT_BUTTON) != 0 ) { - return (float)((data&0x80)>>7); - } else if ((type&DIDFT_AXIS)!=0){ // all axes are set for -32768 to 32738 - return ((float)data)/32768; - } else if ((type&DIDFT_POV)!=0) { - if (data == -1) { - return Component.POV.OFF; - } else if (data == 0.0) { - return Component.POV.UP; - } else if (data == 4500) { - return Component.POV.UP_RIGHT; - } else if (data == 9000) { - return Component.POV.RIGHT; - } else if (data == 13500) { - return Component.POV.DOWN_RIGHT; - } else if (data == 18000) { - return Component.POV.DOWN; - } else if (data == 22500) { - return Component.POV.DOWN_LEFT; - } else if (data == 27000) { - return Component.POV.LEFT; - } else if (data == 31500) { - return Component.POV.UP_LEFT; - } else { - System.err.print("Unexpected value for DX8 HAT: "+data); - return Component.POV.OFF; - } - } else { // return raw value - return (float)data; - } - - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if data has chnaged since last poll, else false - */ - public boolean isRelative() { - return (type & DIDFT_RELAXIS) != 0; - } - - /** Returns whether or not the axis is analog, or false if it is digital. - * @return true if analog, false if digital - */ - public boolean isAnalog() { - return (type & DIDFT_AXIS) != 0; - } - - /** Returns whether or not data polled from this axis is normalized - * between the values of -1.0f and 1.0f. - * @return true if data is normalized, false if not. - */ - public boolean isNormalized() { - return (type & (DIDFT_BUTTON|DIDFT_AXIS|DIDFT_POV)) != 0; - } - - /** Creates a new DirectInputAxis (factory method). - * This is a function used internally during set up - * @return The new DirectInputAxis object. - * @param device The device to attach this axis to. - * - * @param didft The identifier for the axis as provided by DX8. - * @param name A name to give the new axis. - * @param id The identifier for the device - */ - public static DirectInputAxis createAxis(DirectInputDevice device, - Component.Identifier id, int didft, String name) { - return new DirectInputAxis(device, id, didft, name); - } -} diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java b/plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java deleted file mode 100644 index e8f500b..0000000 --- a/plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistribution of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materails provided with the distribution. - * - * Neither the name Sun Microsystems, Inc. or the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND - * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS - * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for us in - * the design, construction, operation or maintenance of any nuclear facility - * - *****************************************************************************/ -package net.java.games.input; - -import net.java.games.input.AbstractController; -import net.java.games.input.Component; -import java.util.ArrayList; -import java.util.Iterator; - -/** - * - * @author martak - * @version - */ -class DirectInputDevice extends AbstractController { - - /** - * DIDEVTYPE_ constants from dinput.h header file - ** JPK NOTE: This changed in DI8. In general this - * is fragile anda way shoudl be found to tie these mroe directly - * to the header files. - */ - /* Mike's <=DX7 types - private static final int DIDEVTYPEJOYSTICK_UNKNOWN = 1; - private static final int DIDEVTYPEJOYSTICK_TRADITIONAL = 2; - private static final int DIDEVTYPEJOYSTICK_FLIGHTSTICK = 3; - private static final int DIDEVTYPEJOYSTICK_GAMEPAD = 4; - private static final int DIDEVTYPEJOYSTICK_RUDDER = 5; - private static final int DIDEVTYPEJOYSTICK_WHEEL = 6; - private static final int DIDEVTYPEJOYSTICK_HEADTRACKER = 7; - */ - - /** - * Pointer to the IDirectInputDevice for this device - */ - private long lpDevice; - - /** - * Type of device - */ - private Type type; - - /** - * Do we need to poll data? - */ - private boolean polled = true; - /** - * Data when polling, as per the DIJOYSTATE structure in dinput.h; - * @see DirectInputAxis for a breakdown of this structure - */ - int[] data = new int[38]; - - /** Array list of rumblers */ - private ArrayList rumblerList = new ArrayList(); - - /** - * Private constructor - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param subtype The subtype of device, as defined in the DIDEVTYPE - * constants above - * @param productName The product name for the device - * @param instanceName The name of the device - */ - private DirectInputDevice(long lpDevice, int subtype, String productName, - String instanceName,boolean polled) { - super(productName + " " + instanceName); - this.lpDevice = lpDevice; - this.polled = polled; - System.out.println("Creating "+productName+" polling = "+polled); - switch(subtype) { - /* - case DIDEVTYPEJOYSTICK_GAMEPAD: - type = Type.GAMEPAD; break; - case DIDEVTYPEJOYSTICK_RUDDER: - type = Type.RUDDER; break; - case DIDEVTYPEJOYSTICK_WHEEL: - type = Type.WHEEL; break; - case DIDEVTYPEJOYSTICK_HEADTRACKER: - type = Type.HEADTRACKER; break; - case DIDEVTYPEJOYSTICK_TRADITIONAL: // fall through - case DIDEVTYPEJOYSTICK_FLIGHTSTICK: // fall through - */ - default: - type = Type.STICK; break; - } - components = initDirectInputAxes(); - } - - /** - * Used instead of overriding initAxes because it needs the - * pointer to the IDirectInputDevice - */ - private Component[] initDirectInputAxes() { - ArrayList list = new ArrayList(); - enumObjects(lpDevice, list); - Component[] ret = new Component[list.size()]; - Iterator it = list.iterator(); - int i = 0; - while (it.hasNext()) { - ret[i] = (Component)it.next(); - i++; - } - return ret; - } - - /** - * Callback called by enumObjects to add a new axis into the list - * @param list This in which to add the new axis - * @param id The identifier for the axis, based on GUID - * @param didft The combination of DIDFT_ flags that make up the type and - * instance number of the axis. - * @param name The name to call the axis. - */ - private void addAxis(ArrayList list, Component.Identifier id, int didft, - String name) { - list.add(DirectInputAxis.createAxis(this, id, didft, name)); - } - - /** - * Callback called by enumDevice to add a rumbler - * - * @param effect the natie effect id - * @param axisID The axis ID - */ - private void addRumbler(long effect, Component.Identifier axisID, String axisName) { - rumblerList.add(new DirectInputRumbler(this, effect, axisID, axisName)); - } - - /** Polls axes for data. Returns false if the controller is no longer valid. - * Polling reflects the current state of the device when polled, and is - * unbuffered. - * @return False if the co troller is no longer valid, else true. - */ - public boolean poll() { - return pollNative(lpDevice, data, polled); - } - - /** Returns the type of Controller. - * @return The type of the controller. - */ - public Type getType() { - return type; - } - - /** Returns the zero-based port number for this Controller. - * @return The port number. - */ - public int getPortNumber() { - // REMIND : We may be able to parse this from the name string - return 0; - } - - /** - * Returns the rumbler array - */ - public Rumbler[] getRumblers() { - return (Rumbler[]) rumblerList.toArray(new Rumbler[0]); - } - - /** - * Polls the device; native method. The data from the poll is stored in - * the data array. - */ - private native boolean pollNative(long lpDevice, int[] data, - boolean polled); - - /** - * Enumerates the axes on the device - */ - private native boolean enumObjects(long lpDevice, ArrayList list); - - /** Creates a new DirectInputDevice (factory method) - * This is a function used internally during set up - * @param polled Whether this device's driver should actually be - * polled during a call to Poll or whether it is an - * interrupt driven device that should ignore poll - * requests. - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param subtype The subtype of device, as defined in the DIDEVTYPE - * constants above - * @param productName The product name for the device - * @param instanceName The name of the device - * @return The new DirectInputDevice object - */ - public static DirectInputDevice createDevice(long lpDevice, int subtype, - String productName, String instanceName, boolean polled) { - return new DirectInputDevice(lpDevice, subtype, productName, - instanceName,polled); - } -} // class DirectInputDevice diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java b/plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java deleted file mode 100644 index d74d023..0000000 --- a/plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistribution of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materails provided with the distribution. - * - * Neither the name Sun Microsystems, Inc. or the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND - * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS - * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for us in - * the design, construction, operation or maintenance of any nuclear facility - * - *****************************************************************************/ -package net.java.games.input; - -import java.util.ArrayList; -import java.util.Iterator; -import net.java.games.input.Controller; -import net.java.games.input.ControllerEnvironment; -//import sun.security.action.LoadLibraryAction; -import net.java.games.util.plugins.Plugin; - -/** DirectInput implementation of controller environment - * @author martak - * @version 1.0 - */ -public class DirectInputEnvironmentPlugin extends ControllerEnvironment - implements Plugin -{ - - static { - /** Mikes old code, causes it to be laoded by wrong loader - java.security.AccessController.doPrivileged( - new LoadLibraryAction("jinput")); - */ - if(isSupported()) { - System.loadLibrary("jinput-dxplugin"); - } - } - - /** - * DIDEVTYPE_ constants from dinput.h header file - * JPK NOTE: changed in DX8 so had to be changed. This is - * fragile, we should find a way to set them from - * the C side sowe can stay up to date with header - */ - /** DX7 and earlier - private static final int DIDEVTYPE_DEVICE = 1; - private static final int DIDEVTYPE_MOUSE = 2; - private static final int DIDEVTYPE_KEYBOARD = 3; - private static final int DIDEVTYPE_JOYSTICK = 4; - private static final int DIDEVTYPE_HID = 0x00010000; - private static int GET_DIDEVICE_TYPE(int dwDevType) { - return (int)((byte)dwDevType); - } - private static int GET_DIDEVICE_SUBTYPE(int dwDevType) { - return (int)((byte)((((short)dwDevType) >> 8) & 0xFF)); - } - **/ - /* DX8 and 9 */ - private static final int DI8DEVTYPE_DEVICE = 0x11; - private static final int DI8DEVTYPE_MOUSE = 0x12; - private static final int DI8DEVTYPE_KEYBOARD = 0x13; - private static final int DI8DEVTYPE_JOYSTICK = 0x14; - private static final int DI8DEVTYPE_GAMEPAD = 0x15; - private static final int DI8DEVTYPE_DRIVING = 0x16; - private static final int DI8DEVTYPE_FLIGHT = 0x17; - private static final int DI8DEVTYPE_1STPERSON = 0x18; - private static final int DI8DEVTYPE_DEVICECTRL = 0x19; - private static final int DI8DEVTYPE_SCREENPOINTER = 0x1A; - private static final int DI8DEVTYPE_REMOTE = 0x1B; - private static final int DI8DEVTYPE_SUPPLEMENTAL = 0x1C; - - private static int GET_DIDEVICE_TYPE(int dwDevType) { - return (dwDevType&0xFF); - } - private static int GET_DIDEVICE_SUBTYPE(int dwDevType) { - return (int)((byte)((((short)dwDevType) >> 8) & 0xFF)); - } - - // Pointer to DirectInput instance - private long lpDirectInput; - // Permanent array of controllers - private Controller[] controllers; - - /** Creates new DirectInputEnvironment */ - public DirectInputEnvironmentPlugin() { - if(isSupported()) { - lpDirectInput = directInputCreate(); - enumControllers(); - } else { - controllers = new Controller[0]; - } - } - - public static boolean isSupported() { - System.out.println("OS name is: " + System.getProperty("os.name")); - if(System.getProperty("os.name").indexOf("Windows")!=-1) { - System.out.println("DX8 plugin is supported"); - return true; - } - System.out.println("DX8 plugin is not supported"); - return false; - } - - /** Returns a list of all controllers available to this environment, - * or an empty array if there are no controllers in this environment. - * @return An array of controllers that may be empty. - */ - public Controller[] getControllers() { - return controllers; - } - - private void enumControllers() { - // If direct input fails, create an empty array - if (lpDirectInput == 0) { - controllers = new Controller[] {}; - return; - } - // Create temporary controller array - ArrayList tempDevices = new ArrayList(); - // Eumerate devices - enumDevices(lpDirectInput, tempDevices); - // Set up permanent controller array - controllers = new Controller[tempDevices.size()]; - Iterator it = tempDevices.iterator(); - int i = 0; - while (it.hasNext()) { - controllers[i] = (Controller)it.next(); - i++; - } - } - - /** - * Creates a new device, adding it to the list supplied. - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param type The type of device to create, as defined by the constants - * in dinput.h (see DI8DEVTYPE constants above). - * @param productName The product name for the device - * @param instanceName The name of the device - */ - private void addDevice(ArrayList list, long lpDevice, - int type, String productName, String instanceName, boolean polled) { - Controller c; - int category = GET_DIDEVICE_TYPE(type); - int subtype = GET_DIDEVICE_SUBTYPE(type); - //System.out.println("Category = "+category); - if (category == DI8DEVTYPE_MOUSE) { - c = DirectInputMouse.createMouse(lpDevice, subtype, productName, - instanceName); - } else if (category == DI8DEVTYPE_KEYBOARD) { - c = DirectInputKeyboard.createKeyboard(lpDevice, subtype, - productName, instanceName); - } else { - // commented out the assert as we have already got devices that are - // gamepad type, but wr are still going to create them as - // DirectInputDevices - //assert category == DI8DEVTYPE_JOYSTICK; - c = DirectInputDevice.createDevice(lpDevice, subtype, productName, - instanceName,polled); - } - if (c != null) { - list.add(c); - } - } - - /** - * Returns the direct input instance, or 0 if failed to initialize - */ - private native long directInputCreate(); - - /** - * Enumerates all devices, calling createDevice for each one - */ - private native boolean enumDevices(long lpDirectInput, ArrayList list); -} // class DirectInputEnvironment diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java b/plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java deleted file mode 100644 index 9b5833c..0000000 --- a/plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistribution of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materails provided with the distribution. - * - * Neither the name Sun Microsystems, Inc. or the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND - * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS - * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for us in - * the design, construction, operation or maintenance of any nuclear facility - * - *****************************************************************************/ -package net.java.games.input; - -import net.java.games.input.AbstractComponent; -import net.java.games.input.Component; -import net.java.games.input.StandardKeyboard; - -/** - * DirectInput keyboard implementation. - * @author martak - * @version - */ -class DirectInputKeyboard extends StandardKeyboard { - - /** - * DIDEVTYPE_ constants from dinput.h header file - */ - private static final int DIDEVTYPEKEYBOARD_UNKNOWN = 0; - private static final int DIDEVTYPEKEYBOARD_PCXT = 1; - private static final int DIDEVTYPEKEYBOARD_OLIVETTI = 2; - private static final int DIDEVTYPEKEYBOARD_PCAT = 3; - private static final int DIDEVTYPEKEYBOARD_PCENH = 4; - private static final int DIDEVTYPEKEYBOARD_NOKIA1050 = 5; - private static final int DIDEVTYPEKEYBOARD_NOKIA9140 = 6; - private static final int DIDEVTYPEKEYBOARD_NEC98 = 7; - private static final int DIDEVTYPEKEYBOARD_NEC98LAPTOP = 8; - private static final int DIDEVTYPEKEYBOARD_NEC98106 = 9; - private static final int DIDEVTYPEKEYBOARD_JAPAN106 = 10; - private static final int DIDEVTYPEKEYBOARD_JAPANAX = 11; - private static final int DIDEVTYPEKEYBOARD_J3100 = 12; - - /** - * Key index crosstable; maps indices into the data array to virtual keys - * in the key array in StandardKeyboard. - * For example, the key F11 is at index 84 in the array of keys in - * StandardKeyboard, yet it is data element 87 (0x57) in our data array. - * <p> - * To access the data element of a particular key (F11), we use the - * crosstable as follows: - * <p><code> - * KeyID f11 = StandardKey.KeyID.F11; - * int keyIndex = f11.getKeyIndex(); // returns 84 - * int crossIndex = CROSSTABLE[keyIndex]; // returns 0x57 (87) - * </code> - * To find a key given the data element index (87), we do a simple search - * through the crosstable starting at that index (index 87/0x57 = 0x65) and - * looking backwards until we find our key itself, or a lower number - * (meaning the key was not found). We can only take advantage of this - * algorithm only because on Windows, our crosstable is in increasing order. - */ - private final static int[] CROSSTABLE = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, // _9 - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // Y - 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // D - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, // BACKSLASH - 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, // RSHIFT - 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, // F7 - 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, // NUMPAD5 - 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x57, 0x58, 0x64, 0x65, // F14 - 0x66, 0x70, 0x79, 0x7B, 0x7D, 0x8D, 0x90, 0x91, 0x92, 0x93, 0x94, // KANJI - 0x95, 0x96, 0x97, 0x9C, 0x9D, 0xB3, 0xB5, 0xB7, 0xB8, 0xC5, 0xC7, // HOME - 0xC8, 0xC9, 0xCB, 0xCD, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xDB, 0xDC, // RWIN - 0xDD, 0xDE, 0xDF // SLEEP - }; - - /** - * Pointer to the IDirectInputDevice for this device - */ - private long lpDevice; - - /** - * Subtype of keyboard, defined by DIDEVTYPE constants - */ - private int subtype; - - /** - * Polling key data - */ - private byte[] keyData = new byte[256]; - - /** - * Private constructor - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param subtype The subtype of keyboard, as defined in the DIDEVTYPE - * constants above - * @param productName The product name for the device - * @param instanceName The name of the device - */ - private DirectInputKeyboard(long lpDevice, int subtype, String productName, - String instanceName) { - super(productName + " (" + instanceName + ")"); - this.lpDevice = lpDevice; - this.subtype = subtype; - } - - /** - * Callback to rename a given key by index, name - * @param index the index in the data array - * @param name the name of the key - */ - private void renameKey(int index, String name) { - int keyIndex = index; - if (keyIndex > CROSSTABLE.length) { - keyIndex = CROSSTABLE.length - 1; - } - for (; CROSSTABLE[keyIndex] > index; keyIndex--) - ; - if (CROSSTABLE[keyIndex] == index) { - Component[] components = getComponents(); - AbstractComponent key = (AbstractComponent)components[index]; - if (name != null && name.length() > 0) { - //System.out.println("Renaming key " + key.getName() + - // " to " + name + " index=" + - // index + " keyIndex=" + keyIndex + " CROSSTAB=" + - // CROSSTABLE[keyIndex]); - key.setName(name); - } - } else { - //System.out.println("Key not found " + name + " index=" + index + - // " keyIndex=" + keyIndex + " CROSSTAB=" + - // CROSSTABLE[keyIndex]); - } - } - - /** Polls axes for data. Returns false if the controller is no longer valid. - * Polling reflects the current state of the device when polled. - * @return False if the KB is no longer valid, true otherwise. - */ - public boolean poll() { - return pollNative(lpDevice, keyData); - } - - /** Returns whether or not the given key has been pressed since the last - * call to poll. - * @param key The key whose state to check. - * @return true if this key has changed state since last read of its state, false otherwise. - */ - protected boolean isKeyPressed(Key key) { - Component.Identifier.Key id = (Component.Identifier.Key)key.getIdentifier(); - int keyIndex = id.getKeyIndex(); - int crossIndex = CROSSTABLE[keyIndex]; - return ((keyData[crossIndex] & 0x80) != 0); - } - - /** - * Polls the device; native method - */ - private native boolean pollNative(long lpDevice, byte[] keyData); - - /** - * Renames the keys with the name provided by DirectInput - */ - private native boolean renameKeys(long lpDevice); - - /** Creates a new DirectInputKeyboard (factory method) - * This is a function used internally during set up. - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param subtype The subtype of keyboard, as defined in the DIDEVTYPE - * constants above - * @param productName The product name for the keyboard - * @param instanceName The name of the keyboard - * @return The new DirectInputKeyboard object. - */ - public static DirectInputKeyboard createKeyboard(long lpDevice, - int subtype, String productName, String instanceName) { - DirectInputKeyboard ret = new DirectInputKeyboard(lpDevice, subtype, - productName, instanceName); - ret.renameKeys(lpDevice); - return ret; - } -} // class DirectInputKeyboard diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java b/plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java deleted file mode 100644 index 4d9e257..0000000 --- a/plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistribution of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materails provided with the distribution. - * - * Neither the name Sun Microsystems, Inc. or the names of the contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND - * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS - * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for us in - * the design, construction, operation or maintenance of any nuclear facility - * - *****************************************************************************/ -package net.java.games.input; - -import net.java.games.input.AbstractComponent; -import net.java.games.input.Component; -import net.java.games.input.Mouse; - -/** - * DirectInput mouse implementation. - * @author martak - * @version - */ -class DirectInputMouse extends Mouse { - - /** - * DIDEVTYPE_ constants from dinput.h header file - */ - private static final int DIDEVTYPEMOUSE_UNKNOWN = 1; - private static final int DIDEVTYPEMOUSE_TRADITIONAL = 2; - private static final int DIDEVTYPEMOUSE_FINGERSTICK = 3; - private static final int DIDEVTYPEMOUSE_TOUCHPAD = 4; - private static final int DIDEVTYPEMOUSE_TRACKBALL = 5; - - /** - * Pointer to the IDirectInputDevice for this device - */ - private long lpDevice; - - /** - * Type of mouse - */ - private Type type; - - /** - * Mouse data - */ - private byte[] mouseData = new byte[20]; - - /** - * Private constructor - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param subtype The subtype of mouse, as defined in the DIDEVTYPE - * constants above - * @param productName The product name for the device - * @param instanceName The name of the device - */ - private DirectInputMouse(long lpDevice, int subtype, String productName, - String instanceName) { - super(productName + " " + instanceName); - this.lpDevice = lpDevice; - buttons = new ButtonsImpl(); - ball = new BallImpl(); - switch(subtype) { - case DIDEVTYPEMOUSE_FINGERSTICK: - type = Type.FINGERSTICK; break; - case DIDEVTYPEMOUSE_TOUCHPAD: - type = Type.TRACKPAD; break; - case DIDEVTYPEMOUSE_TRACKBALL: - type = Type.TRACKBALL; break; - case DIDEVTYPEMOUSE_TRADITIONAL: // fall through - case DIDEVTYPEMOUSE_UNKNOWN: // fall through - default: - type = Type.MOUSE; break; - } - renameAxes(lpDevice); - } - - /** - * Callback to rename a given axis by type, name - */ - private void renameAxis(Component.Identifier id, String name) { - AbstractComponent axis; - if (id instanceof Component.Identifier.Button) { - axis = (AbstractComponent)getButtons().getComponent(id); - } else { - axis = (AbstractComponent)getBall().getComponent(id); - } - axis.setName(name); - //System.out.println("Renaming " + name); - } - - /** Polls axes for data. Returns false if the controller is no longer valid. - * Polling reflects the current state of the device when polled. - * @return false if the mosue is no lonegr valid, true otherwise. - */ - public boolean poll() { - return pollNative(lpDevice, mouseData); - } - - /** Returns the type of the Controller. - * @return The device type of the controller (logically this - * shoudl be some form of "mouse" .) - */ - public Type getType() { - return type; - } - - /** Creates a new DirectInputMouse (factory method) - * This is a function used internally during set up. - * @param lpDevice A pointer to the IDirectInputDevice for the device. - * @param subtype The subtype of mouse, as defined in the DIDEVTYPE - * constants above - * @param productName The product name for the keyboard - * @param instanceName The name of the keyboard - * @return The new DirectInputMouse object. - */ - public static DirectInputMouse createMouse(long lpDevice, int subtype, - String productName, String instanceName) { - return new DirectInputMouse(lpDevice, subtype, productName, - instanceName); - } - - /** - * Implementation class representing the mouse ball - */ - class BallImpl extends Ball { - - private int numAxes; - - /** - * Public constructor - */ - public BallImpl() { - super(DirectInputMouse.this.getName() + " ball"); - numAxes = getNumAxes(lpDevice); - x = new BallAxis(Component.Identifier.Axis.X); - y = new BallAxis(Component.Identifier.Axis.Y); - if(numAxes > 2) { - wheel = new BallAxis(Component.Identifier.Axis.SLIDER); - } - } - } // class DirectInputMouse.BallImpl - - /** - * Implementation class representing the mouse buttons - */ - class ButtonsImpl extends Buttons { - - private int numButtons; - - /** - * Public constructor - */ - public ButtonsImpl() { - super(DirectInputMouse.this.getName() + " buttons"); - numButtons = getNumButtons(lpDevice); - left = new ButtonImpl(Component.Identifier.Button.LEFT); - right = new ButtonImpl(Component.Identifier.Button.RIGHT); - if(numButtons>2) { - middle = new ButtonImpl(Component.Identifier.Button.MIDDLE); - } - if(numButtons>3) { - side = new ButtonImpl(Component.Identifier.Button.SIDE); - } - if(numButtons>4) { - extra = new ButtonImpl(Component.Identifier.Button.EXTRA); - } - if(numButtons>5) { - forward = new ButtonImpl(Component.Identifier.Button.FORWARD); - } - if(numButtons>6) { - back = new ButtonImpl(Component.Identifier.Button.BACK); - } - } - } // class DirectInputMouse.ButtonsImpl - - /** - * Polls the device; native method - */ - private native boolean pollNative(long lpDevice, byte[] mouseData); - - /** - * Renames the axes with the name provided by DirectInput - */ - private native boolean renameAxes(long lpDevice); - - // another Endolf special - /** - * Gets the number of buttons the mouse supports - */ - private native int getNumButtons(long lpDevice); - /** - * Gets the number of axes the mouse supports - */ - private native int getNumAxes(long lpDevice); - - /** - * Mouse button axis implementation - */ - class ButtonImpl extends Button { - - /** - * Index into the mouseData array - */ - private final int index; - - /** Public constructor - * @param id An ID of a button to create an obejct to represent. - * - */ - public ButtonImpl(Component.Identifier.Button id) { - super(id.getName(), id); - if (id == Component.Identifier.Button.LEFT) { - index = 12; - } else if (id == Component.Identifier.Button.RIGHT) { - index = 13; - } else if (id == Component.Identifier.Button.MIDDLE) { - index = 14; - } else if (id == Component.Identifier.Button.SIDE) { - index = 15; - } else if (id == Component.Identifier.Button.EXTRA) { - index = 16; - } else if (id == Component.Identifier.Button.FORWARD) { - index = 17; - } else if (id == Component.Identifier.Button.BACK) { - index = 18; - } else { - throw new RuntimeException("Unknown button"); - } - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return state of controller. (Note: DX8 mice actually - * queue state so what is returned is the next state, - * not necessarily the most current one.) - */ - public float getPollData() { - // Mouse button - byte data = mouseData[index]; - if ((data & 0x80) != 0) { - return 1.0f; - } else { - return 0.0f; - } - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if data is relative, otherwise false. - */ - public boolean isRelative() { - return false; - } - } // class DirectInputMouse.ButtonImpl - - /** - * Mouse ball axis implementation - */ - class BallAxis extends AbstractComponent { - - /** - * Starting index into the mouseData array - */ - private final int index; - - /** Public constructor - * @param id An ID for a mouse axis to create an object to represent. - */ - public BallAxis(Identifier id) { - super(id.getName(), id); - if (id == Identifier.Axis.X) { - index = 0; - } else if (id == Identifier.Axis.Y) { - index = 4; - } else if (id == Identifier.Axis.SLIDER) { - index = 8; - } else { - throw new RuntimeException("Unknown mouse axis"); - } - } - - // Endolf changed this comment, we *are* a mouse axis if we are in here, - // and mouse axes no longer are normalised at all - /** Returns the data from the last time the control has been polled. - * - * @return data The total mouse axis change since the last poll - */ - public float getPollData() { - int data = ((int)mouseData[index+3] << 24) | - ((int)mouseData[index + 2] << 16) | - ((int)mouseData[index + 1] << 8) | - ((int)mouseData[index]); - return (float)data; - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if relative, otherwise false. - */ - public boolean isRelative() { - return true; - } - - /** Returns whether or not the axis is analog, or false if it is digital. - * @return true if analog, false if digital - */ - public boolean isAnalog() { - return true; - } - - /** Returns whether or not data polled from this axis is normalized between the values of -1.0f and 1.0f. - * - * @return true if normalized, otherwise false. - */ - public boolean isNormalized() { - return false; - } - - } // class DirectInputMouse.MouseBallAxis -} // class DirectInputMouse diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputRumbler.java b/plugins/DX8/src/java/net/java/games/input/DirectInputRumbler.java deleted file mode 100644 index 5d9ead1..0000000 --- a/plugins/DX8/src/java/net/java/games/input/DirectInputRumbler.java +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ -package net.java.games.input; - -/** - * Implementation of the Rumbler interface for direct x - * - * @author Endolf - */ -public class DirectInputRumbler implements Rumbler { - - /** The parent device */ - private DirectInputDevice device; - /** The native effect */ - private long effect; - /** The identifier of the axis we are attached too */ - private Component.Identifier axisID; - /** The name of the axis this rumbler is attached too */ - private String axisName; - - /** - * Creates a new instance of DirectInputRumbler - * - * @param device The parent device - * @param effect The native effect - * @param axisID The id of the axis this rumbler is attached too - * @param axisName The name of the axis this rumbler is attached too - */ - public DirectInputRumbler(DirectInputDevice device, long effect, Component.Identifier axisID, String axisName) { - this.device = device; - this.effect = effect; - this.axisID = axisID; - this.axisName = axisName; - - Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook(this))); - } - - /** - * Gets the identifier of the axis this rumbler is attached too - * - * @return The axis id - */ - public Component.Identifier getAxisIdentifier() { - return axisID; - } - - /** - * Gets the name of the axis this rumbler is attached too - * - * @return The axis name - */ - public String getAxisName() { - return axisName; - } - - /** - * Rumbles this rumbler at the given intensity. - * This will start or stop the effect if necesary. - * The intensity is in the range of -1 to 1 and will be clipped if values - * outside that range are provided. - * - * @param intensity The intensity - */ - public void rumble(float intensity) { - if(intensity>1f) { - intensity = 1.0f; - } else if(intensity<-1f) { - intensity = -1.0f; - } - setRumble(effect, intensity); - } - - /** - * Performs the native call(s) to run the effect - * - * @param effect The native effect - * @param intensity The intensity of the rumble - */ - private native void setRumble(long effect, float intensity); - - private class ShutdownHook implements Runnable { - private DirectInputRumbler rumbler; - public ShutdownHook(DirectInputRumbler rumbler) { - this.rumbler = rumbler; - } - - public void run() { - if(rumbler!=null) { - System.out.println("Reseting rumbler " + getAxisName() + " before exit"); - rumbler.rumble(0f); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - //Ignore, we are quitting anyway - } - } - } - } -} diff --git a/plugins/DX8/src/native/input.cpp b/plugins/DX8/src/native/input.cpp deleted file mode 100644 index a6e2fd1..0000000 --- a/plugins/DX8/src/native/input.cpp +++ /dev/null @@ -1,1494 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -#ifndef WIN32 - #error This is a Windows-only file -#endif - -// hard define as DX7 -//#define DIRECTINPUT_VERSION 0x0800 -#include <windows.h> -#include <jni.h> -#include <dinput.h> - - -/* - ****************************************************************************** - * Global variables - ****************************************************************************** - */ -jclass CLASS_AxisIdentifier = NULL; -jclass CLASS_ButtonIdentifier = NULL; -jclass CLASS_DirectInputEnvironmentPlugin = NULL; -jclass CLASS_DirectInputDevice = NULL; -jclass CLASS_DirectInputKeyboard = NULL; -jclass CLASS_DirectInputMouse = NULL; -jmethodID MID_AddDevice = NULL; -jmethodID MID_AddAxis = NULL; -jmethodID MID_AddRumbler = NULL; -jmethodID MID_RenameKey = NULL; -jmethodID MID_RenameAxis = NULL; -jfieldID FID_X = NULL; -jfieldID FID_Y = NULL; -jfieldID FID_Z = NULL; -jfieldID FID_RX = NULL; -jfieldID FID_RY = NULL; -jfieldID FID_RZ = NULL; -jfieldID FID_Slider = NULL; -jfieldID FID_Button0 = NULL; -jfieldID FID_Button1 = NULL; -jfieldID FID_Button2 = NULL; -jfieldID FID_Button3 = NULL; -jfieldID FID_Button4 = NULL; -jfieldID FID_Button5 = NULL; -jfieldID FID_Button6 = NULL; -jfieldID FID_Button7 = NULL; -jfieldID FID_Button8 = NULL; -jfieldID FID_Button9 = NULL; -jfieldID FID_Button10 = NULL; -jfieldID FID_Button11 = NULL; -jfieldID FID_Button12 = NULL; -jfieldID FID_Button13 = NULL; -jfieldID FID_Button14 = NULL; -jfieldID FID_Button15 = NULL; -jfieldID FID_Button16 = NULL; -jfieldID FID_Button17 = NULL; -jfieldID FID_Button18 = NULL; -jfieldID FID_Button19 = NULL; -jfieldID FID_Button20 = NULL; -jfieldID FID_Button21 = NULL; -jfieldID FID_Button22 = NULL; -jfieldID FID_Button23 = NULL; -jfieldID FID_Button24 = NULL; -jfieldID FID_Button25 = NULL; -jfieldID FID_Button26 = NULL; -jfieldID FID_Button27 = NULL; -jfieldID FID_Button28 = NULL; -jfieldID FID_Button29 = NULL; -jfieldID FID_Button30 = NULL; -jfieldID FID_Button31 = NULL; -jfieldID FID_UnknownButton = NULL; -jfieldID FID_POV = NULL; -jfieldID FID_Left = NULL; -jfieldID FID_Right = NULL; -jfieldID FID_Middle = NULL; -jfieldID FID_Extra = NULL; -jfieldID FID_Side = NULL; -jfieldID FID_Forward = NULL; -jfieldID FID_Back = NULL; - -const char* FD_AxisIdentifier = "Lnet/java/games/input/Component$Identifier$Axis;"; -const char* FD_ButtonIdentifier = "Lnet/java/games/input/Component$Identifier$Button;"; -// Dummy input window. This is needed because DirectX evidently needs a window -// to do anything, such as setting the cooperative level for a device. -const TCHAR* DUMMY_WINDOW_NAME = "InputControllerWindow"; -HWND hwndDummy = NULL; -// Buffer size -// Endolf changed the name as it is specific to the mouse -// Endolf increased the size as he kept making it go pop -const DWORD MOUSE_BUFFER_SIZE = 32; - -// Class for handing device data to the callback for EnumDevices -class DeviceParamData { -public: - DeviceParamData(LPDIRECTINPUT8 lpdi, JNIEnv* e, jobject o, jobject l) : - lpDirectInput(lpdi), env(e), obj(o), list(l) - { - } - LPDIRECTINPUT8 lpDirectInput; - JNIEnv* env; - jobject obj; - jobject list; -}; - -// Class for handing device data to the callback for EnumObjects -class ObjectParamData { -public: - ObjectParamData(LPDIRECTINPUTDEVICE8 lpDev, JNIEnv* e, jobject o, - jobject l) : - lpDevice(lpDev), env(e), obj(o), list(l) - { - } - LPDIRECTINPUTDEVICE8 lpDevice; - JNIEnv* env; - jobject obj; - jobject list; -}; - -void PrintOutput(TCHAR* tszMessage) { - printf("%s\n", tszMessage); -} - -void PrintDIError(TCHAR* tszOutput, HRESULT res) { - TCHAR tszMessage[256]; -#define CHECK_RESULT(r) case r: \ -sprintf(tszMessage, "%s : %s", tszOutput, #r); \ -break; - switch (res) { - CHECK_RESULT(DI_OK) - CHECK_RESULT(DI_NOTATTACHED) - CHECK_RESULT(DI_POLLEDDEVICE) - CHECK_RESULT(DI_DOWNLOADSKIPPED) - CHECK_RESULT(DI_EFFECTRESTARTED) - CHECK_RESULT(DI_TRUNCATED) - CHECK_RESULT(DI_TRUNCATEDANDRESTARTED) - CHECK_RESULT(DIERR_OLDDIRECTINPUTVERSION) - CHECK_RESULT(DIERR_BETADIRECTINPUTVERSION) - CHECK_RESULT(DIERR_BADDRIVERVER) - CHECK_RESULT(DIERR_DEVICENOTREG) - CHECK_RESULT(DIERR_NOTFOUND) - //CHECK_RESULT(DIERR_OBJECTNOTFOUND) - CHECK_RESULT(DIERR_INVALIDPARAM) - CHECK_RESULT(DIERR_NOINTERFACE) - CHECK_RESULT(DIERR_GENERIC) - CHECK_RESULT(DIERR_OUTOFMEMORY) - CHECK_RESULT(DIERR_UNSUPPORTED) - CHECK_RESULT(DIERR_NOTINITIALIZED) - CHECK_RESULT(DIERR_ALREADYINITIALIZED) - CHECK_RESULT(DIERR_NOAGGREGATION) - CHECK_RESULT(DIERR_OTHERAPPHASPRIO) - CHECK_RESULT(DIERR_INPUTLOST) - CHECK_RESULT(DIERR_ACQUIRED) - CHECK_RESULT(DIERR_NOTACQUIRED) - //CHECK_RESULT(DIERR_READONLY) - //CHECK_RESULT(DIERR_HANDLEEXISTS) - CHECK_RESULT(DIERR_INSUFFICIENTPRIVS) - CHECK_RESULT(DIERR_DEVICEFULL) - CHECK_RESULT(DIERR_MOREDATA) - CHECK_RESULT(DIERR_NOTDOWNLOADED) - CHECK_RESULT(DIERR_HASEFFECTS) - CHECK_RESULT(DIERR_NOTEXCLUSIVEACQUIRED) - CHECK_RESULT(DIERR_INCOMPLETEEFFECT) - CHECK_RESULT(DIERR_NOTBUFFERED) - CHECK_RESULT(DIERR_EFFECTPLAYING) - CHECK_RESULT(DIERR_UNPLUGGED) - CHECK_RESULT(DIERR_REPORTFULL) - default: sprintf(tszMessage, "Unknown"); break; - } - PrintOutput(tszMessage); -} - -/* - ****************************************************************************** - * DirectInputEnvironmentPlugin - ****************************************************************************** - */ - -/* - * Initialize all class, method, and field IDs - */ -BOOL InitIDs(JNIEnv* env) { - CLASS_AxisIdentifier = - env->FindClass("net/java/games/input/Component$Identifier$Axis"); - if (CLASS_AxisIdentifier == NULL) { - return FALSE; - } - FID_X = env->GetStaticFieldID(CLASS_AxisIdentifier, "X", - FD_AxisIdentifier); - if (FID_X == NULL) { - return FALSE; - } - FID_Y = env->GetStaticFieldID(CLASS_AxisIdentifier, "Y", - FD_AxisIdentifier); - if (FID_Y == NULL) { - return FALSE; - } - FID_Z = env->GetStaticFieldID(CLASS_AxisIdentifier, "Z", - FD_AxisIdentifier); - if (FID_Z == NULL) { - return FALSE; - } - FID_RX = env->GetStaticFieldID(CLASS_AxisIdentifier, "RX", - FD_AxisIdentifier); - if (FID_RX == NULL) { - return FALSE; - } - FID_RY = env->GetStaticFieldID(CLASS_AxisIdentifier, "RY", - FD_AxisIdentifier); - if (FID_RY == NULL) { - return FALSE; - } - FID_RZ = env->GetStaticFieldID(CLASS_AxisIdentifier, "RZ", - FD_AxisIdentifier); - if (FID_RZ == NULL) { - return FALSE; - } - FID_Slider = env->GetStaticFieldID(CLASS_AxisIdentifier, "SLIDER", - FD_AxisIdentifier); - if (FID_Slider == NULL) { - return FALSE; - } - CLASS_ButtonIdentifier = - env->FindClass("net/java/games/input/Component$Identifier$Button"); - if (CLASS_ButtonIdentifier == NULL) { - return FALSE; - } - FID_UnknownButton = env->GetStaticFieldID(CLASS_ButtonIdentifier, "UNKNOWN", - FD_ButtonIdentifier); - if (FID_UnknownButton == NULL) { - return FALSE; - } - FID_Button0 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_0", - FD_ButtonIdentifier); - if (FID_Button0 == NULL) { - return FALSE; - } - FID_Button1 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_1", - FD_ButtonIdentifier); - if (FID_Button1 == NULL) { - return FALSE; - } - FID_Button2 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_2", - FD_ButtonIdentifier); - if (FID_Button2 == NULL) { - return FALSE; - } - FID_Button3 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_3", - FD_ButtonIdentifier); - if (FID_Button3 == NULL) { - return FALSE; - } - FID_Button4 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_4", - FD_ButtonIdentifier); - if (FID_Button4 == NULL) { - return FALSE; - } - FID_Button5 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_5", - FD_ButtonIdentifier); - if (FID_Button5 == NULL) { - return FALSE; - } - FID_Button6 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_6", - FD_ButtonIdentifier); - if (FID_Button6 == NULL) { - return FALSE; - } - FID_Button7 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_7", - FD_ButtonIdentifier); - if (FID_Button7 == NULL) { - return FALSE; - } - FID_Button8 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_8", - FD_ButtonIdentifier); - if (FID_Button8 == NULL) { - return FALSE; - } - FID_Button9 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_9", - FD_ButtonIdentifier); - if (FID_Button9 == NULL) { - return FALSE; - } - FID_Button10 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_10", - FD_ButtonIdentifier); - if (FID_Button10 == NULL) { - return FALSE; - } - FID_Button11 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_11", - FD_ButtonIdentifier); - if (FID_Button11 == NULL) { - return FALSE; - } - FID_Button12 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_12", - FD_ButtonIdentifier); - if (FID_Button12 == NULL) { - return FALSE; - } - FID_Button13 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_13", - FD_ButtonIdentifier); - if (FID_Button13 == NULL) { - return FALSE; - } - FID_Button14 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_14", - FD_ButtonIdentifier); - if (FID_Button14 == NULL) { - return FALSE; - } - FID_Button15 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_15", - FD_ButtonIdentifier); - if (FID_Button15 == NULL) { - return FALSE; - } - FID_Button16 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_16", - FD_ButtonIdentifier); - if (FID_Button16 == NULL) { - return FALSE; - } - FID_Button17 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_17", - FD_ButtonIdentifier); - if (FID_Button17 == NULL) { - return FALSE; - } - FID_Button18 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_18", - FD_ButtonIdentifier); - if (FID_Button18 == NULL) { - return FALSE; - } - FID_Button19 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_19", - FD_ButtonIdentifier); - if (FID_Button19 == NULL) { - return FALSE; - } - FID_Button20 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_20", - FD_ButtonIdentifier); - if (FID_Button20 == NULL) { - return FALSE; - } - FID_Button21 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_21", - FD_ButtonIdentifier); - if (FID_Button21 == NULL) { - return FALSE; - } - FID_Button22 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_22", - FD_ButtonIdentifier); - if (FID_Button22 == NULL) { - return FALSE; - } - FID_Button23 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_23", - FD_ButtonIdentifier); - if (FID_Button23 == NULL) { - return FALSE; - } - FID_Button24 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_24", - FD_ButtonIdentifier); - if (FID_Button24 == NULL) { - return FALSE; - } - FID_Button25 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_25", - FD_ButtonIdentifier); - if (FID_Button25 == NULL) { - return FALSE; - } - FID_Button26 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_26", - FD_ButtonIdentifier); - if (FID_Button26 == NULL) { - return FALSE; - } - FID_Button27 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_27", - FD_ButtonIdentifier); - if (FID_Button27 == NULL) { - return FALSE; - } - FID_Button28 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_28", - FD_ButtonIdentifier); - if (FID_Button28 == NULL) { - return FALSE; - } - FID_Button29 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_29", - FD_ButtonIdentifier); - if (FID_Button29 == NULL) { - return FALSE; - } - FID_Button30 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_30", - FD_ButtonIdentifier); - if (FID_Button30 == NULL) { - return FALSE; - } - FID_Button31 = env->GetStaticFieldID(CLASS_ButtonIdentifier, "_31", - FD_ButtonIdentifier); - if (FID_Button31 == NULL) { - return FALSE; - } - FID_POV = env->GetStaticFieldID(CLASS_AxisIdentifier, "POV", - FD_AxisIdentifier); - if (FID_POV == NULL) { - return FALSE; - } - FID_Left = env->GetStaticFieldID(CLASS_ButtonIdentifier, "LEFT", - FD_ButtonIdentifier); - if (FID_Left == NULL) { - return FALSE; - } - FID_Right = env->GetStaticFieldID(CLASS_ButtonIdentifier, "RIGHT", - FD_ButtonIdentifier); - if (FID_Right == NULL) { - return FALSE; - } - FID_Middle = env->GetStaticFieldID(CLASS_ButtonIdentifier, "MIDDLE", - FD_ButtonIdentifier); - if (FID_Middle == NULL) { - return FALSE; - } -// Endolf - FID_Side = env->GetStaticFieldID(CLASS_ButtonIdentifier, "SIDE", - FD_ButtonIdentifier); - if (FID_Side == NULL) { - return FALSE; - } - FID_Extra = env->GetStaticFieldID(CLASS_ButtonIdentifier, "EXTRA", - FD_ButtonIdentifier); - if (FID_Extra == NULL) { - return FALSE; - } - FID_Forward = env->GetStaticFieldID(CLASS_ButtonIdentifier, "FORWARD", - FD_ButtonIdentifier); - if (FID_Forward == NULL) { - return FALSE; - } - FID_Back = env->GetStaticFieldID(CLASS_ButtonIdentifier, "BACK", - FD_ButtonIdentifier); - if (FID_Back == NULL) { - return FALSE; - } - - CLASS_DirectInputEnvironmentPlugin = - env->FindClass("net/java/games/input/DirectInputEnvironmentPlugin"); - if (CLASS_DirectInputEnvironmentPlugin == NULL) { - return FALSE; - } - MID_AddDevice = env->GetMethodID(CLASS_DirectInputEnvironmentPlugin, "addDevice", - "(Ljava/util/ArrayList;JILjava/lang/String;Ljava/lang/String;Z)V"); - if (MID_AddDevice == NULL) { - return FALSE; - } - CLASS_DirectInputDevice = - env->FindClass("net/java/games/input/DirectInputDevice"); - if (CLASS_DirectInputDevice == NULL) { - return FALSE; - } - MID_AddAxis = env->GetMethodID(CLASS_DirectInputDevice, "addAxis", - "(Ljava/util/ArrayList;Lnet/java/games/input/Component$Identifier;ILjava/lang/String;)V"); - if (MID_AddAxis == NULL) { - return FALSE; - } - MID_AddRumbler = env->GetMethodID(CLASS_DirectInputDevice, "addRumbler", - "(JLnet/java/games/input/Component$Identifier;Ljava/lang/String;)V"); - if (MID_AddRumbler == NULL) { - return FALSE; - } - CLASS_DirectInputKeyboard = - env->FindClass("net/java/games/input/DirectInputKeyboard"); - if (CLASS_DirectInputKeyboard == NULL) { - return FALSE; - } - MID_RenameKey = env->GetMethodID(CLASS_DirectInputKeyboard, "renameKey", - "(ILjava/lang/String;)V"); - if (MID_RenameKey == NULL) { - return FALSE; - } - CLASS_DirectInputMouse = - env->FindClass("net/java/games/input/DirectInputMouse"); - if (CLASS_DirectInputMouse == NULL) { - return FALSE; - } - MID_RenameAxis = env->GetMethodID(CLASS_DirectInputMouse, "renameAxis", - "(Lnet/java/games/input/Component$Identifier;Ljava/lang/String;)V"); - if (MID_RenameAxis == NULL) { - return FALSE; - } - return TRUE; -} - -/* - * WndProc for our dummy input window - */ -LRESULT CALLBACK DummyWndProc( - HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - return DefWindowProc(hWnd, message, wParam, lParam); -} - -/* - * Register the dummy input window class - */ -BOOL RegisterDummyWindow(HINSTANCE hInstance) -{ - WNDCLASSEX wcex; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = (WNDPROC)DummyWndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = NULL; - wcex.hCursor = NULL; - wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wcex.lpszMenuName = (LPCSTR)NULL; - wcex.lpszClassName = DUMMY_WINDOW_NAME; - wcex.hIconSm = NULL; - return RegisterClassEx(&wcex); -} - -// Callback for finding out what effects a device supports -BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, - LPVOID pvRef) -{ - if(DIEFT_GETTYPE(pdei->dwEffType)==DIEFT_CONSTANTFORCE) { - printf("Constant force "); - } else if(DIEFT_GETTYPE(pdei->dwEffType)==DIEFT_RAMPFORCE){ - printf("Ramp force "); - } else if(DIEFT_GETTYPE(pdei->dwEffType)==DIEFT_PERIODIC ){ - printf("Periodic force "); - } else if(DIEFT_GETTYPE(pdei->dwEffType)==DIEFT_CONDITION ){ - printf("Condition force "); - } else if(DIEFT_GETTYPE(pdei->dwEffType)==DIEFT_CUSTOMFORCE ){ - printf("Custom force "); - } else if(DIEFT_GETTYPE(pdei->dwEffType)==DIEFT_HARDWARE ){ - printf("Hardware force "); - } - return DIENUM_CONTINUE; // one is enough -} - -/* - * Class: org_java_games_input_DirectInputEnvironmentPlugin - * Method: directInputCreate - * Signature: ()J - */ -extern "C" JNIEXPORT jlong JNICALL -Java_net_java_games_input_DirectInputEnvironmentPlugin_directInputCreate - (JNIEnv* env, jobject obj) -{ - // Get our module handle - HINSTANCE hInst = GetModuleHandle(NULL); - - // Register the dummy input window - if (!RegisterDummyWindow(hInst)) { - return (jlong)0; - } - - // Create the dummy input window - hwndDummy = CreateWindow(DUMMY_WINDOW_NAME, NULL, - WS_POPUP | WS_ICONIC, - 0, 0, 0, 0, NULL, NULL, hInst, NULL); - if (hwndDummy == NULL) - { - return (jlong)0; - } - - // Create the IDirectInput object - DWORD dwVersion = DIRECTINPUT_VERSION; - LPDIRECTINPUT8 lpDirectInput = NULL; - HRESULT res; - if (FAILED(res = DirectInput8Create(hInst, DIRECTINPUT_VERSION, - IID_IDirectInput8,(VOID **)&lpDirectInput, NULL))){ - PrintDIError("DirectInputCreate", res); - return (jlong)0; - } - - // Initialize method, class, and field IDs - if (!InitIDs(env)) { - lpDirectInput->Release(); - return (jlong)0; - } - - return (jlong)(long)lpDirectInput; -} - -BOOL CALLBACK CountFFAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, - VOID* pContext ) -{ - DWORD* pdwNumForceFeedbackAxis = (DWORD*) pContext; - - if( (pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0 ) { - //printf("%s is ff enabled\n", pdidoi->tszName); - (*pdwNumForceFeedbackAxis)++; - } - - return DIENUM_CONTINUE; -} - -/* - * Enumeration callback for devices - * - * returns DIENUM_CONTINUE or DIENUM_STOP - */ - -/** jeff's new enum callback */ -BOOL CALLBACK EnumDeviceCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - DeviceParamData* pData = (DeviceParamData*)pvRef; - LPDIRECTINPUT8 lpDirectInput = pData->lpDirectInput; - JNIEnv* env = pData->env; - jobject obj = pData->obj; - jobject list = pData->list; - LPDIRECTINPUTDEVICE8 lpDevice = NULL; - LPUNKNOWN pUnknown = NULL; - HRESULT res; - - // Create the device object - if (FAILED(res = lpDirectInput->CreateDevice(lpddi->guidInstance, &lpDevice, - pUnknown))){ - PrintDIError("CreateDevice", res); - return DIENUM_STOP; - } - - /* - LPDIRECTINPUTDEVICE8 lpDevice2 = NULL; - // Get the IDirectDrawDevice8 interface from the object - res = lpDevice->QueryInterface(IID_IDirectInputDevice8, - (void**)&lpDevice2); - if (res != DI_OK) { - PrintDIError("QueryInterface DID2", res); - lpDevice->Release(); - return DIENUM_STOP; - } - */ - - //find out if this device is ff enabled - DWORD numForceFeedbackAxis = 0; - res = lpDevice->EnumObjects( CountFFAxesCallback, - (VOID*)&numForceFeedbackAxis, DIDFT_AXIS ); - if(FAILED(res)) { - PrintDIError("getting ff devices", res); - } - - // Set the data format - LPCDIDATAFORMAT lpDataFormat; - DWORD category = GET_DIDEVICE_TYPE(lpddi->dwDevType)&0xFF; - switch (category){ - case DI8DEVTYPE_KEYBOARD: - //printf("found Keyboard\n"); - lpDataFormat = &c_dfDIKeyboard; - break; - case DI8DEVTYPE_MOUSE: - //printf("found mouse\n"); - lpDataFormat = &c_dfDIMouse2; - // set up buffering - DIPROPDWORD dipropdw; - dipropdw.diph.dwSize = sizeof(DIPROPDWORD); - dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipropdw.diph.dwObj = 0; - dipropdw.diph.dwHow = DIPH_DEVICE; - dipropdw.dwData = MOUSE_BUFFER_SIZE; - if (FAILED( - res = lpDevice->SetProperty(DIPROP_BUFFERSIZE, - &dipropdw.diph))) { - PrintDIError("SetProperty", res); - lpDevice->Release(); - return DIENUM_STOP; - } - break; - case DI8DEVTYPE_JOYSTICK: - default: - //printf("found stick\n"); - lpDataFormat = &c_dfDIJoystick; - break; - } - - if (FAILED(res = lpDevice->SetDataFormat(lpDataFormat))){ - PrintDIError("SetDataFormat", res); - lpDevice->Release(); - return DIENUM_STOP; - } - - if(numForceFeedbackAxis>0) { - // Set the cooperative level - if(FAILED(res = lpDevice->SetCooperativeLevel(hwndDummy, - DISCL_EXCLUSIVE | DISCL_BACKGROUND))){ - PrintDIError("SetCooperativeLevel", res); - lpDevice->Release(); - return DIENUM_STOP; - } - } else { - // Set the cooperative level - if(FAILED(res = lpDevice->SetCooperativeLevel(hwndDummy, - DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))){ - PrintDIError("SetCooperativeLevel", res); - lpDevice->Release(); - return DIENUM_STOP; - } - } - - // get polling - DIDEVCAPS didc; - // Allocate space for all the device's objects (axes, buttons, POVS) - ZeroMemory( &didc, sizeof(DIDEVCAPS) ); - didc.dwSize = sizeof(DIDEVCAPS); - if (FAILED(res=lpDevice->GetCapabilities(&didc))){ - PrintDIError("Get Device Capabilities", res); - lpDevice->Release(); - return DIENUM_STOP; - } - jboolean polled = JNI_FALSE; - if ((didc.dwFlags)&DIDC_POLLEDDATAFORMAT) { - polled = JNI_TRUE; - } - - // Acquire the device - if(FAILED(res = lpDevice->Acquire())){ - PrintDIError("Acquire", res); - lpDevice->Release(); - return DIENUM_STOP; - } - - // Set the variables for the Java callback - jint type = (jint)lpddi->dwDevType&0xffff; - //printf("type == %x\n",type); - jstring productName = env->NewStringUTF(lpddi->tszProductName); - if (productName == NULL) { - lpDevice->Release(); - return DIENUM_STOP; - } - jstring instanceName = env->NewStringUTF(lpddi->tszInstanceName); - if (instanceName == NULL) { - lpDevice->Release(); - return DIENUM_STOP; - } - - // Add the device into the list - env->CallVoidMethod(obj, MID_AddDevice, list, (jlong)(long)lpDevice, type, - productName, instanceName,(jboolean)polled); - return DIENUM_CONTINUE; -} - -/* - * Class: org_java_games_input_DirectInputEnvironmentPlugin - * Method: enumDevices - * Signature: (JLjava/util/ArrayList;)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputEnvironmentPlugin_enumDevices - (JNIEnv* env, jobject obj, jlong lDirectInput, jobject list) -{ - LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(long)lDirectInput; - DWORD dwDevType = DI8DEVCLASS_ALL; - DeviceParamData data(lpDirectInput, env, obj, list); - LPVOID pvRef = (LPVOID)&data; - DWORD dwFlags = DIEDFL_ATTACHEDONLY; - HRESULT res; - if(FAILED(res=lpDirectInput->EnumDevices(dwDevType, - EnumDeviceCallback, pvRef, dwFlags))){ - PrintDIError("EnumDevices", res); - return JNI_FALSE; - } - return JNI_TRUE; -} - -/* - ****************************************************************************** - * DirectInputDevice - ****************************************************************************** - */ - -/* - * Class: org_java_games_input_DirectInputDevice - * Method: pollNative - * Signature: (J[B)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputDevice_pollNative - (JNIEnv* env, jobject obj, jlong lDevice, jintArray baData, - jboolean pollme) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - // Reacquire the device - HRESULT res = lpDevice->Acquire(); - if (res != DI_OK && res != S_FALSE) { - PrintDIError("Acquire", res); - return JNI_FALSE; - } - // Poll the device - if (pollme == JNI_TRUE) { - res = lpDevice->Poll(); - // Changed this to FAILED(res) instead of res != DI_OK as it was - // causeing problems and the dx samples check for FAILED too. - if ( FAILED(res) ) { - PrintDIError("Poll", res); - return JNI_FALSE; - } - } - // Get the device state (data) - DIJOYSTATE data; - res = lpDevice->GetDeviceState(sizeof(data), &data); - if (res != DI_OK) { - PrintDIError("GetDeviceState", res); - return JNI_FALSE; - } - // Copy the data into the byte array - env->SetIntArrayRegion(baData, 0, (jsize)(sizeof(data)/4), (jint*)&data); - return JNI_TRUE; -} - -/* - * Enumeration callback for device objects - * - * returns DIENUM_CONTINUE or DIENUM_STOP - */ -BOOL CALLBACK EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef) -{ - ObjectParamData* pData = (ObjectParamData*)pvRef; - LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice; - JNIEnv* env = pData->env; - jobject obj = pData->obj; - jobject list = pData->list; - jobject identifier = NULL; - char ffEnabled = 0; - - HRESULT res; - if (lpddoi->guidType == GUID_XAxis) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_X); - } else if (lpddoi->guidType == GUID_YAxis) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Y); - } else if (lpddoi->guidType == GUID_ZAxis) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Z); - } else if (lpddoi->guidType == GUID_RxAxis) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RX); - } else if (lpddoi->guidType == GUID_RyAxis) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RY); - } else if (lpddoi->guidType == GUID_RzAxis) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RZ); - } else if (lpddoi->guidType == GUID_Slider) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Slider); - } else if (lpddoi->guidType == GUID_POV) { - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_POV); - } else if (lpddoi->guidType == GUID_Button) { - // Not sure why I have to add 15 here, but I do - switch (lpddoi->dwOfs+15) { - case DIJOFS_BUTTON0: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button0); - break; - case DIJOFS_BUTTON1: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button1); - break; - case DIJOFS_BUTTON2: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button2); - break; - case DIJOFS_BUTTON3: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button3); - break; - case DIJOFS_BUTTON4: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button4); - break; - case DIJOFS_BUTTON5: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button5); - break; - case DIJOFS_BUTTON6: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button6); - break; - case DIJOFS_BUTTON7: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button7); - break; - case DIJOFS_BUTTON8: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button8); - break; - case DIJOFS_BUTTON9: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button9); - break; - case DIJOFS_BUTTON10: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button10); - break; - case DIJOFS_BUTTON11: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button11); - break; - case DIJOFS_BUTTON12: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button12); - break; - case DIJOFS_BUTTON13: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button13); - break; - case DIJOFS_BUTTON14: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button14); - break; - case DIJOFS_BUTTON15: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button15); - break; - case DIJOFS_BUTTON16: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button16); - break; - case DIJOFS_BUTTON17: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button17); - break; - case DIJOFS_BUTTON18: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button18); - break; - case DIJOFS_BUTTON19: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button19); - break; - case DIJOFS_BUTTON20: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button20); - break; - case DIJOFS_BUTTON21: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button21); - break; - case DIJOFS_BUTTON22: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button22); - break; - case DIJOFS_BUTTON23: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button23); - break; - case DIJOFS_BUTTON24: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button24); - break; - case DIJOFS_BUTTON25: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button25); - break; - case DIJOFS_BUTTON26: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button26); - break; - case DIJOFS_BUTTON27: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button27); - break; - case DIJOFS_BUTTON28: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button28); - break; - case DIJOFS_BUTTON29: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button29); - break; - case DIJOFS_BUTTON30: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button30); - break; - case DIJOFS_BUTTON31: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Button31); - break; - default: - identifier = identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_UnknownButton); - } - } else { - return DIENUM_CONTINUE; - } - - if (identifier == NULL) { - return DIENUM_STOP; - } - if (DIDFT_GETTYPE(lpddoi->dwType)&DIDFT_AXIS){ - // set axis range - DIPROPRANGE joy_axis_range; - joy_axis_range.lMin = -32768; - joy_axis_range.lMax = 32768; - joy_axis_range.diph.dwSize=sizeof(DIPROPRANGE); - joy_axis_range.diph.dwHeaderSize=sizeof(DIPROPHEADER); - joy_axis_range.diph.dwHow = DIPH_BYID; - joy_axis_range.diph.dwObj=lpddoi->dwType; - if (FAILED( - res=lpDevice->SetProperty(DIPROP_RANGE,&joy_axis_range.diph))){ - PrintDIError("SetProperty", res); - } - - //check if this axis is ff enabled - if( (lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 ) { - //printf("%s is ff enabled\n", lpddoi->tszName); - ffEnabled = 1; - } - } - - jint didft = (jint)lpddoi->dwType; - jstring name = env->NewStringUTF(lpddoi->tszName); - // Add the axis into our list - env->CallVoidMethod(obj, MID_AddAxis, list, identifier, didft, - name); - - if(ffEnabled) { - - HRESULT hr; - GUID guidEffect; - printf("Supported effects: "); - hr = lpDevice->EnumEffects( - (LPDIENUMEFFECTSCALLBACK) DIEnumEffectsCallback, - &guidEffect, - DIEFT_ALL); - if (FAILED(hr)) - { - // Note that success does not mean that any effects were found, - // only that the process went smoothly. - } - printf("\n"); - - // This application needs only one effect: Applying raw forces. - DWORD rgdwAxes; - LONG rglDirection = 0; - if(lpddoi->guidType == GUID_XAxis) { - printf("effect is in the x axis\n"); - rgdwAxes = DIJOFS_X; - } else if(lpddoi->guidType == GUID_YAxis) { - printf("effect is in the y axis\n"); - rgdwAxes = DIJOFS_Y; - } else if(lpddoi->guidType == GUID_ZAxis) { - printf("effect is in the z axis\n"); - rgdwAxes = DIJOFS_Z; - } else if (lpddoi->guidType == GUID_RxAxis) { - printf("effect is in the rx axis\n"); - rgdwAxes = DIJOFS_RX; - } else if (lpddoi->guidType == GUID_RyAxis) { - printf("effect is in the ry axis\n"); - rgdwAxes = DIJOFS_RY; - } else if (lpddoi->guidType == GUID_RzAxis) { - printf("effect is in the rz axis\n"); - rgdwAxes = DIJOFS_RZ; - } else if (lpddoi->guidType == GUID_Slider) { - printf("effect is in the slider axis\n"); - rgdwAxes = DIJOFS_SLIDER(0); - } else if (lpddoi->guidType == GUID_Button) { - printf("effect is in the button axis\n"); - rgdwAxes = DIJOFS_BUTTON0; - } else if (lpddoi->guidType == GUID_POV) { - printf("effect is in the pov axis\n"); - rgdwAxes = DIJOFS_POV(0); - } else { - printf("effect is in an unknown axis\n"); - } - - DICONSTANTFORCE cf = { DI_FFNOMINALMAX }; - - DIEFFECT eff; - ZeroMemory( &eff, sizeof(eff) ); - eff.dwSize = sizeof(DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - eff.dwDuration = INFINITE; - eff.dwSamplePeriod = 0; - eff.dwGain = DI_FFNOMINALMAX; - eff.dwTriggerButton = DIEB_NOTRIGGER; - eff.dwTriggerRepeatInterval = 0; - eff.cAxes = 1; - eff.rgdwAxes = &rgdwAxes; - eff.rglDirection = &rglDirection; - eff.lpEnvelope = 0; - eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - eff.lpvTypeSpecificParams = &cf; - eff.dwStartDelay = 0; - cf.lMagnitude = (long) (0); - - LPDIRECTINPUTEFFECT g_pEffect; - // Create the prepared effect - if( FAILED( res = lpDevice->CreateEffect( GUID_ConstantForce, - &eff, &g_pEffect, NULL ) ) ) - { - PrintDIError("Create effect", res); - return res; - } - - env->CallVoidMethod(obj, MID_AddRumbler, (jlong)(long)g_pEffect, identifier, name); - } - return DIENUM_CONTINUE; -} - -/* - * Class: org_java_games_input_DirectInputRumbler - * Method setRumble - * Signature (JF)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputRumbler_setRumble - (JNIEnv *env, jobject obj, jlong effect, jfloat value) -{ - LPDIRECTINPUTEFFECT g_pEffect = (LPDIRECTINPUTEFFECT)(long)effect; - float force = (float)value; - HRESULT hr; - - DICONSTANTFORCE cf = { DI_FFNOMINALMAX }; - - DIEFFECT eff; - ZeroMemory( &eff, sizeof(eff) ); - eff.dwSize = sizeof(DIEFFECT); - eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - eff.lpvTypeSpecificParams = &cf; - cf.lMagnitude = (long) (((float)DI_FFNOMINALMAX)*force); - - //printf("force: %f, mag: %d\n", force, cf.lMagnitude); - - hr = g_pEffect->SetParameters( &eff, DIEP_TYPESPECIFICPARAMS ); - if (FAILED(hr)) { - PrintDIError("set parameters", hr); - return hr; - } - - if(force!=0) { - hr = g_pEffect->Start(1,0); - if (FAILED(hr)) { - PrintDIError("start", hr); - return hr; - } - } else { - hr = g_pEffect->Stop(); - if (FAILED(hr)) { - PrintDIError("stop", hr); - return hr; - } - } -} - -/* - * Class: org_java_games_input_DirectInputDevice - * Method: enumObjects - * Signature: (JLjava/util/ArrayList;)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputDevice_enumObjects - (JNIEnv* env, jobject obj, jlong lDevice, jobject list) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - ObjectParamData data(lpDevice, env, obj, list); - LPVOID pvRef = (LPVOID)&data; - DWORD dwFlags = DIDFT_ALL; - // Enum objects - HRESULT res = lpDevice->EnumObjects(EnumObjectsCallback, pvRef, dwFlags); - if (res != DI_OK) { - PrintDIError("EnumObjects", res); - return JNI_FALSE; - } - return JNI_TRUE; -} - -/* - ****************************************************************************** - * DirectInputKeyboard - ****************************************************************************** - */ - -/* - * Class: org_java_games_input_DirectInputKeyboard - * Method: pollNative - * Signature: (J[B)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputKeyboard_pollNative - (JNIEnv* env, jobject obj, jlong lDevice, jbyteArray baData) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - // Reacquire the device - HRESULT res = lpDevice->Acquire(); - if (res != DI_OK && res != S_FALSE) { - PrintDIError("Acquire", res); - return JNI_FALSE; - } - // Get the device state (data) - char data[256]; - res = lpDevice->GetDeviceState(sizeof(data), data); - if (res != DI_OK) { - PrintDIError("GetDeviceState", res); - return JNI_FALSE; - } - env->SetByteArrayRegion(baData, 0, (jsize)sizeof(data), (jbyte*)&data); - return JNI_TRUE; -} - -/* - * Enumeration callback to rename keyboard keys - * - * returns DIENUM_CONTINUE or DIENUM_STOP - */ -BOOL CALLBACK RenameKeysCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef) -{ - ObjectParamData* pData = (ObjectParamData*)pvRef; - //LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice; - JNIEnv* env = pData->env; - jobject obj = pData->obj; - jint index = (jint)lpddoi->dwOfs; - jstring name = env->NewStringUTF(lpddoi->tszName); - env->CallVoidMethod(obj, MID_RenameKey, index, name); - return DIENUM_CONTINUE; -} - -/* - * Class: org_java_games_input_DirectInputKeyboard - * Method: renameKeys - * Signature: (J)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputKeyboard_renameKeys - (JNIEnv* env, jobject obj, jlong lDevice) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - ObjectParamData data(lpDevice, env, obj, NULL); - LPVOID pvRef = (LPVOID)&data; - DWORD dwFlags = DIDFT_ALL; - // Enum objects - HRESULT res = lpDevice->EnumObjects(RenameKeysCallback, pvRef, dwFlags); - if (res != DI_OK) { - PrintDIError("EnumObjects", res); - return JNI_FALSE; - } - return JNI_TRUE; -} - -/* - ****************************************************************************** - * DirectInputMouse - ****************************************************************************** - */ - -/* - * Class: org_java_games_input_DirectInputMouse - * Method: getNumAxes - * Signature: (J)I - */ -extern "C" JNIEXPORT jint JNICALL -Java_net_java_games_input_DirectInputMouse_getNumAxes - (JNIEnv* env, jobject obj, jlong lDevice) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - // Reacquire the device - HRESULT res = lpDevice->Acquire(); - if (res != DI_OK && res != S_FALSE) { - PrintDIError("Acquire", res); - return 0; - } - DIDEVCAPS deviceCaps; - // Allocate space for all the device's objects (axes, buttons, POVS) - ZeroMemory( &deviceCaps, sizeof(DIDEVCAPS) ); - deviceCaps.dwSize = sizeof(DIDEVCAPS); - res = lpDevice->GetCapabilities(&deviceCaps); - if(res != DI_OK) { - PrintDIError("GetCapabilities", res); - return JNI_FALSE; - } - return deviceCaps.dwAxes; -} - -/* - * Class: org_java_games_input_DirectInputMouse - * Method: getNumButtons - * Signature: (J)I - */ -extern "C" JNIEXPORT jint JNICALL -Java_net_java_games_input_DirectInputMouse_getNumButtons - (JNIEnv* env, jobject obj, jlong lDevice) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - // Reacquire the device - HRESULT res = lpDevice->Acquire(); - if (res != DI_OK && res != S_FALSE) { - PrintDIError("Acquire", res); - return 0; - } - DIDEVCAPS deviceCaps; - // Allocate space for all the device's objects (axes, buttons, POVS) - ZeroMemory( &deviceCaps, sizeof(DIDEVCAPS) ); - deviceCaps.dwSize = sizeof(DIDEVCAPS); - res = lpDevice->GetCapabilities(&deviceCaps); - if(res != DI_OK) { - PrintDIError("GetCapabilities", res); - return JNI_FALSE; - } - return deviceCaps.dwButtons; -} - -/* - * Class: org_java_games_input_DirectInputMouse - * Method: pollNative - * Signature: (J[B)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputMouse_pollNative - (JNIEnv* env, jobject obj, jlong lDevice, jbyteArray baData) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - // Reacquire the device - HRESULT res = lpDevice->Acquire(); - if (res != DI_OK && res != S_FALSE) { - PrintDIError("Acquire", res); - return JNI_FALSE; - } - // Get the data - DIMOUSESTATE2 data; - res = lpDevice->GetDeviceState(sizeof(data), &data); - if (res != DI_OK) { - PrintDIError("GetDeviceState", res); - return JNI_FALSE; - } - - // Endolf woz here - // Set the axis data to 0, we only want the buttons for this second - data.lX = 0; - data.lY = 0; - data.lZ = 0; - - DIDEVICEOBJECTDATA dataBuffer[MOUSE_BUFFER_SIZE]; - DWORD numEvents = MOUSE_BUFFER_SIZE; - HRESULT res2 = lpDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), dataBuffer, &numEvents, 0); - switch(res2) { - case DIERR_INPUTLOST: - printf("DIERR_INPUTLOST\n"); - break; - case DIERR_INVALIDPARAM: - printf("DIERR_INVALIDPARAM\n"); - break; - case DIERR_NOTACQUIRED: - printf("DIERR_NOTACQUIRED\n"); - break; - case DIERR_NOTBUFFERED: - printf("DIERR_NOTBUFFERED\n"); - break; - case DIERR_NOTINITIALIZED: - printf("DIERR_NOTINITIALIZED\n"); - break; - case DI_BUFFEROVERFLOW: - printf("DI_BUFFEROVERFLOW\n"); - break; - } - int i=0; - for(i=0;i<numEvents;i++) { - switch(dataBuffer[i].dwOfs) { - case DIMOFS_BUTTON0: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[0] = 0x80; - } - break; - case DIMOFS_BUTTON1: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[1] = 0x80; - } - break; - case DIMOFS_BUTTON2: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[2] = 0x80; - } - break; - case DIMOFS_BUTTON3: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[3] = 0x80; - } - break; - case DIMOFS_BUTTON4: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[4] = 0x80; - } - break; - case DIMOFS_BUTTON5: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[5] = 0x80; - } - break; - case DIMOFS_BUTTON6: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[6] = 0x80; - } - break; - case DIMOFS_BUTTON7: - if(dataBuffer[i].dwData == 0x80) { - data.rgbButtons[7] = 0x80; - } - break; - case DIMOFS_X: - data.lX += dataBuffer[i].dwData; - break; - case DIMOFS_Y: - data.lY += dataBuffer[i].dwData; - break; - case DIMOFS_Z: - data.lZ += dataBuffer[i].dwData; - break; - default: - printf("Uknown data offset (%d)\n", dataBuffer[i].dwOfs); - } - } - - //printf("axis data in native at poll end is x: %d, y: %d, z: %d\n", data.lX, data.lY, data.lZ); - - // Set the data in our array - env->SetByteArrayRegion(baData, 0, (jsize)sizeof(data), (jbyte*)&data); - return JNI_TRUE; -} - -/* - * Enumeration callback to rename mouse axes - * - * returns DIENUM_CONTINUE or DIENUM_STOP - */ -BOOL CALLBACK RenameAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef) -{ - ObjectParamData* pData = (ObjectParamData*)pvRef; - //LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice; - JNIEnv* env = pData->env; - jobject obj = pData->obj; - jobject identifier; - switch (lpddoi->dwOfs) { - case DIMOFS_X: - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, - FID_X); - break; - case DIMOFS_Y: - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, - FID_Y); - break; - case DIMOFS_Z: - identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, - FID_Slider); - break; - case DIMOFS_BUTTON0: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Left); - break; - case DIMOFS_BUTTON1: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Right); - break; - case DIMOFS_BUTTON2: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Middle); - break; - case DIMOFS_BUTTON3: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Side); - break; - case DIMOFS_BUTTON4: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Extra); - break; - case DIMOFS_BUTTON5: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Forward); - break; - case DIMOFS_BUTTON6: - identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier, - FID_Back); - break; - default: - return DIENUM_CONTINUE; // Not an axis we know - } - jstring name = env->NewStringUTF(lpddoi->tszName); - env->CallVoidMethod(obj, MID_RenameAxis, identifier, name); - return DIENUM_CONTINUE; -} - -/* - * Class: org_java_games_input_DirectInputMouse - * Method: renameAxes - * Signature: (J)Z - */ -extern "C" JNIEXPORT jboolean JNICALL -Java_net_java_games_input_DirectInputMouse_renameAxes - (JNIEnv* env, jobject obj, jlong lDevice) -{ - LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice; - ObjectParamData data(lpDevice, env, obj, NULL); - LPVOID pvRef = (LPVOID)&data; - DWORD dwFlags = DIDFT_ALL; - // Enum objects - HRESULT res = lpDevice->EnumObjects(RenameAxesCallback, pvRef, dwFlags); - if (res != DI_OK) { - PrintDIError("EnumObjects", res); - return JNI_FALSE; - } - return JNI_TRUE; -} - - diff --git a/plugins/OSX/build.xml b/plugins/OSX/build.xml index 066c838..659f766 100644 --- a/plugins/OSX/build.xml +++ b/plugins/OSX/build.xml @@ -2,35 +2,37 @@ <project basedir="." default="all" name="OSX Plugin"> <description>OSX JInput Plugin</description> <property name="src" location="src" /> - <property name="build" location="classes" /> - <property name="dist" location="dist" /> + <property name="build" location="classes"/> + <property name="bin" location="bin" /> <property name="plugins" location="plugins" /> <target name="init"> - <mkdir dir="classes"/> - <mkdir dir="dist"/> + <mkdir dir="${build}"/> + <mkdir dir="${bin}"/> + <condition property="macosx"> + <and> + <os family="mac" /> + <os family="unix" /> + </and> + </condition> </target> <target depends="init" name="compile"> <javac debug="true" deprecation="true" destdir="${build}" source="1.4" srcdir="src/java"> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> - <pathelement location="../../coreAPI/lib/jutils.jar"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> </classpath> </javac> </target> <target depends="init,compile" name="jar"> - <jar jarfile="${dist}/HIDWrapper.jar" compress="true" basedir="${build}"> - <exclude name="**/*.java"/> - <exclude name="HIDWrapper.jar"/> - <exclude name="apidoc"/> + <jar jarfile="${bin}/HIDWrapper.jar" compress="true" basedir="${build}"> + <include name="**/*.class"/> </jar> - <copy file="${dist}/HIDWrapper.jar" todir="../../coreAPI/src/tests/controller" /> </target> <target depends="compileNativeJinputLib,jar" description="Build everything." name="all"> - <echo message="Native OSX JInput library built!"/> </target> <target name="javadoc" depends="init" description="Javadoc for OS X plugin for JInput."> @@ -43,23 +45,17 @@ <pathelement location="src/java"/> </sourcepath> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> - <pathelement location="../../coreAPI/lib/jutils.jar"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> </classpath> </javadoc> </target> <target description="Clean all build products." name="clean"> - <delete failonerror="no"> - <fileset dir="${build}"> - <include name="**/*.class"/> - </fileset> - </delete> - <delete file="${dist}/HIDWrapper.jar" failonerror="no"/> - <delete file="${dist}/libjinput.jnilib" failonerror="no"/> - <delete file="../../coreAPI/src/tests/controller/HIDWrapper.jar" failonerror="no" /> - <delete file="../../coreAPI/src/tests/controller/libjinput.jnilib" failonerror="no"/> - <delete file="apidoc" failonerror="no"/> + <delete dir="classes" failonerror="no"/> + <delete dir="bin" failonerror="no"/> + <delete dir="apidocs" failonerror="no"/> + <ant inheritAll="false" antfile="src/native/build.xml" target="clean"/> </target> <target depends="init,compile" name="createJNIHeaders"> @@ -68,14 +64,17 @@ <pathelement path="${build}"/> <pathelement location="../../coreAPI/classes"/> </classpath> - <class name="net.java.games.input.OSXEnvironmentPlugin"/> + <class name="net.java.games.input.OSXHIDDeviceIterator"/> + <class name="net.java.games.input.OSXHIDDevice"/> + <class name="net.java.games.input.OSXHIDQueue"/> </javah> </target> - <target name="compileNativeJinputLib" depends="init,createJNIHeaders" > + <target name="compileNativeJinputLib" depends="init,createJNIHeaders" if="macosx"> <ant dir="src/native" target="compileNativeJinputLib"/> - <copy file="src/native/libjinput.jnilib" todir="${dist}" /> - <copy file="${dist}/libjinput.jnilib" todir="../../coreAPI/src/tests/controller" /> + <copy todir="${bin}"> + <fileset dir="src/native" includes="*.jnilib"/> + </copy> </target> </project> diff --git a/plugins/OSX/src/java/net/java/games/input/ButtonUsage.java b/plugins/OSX/src/java/net/java/games/input/ButtonUsage.java new file mode 100644 index 0000000..d83dcb8 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/ButtonUsage.java @@ -0,0 +1,141 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.util.Map; +import java.util.HashMap; + +/** Button Usages +* @author elias +* @version 1.0 +*/ +final class ButtonUsage implements Usage { + private final static Map map = new HashMap(); + + private final int button_id; + + public final static ButtonUsage map(int button_id) { + Integer button_id_obj = new Integer(button_id); + ButtonUsage existing = (ButtonUsage)map.get(button_id_obj); + if (existing != null) + return existing; + ButtonUsage new_button = new ButtonUsage(button_id); + map.put(button_id_obj, new_button); + return new_button; + } + + private ButtonUsage(int button_id) { + this.button_id = button_id; + } + + public final Component.Identifier.Button getIdentifier() { + switch (button_id) { + case 1: + return Component.Identifier.Button._0; + case 2: + return Component.Identifier.Button._1; + case 3: + return Component.Identifier.Button._2; + case 4: + return Component.Identifier.Button._3; + case 5: + return Component.Identifier.Button._4; + case 6: + return Component.Identifier.Button._5; + case 7: + return Component.Identifier.Button._6; + case 8: + return Component.Identifier.Button._7; + case 9: + return Component.Identifier.Button._8; + case 10: + return Component.Identifier.Button._9; + case 11: + return Component.Identifier.Button._10; + case 12: + return Component.Identifier.Button._11; + case 13: + return Component.Identifier.Button._12; + case 14: + return Component.Identifier.Button._13; + case 15: + return Component.Identifier.Button._14; + case 16: + return Component.Identifier.Button._15; + case 17: + return Component.Identifier.Button._16; + case 18: + return Component.Identifier.Button._17; + case 19: + return Component.Identifier.Button._18; + case 20: + return Component.Identifier.Button._19; + case 21: + return Component.Identifier.Button._20; + case 22: + return Component.Identifier.Button._21; + case 23: + return Component.Identifier.Button._22; + case 24: + return Component.Identifier.Button._23; + case 25: + return Component.Identifier.Button._24; + case 26: + return Component.Identifier.Button._25; + case 27: + return Component.Identifier.Button._26; + case 28: + return Component.Identifier.Button._27; + case 29: + return Component.Identifier.Button._28; + case 30: + return Component.Identifier.Button._29; + case 31: + return Component.Identifier.Button._30; + case 32: + return Component.Identifier.Button._31; + default: + return null; + } + } + + public final String toString() { + return "ButtonUsage (" + button_id + ")"; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/ElementType.java b/plugins/OSX/src/java/net/java/games/input/ElementType.java new file mode 100644 index 0000000..efc303f --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/ElementType.java @@ -0,0 +1,74 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.lang.reflect.Method; + +/** HID Element types +* @author elias +* @version 1.0 +*/ +final class ElementType { + private final static ElementType[] map = new ElementType[514]; + + public final static ElementType INPUT_MISC = new ElementType(1); + public final static ElementType INPUT_BUTTON = new ElementType(2); + public final static ElementType INPUT_AXIS = new ElementType(3); + public final static ElementType INPUT_SCANCODES = new ElementType(4); + public final static ElementType OUTPUT = new ElementType(129); + public final static ElementType FEATURE = new ElementType(257); + public final static ElementType COLLECTION = new ElementType(513); + + private final int type_id; + + public final static ElementType map(int type_id) { + if (type_id < 0 || type_id >= map.length) + return null; + return map[type_id]; + } + + private ElementType(int type_id) { + map[type_id] = this; + this.type_id = type_id; + } + + public final String toString() { + return "ElementType (0x" + Integer.toHexString(type_id) + ")"; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/GenericDesktopUsage.java b/plugins/OSX/src/java/net/java/games/input/GenericDesktopUsage.java new file mode 100644 index 0000000..9b6d48b --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/GenericDesktopUsage.java @@ -0,0 +1,142 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +/** Generic Desktop Usages +* @author elias +* @version 1.0 +*/ +final class GenericDesktopUsage implements Usage { + private final static GenericDesktopUsage[] map = new GenericDesktopUsage[0xFF]; + + public final static GenericDesktopUsage POINTER = new GenericDesktopUsage(0x01); /* Physical Collection */ + public final static GenericDesktopUsage MOUSE = new GenericDesktopUsage(0x02); /* Application Collection */ + /* 0x03 Reserved */ + public final static GenericDesktopUsage JOYSTICK = new GenericDesktopUsage(0x04); /* Application Collection */ + public final static GenericDesktopUsage GAME_PAD = new GenericDesktopUsage(0x05); /* Application Collection */ + public final static GenericDesktopUsage KEYBOARD = new GenericDesktopUsage(0x06); /* Application Collection */ + public final static GenericDesktopUsage KEYPAD = new GenericDesktopUsage(0x07); /* Application Collection */ + public final static GenericDesktopUsage MULTI_AXIS_CONTROLLER = new GenericDesktopUsage(0x08); /* Application Collection */ + /* 0x09 - 0x2F Reserved */ + public final static GenericDesktopUsage X = new GenericDesktopUsage(0x30); /* Dynamic Value */ + public final static GenericDesktopUsage Y = new GenericDesktopUsage(0x31); /* Dynamic Value */ + public final static GenericDesktopUsage Z = new GenericDesktopUsage(0x32); /* Dynamic Value */ + public final static GenericDesktopUsage RX = new GenericDesktopUsage(0x33); /* Dynamic Value */ + public final static GenericDesktopUsage RY = new GenericDesktopUsage(0x34); /* Dynamic Value */ + public final static GenericDesktopUsage RZ = new GenericDesktopUsage(0x35); /* Dynamic Value */ + public final static GenericDesktopUsage SLIDER = new GenericDesktopUsage(0x36); /* Dynamic Value */ + public final static GenericDesktopUsage DIAL = new GenericDesktopUsage(0x37); /* Dynamic Value */ + public final static GenericDesktopUsage WHEEL = new GenericDesktopUsage(0x38); /* Dynamic Value */ + public final static GenericDesktopUsage HATSWITCH = new GenericDesktopUsage(0x39); /* Dynamic Value */ + public final static GenericDesktopUsage COUNTED_BUFFER = new GenericDesktopUsage(0x3A); /* Logical Collection */ + public final static GenericDesktopUsage BYTE_COUNT = new GenericDesktopUsage(0x3B); /* Dynamic Value */ + public final static GenericDesktopUsage MOTION_WAKEUP = new GenericDesktopUsage(0x3C); /* One-Shot Control */ + public final static GenericDesktopUsage START = new GenericDesktopUsage(0x3D); /* On/Off Control */ + public final static GenericDesktopUsage SELECT = new GenericDesktopUsage(0x3E); /* On/Off Control */ + /* 0x3F Reserved */ + public final static GenericDesktopUsage VX = new GenericDesktopUsage(0x40); /* Dynamic Value */ + public final static GenericDesktopUsage VY = new GenericDesktopUsage(0x41); /* Dynamic Value */ + public final static GenericDesktopUsage VZ = new GenericDesktopUsage(0x42); /* Dynamic Value */ + public final static GenericDesktopUsage VBRX = new GenericDesktopUsage(0x43); /* Dynamic Value */ + public final static GenericDesktopUsage VBRY = new GenericDesktopUsage(0x44); /* Dynamic Value */ + public final static GenericDesktopUsage VBRZ = new GenericDesktopUsage(0x45); /* Dynamic Value */ + public final static GenericDesktopUsage VNO = new GenericDesktopUsage(0x46); /* Dynamic Value */ + /* 0x47 - 0x7F Reserved */ + public final static GenericDesktopUsage SYSTEM_CONTROL = new GenericDesktopUsage(0x80); /* Application Collection */ + public final static GenericDesktopUsage SYSTEM_POWER_DOWN = new GenericDesktopUsage(0x81); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_SLEEP = new GenericDesktopUsage(0x82); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_WAKE_UP = new GenericDesktopUsage(0x83); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_CONTEXT_MENU = new GenericDesktopUsage(0x84); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_MAIN_MENU = new GenericDesktopUsage(0x85); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_APP_MENU = new GenericDesktopUsage(0x86); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_MENU_HELP = new GenericDesktopUsage(0x87); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_MENU_EXIT = new GenericDesktopUsage(0x88); /* One-Shot Control */ + public final static GenericDesktopUsage SYSTEM_MENU = new GenericDesktopUsage(0x89); /* Selector */ + public final static GenericDesktopUsage SYSTEM_MENU_RIGHT = new GenericDesktopUsage(0x8A); /* Re-Trigger Control */ + public final static GenericDesktopUsage SYSTEM_MENU_LEFT = new GenericDesktopUsage(0x8B); /* Re-Trigger Control */ + public final static GenericDesktopUsage SYSTEM_MENU_UP = new GenericDesktopUsage(0x8C); /* Re-Trigger Control */ + public final static GenericDesktopUsage SYSTEM_MENU_DOWN = new GenericDesktopUsage(0x8D); /* Re-Trigger Control */ + /* 0x8E - 0x8F Reserved */ + public final static GenericDesktopUsage DPAD_UP = new GenericDesktopUsage(0x90); /* On/Off Control */ + public final static GenericDesktopUsage DPAD_DOWN = new GenericDesktopUsage(0x91); /* On/Off Control */ + public final static GenericDesktopUsage DPAD_RIGHT = new GenericDesktopUsage(0x92); /* On/Off Control */ + public final static GenericDesktopUsage DPAD_LEFT = new GenericDesktopUsage(0x93); /* On/Off Control */ + /* 0x94 - 0xFFFF Reserved */ + + private final int usage_id; + + public final static GenericDesktopUsage map(int usage_id) { + if (usage_id < 0 || usage_id >= map.length) + return null; + return map[usage_id]; + } + + private GenericDesktopUsage(int usage_id) { + map[usage_id] = this; + this.usage_id = usage_id; + } + + public final String toString() { + return "GenericDesktopUsage (0x" + Integer.toHexString(usage_id) + ")"; + } + + public final Component.Identifier getIdentifier() { + if (this == GenericDesktopUsage.X) { + return Component.Identifier.Axis.X; + } else if (this == GenericDesktopUsage.Y) { + return Component.Identifier.Axis.Y; + } else if (this == GenericDesktopUsage.Z) { + return Component.Identifier.Axis.Z; + } else if (this == GenericDesktopUsage.RX) { + return Component.Identifier.Axis.RX; + } else if (this == GenericDesktopUsage.RY) { + return Component.Identifier.Axis.RY; + } else if (this == GenericDesktopUsage.RZ) { + return Component.Identifier.Axis.RZ; + } else if (this == GenericDesktopUsage.SLIDER) { + return Component.Identifier.Axis.SLIDER; + } else if (this == GenericDesktopUsage.HATSWITCH) { + return Component.Identifier.Axis.POV; + } else if (this == GenericDesktopUsage.SELECT) { + return Component.Identifier.Button.SELECT; + } else + return null; + } + +} diff --git a/plugins/OSX/src/java/net/java/games/input/InputController.java b/plugins/OSX/src/java/net/java/games/input/InputController.java deleted file mode 100644 index 2a5442b..0000000 --- a/plugins/OSX/src/java/net/java/games/input/InputController.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.java.games.input; - -/** - * Created by IntelliJ IDEA. - * User: gpierce - * Date: Aug 2, 2003 - * Time: 2:57:15 PM - * To change this template use Options | File Templates. - */ -public interface InputController -{ - public void addControllerElement( InputControllerElement element ); -} diff --git a/plugins/OSX/src/java/net/java/games/input/InputControllerElement.java b/plugins/OSX/src/java/net/java/games/input/InputControllerElement.java deleted file mode 100644 index 8ba92c3..0000000 --- a/plugins/OSX/src/java/net/java/games/input/InputControllerElement.java +++ /dev/null @@ -1,195 +0,0 @@ -package net.java.games.input; - -/** - * Created by IntelliJ IDEA. - * User: gpierce - * Date: Aug 2, 2003 - * Time: 2:59:26 PM - * To change this template use Options | File Templates. - */ -public class InputControllerElement -{ - private long hidCookie; - private int elementType; - private int usagePage; - private int usage; - - private int rawMin; - private int rawMax; - private int scaledMin; - private int scaledMax; - - private int dataBitSize; - - private boolean isRelative; - private boolean isWrapping; - private boolean isNonLinear; - private boolean hasPreferredState; - private boolean hasNullState; - - public InputControllerElement() - { - } - - public InputControllerElement(long hidCookie, int elementType, int usage, int usagePage, - int rawMin, int rawMax, int scaledMin, int scaledMax, - int dataBitSize, boolean isRelative, boolean isWrapping, - boolean isNonLinear, boolean hasPreferredState, boolean hasNullState ) - { - this.hidCookie = hidCookie; - this.elementType = elementType; - this.usage = usage; - this.usagePage = usagePage; - this.rawMin = rawMin; - this.rawMax = rawMax; - this.scaledMin = scaledMin; - this.scaledMax = scaledMax; - this.dataBitSize = dataBitSize; - this.isRelative = isRelative; - this.isWrapping = isWrapping; - this.isNonLinear = isNonLinear; - this.hasPreferredState = hasPreferredState; - this.hasNullState = hasNullState; - } - - public long getHidCookie() - { - return hidCookie; - } - - public void setHidCookie(long hidCookie) - { - this.hidCookie = hidCookie; - } - - public int getElementType() - { - return elementType; - } - - public void setElementType(int elementType) - { - this.elementType = elementType; - } - - public int getUsagePage() - { - return usagePage; - } - - public void setUsagePage(int usagePage) - { - this.usagePage = usagePage; - } - - public int getUsage() - { - return usage; - } - - public void setUsage(int usage) - { - this.usage = usage; - } - - public int getRawMin() - { - return rawMin; - } - - public void setRawMin(int rawMin) - { - this.rawMin = rawMin; - } - - public int getRawMax() - { - return rawMax; - } - - public void setRawMax(int rawMax) - { - this.rawMax = rawMax; - } - - public int getScaledMin() - { - return scaledMin; - } - - public void setScaledMin(int scaledMin) - { - this.scaledMin = scaledMin; - } - - public int getScaledMax() - { - return scaledMax; - } - - public void setScaledMax(int scaledMax) - { - this.scaledMax = scaledMax; - } - - public int getDataBitSize() - { - return dataBitSize; - } - - public void setDataBitSize(int dataBitSize) - { - this.dataBitSize = dataBitSize; - } - - public boolean isRelative() - { - return isRelative; - } - - public void setRelative(boolean relative) - { - isRelative = relative; - } - - public boolean isWrapping() - { - return isWrapping; - } - - public void setWrapping(boolean wrapping) - { - isWrapping = wrapping; - } - - public boolean isNonLinear() - { - return isNonLinear; - } - - public void setNonLinear(boolean nonLinear) - { - isNonLinear = nonLinear; - } - - public boolean isHasPreferredState() - { - return hasPreferredState; - } - - public void setHasPreferredState(boolean hasPreferredState) - { - this.hasPreferredState = hasPreferredState; - } - - public boolean isHasNullState() - { - return hasNullState; - } - - public void setHasNullState(boolean hasNullState) - { - this.hasNullState = hasNullState; - } - -} diff --git a/plugins/OSX/src/java/net/java/games/input/KeyboardUsage.java b/plugins/OSX/src/java/net/java/games/input/KeyboardUsage.java new file mode 100644 index 0000000..7621032 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/KeyboardUsage.java @@ -0,0 +1,251 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.util.Map; +import java.util.HashMap; + +/** Mapping from Keyboard HID usages to Component.Identifier.Key +* @author elias +* @version 1.0 +*/ +final class KeyboardUsage implements Usage { + private final static KeyboardUsage[] map = new KeyboardUsage[0xFF]; + + public static final KeyboardUsage ERRORROLLOVER = new KeyboardUsage(0x01); /* ErrorRollOver */ + public static final KeyboardUsage POSTFAIL = new KeyboardUsage(0x02); /* POSTFail */ + public static final KeyboardUsage ERRORUNDEFINED = new KeyboardUsage(0x03); /* ErrorUndefined */ + public static final KeyboardUsage A = new KeyboardUsage(Component.Identifier.Key.A, 0x04); /* a or A */ + public static final KeyboardUsage B = new KeyboardUsage(Component.Identifier.Key.B, 0x05); /* b or B */ + public static final KeyboardUsage C = new KeyboardUsage(Component.Identifier.Key.C, 0x06); /* c or C */ + public static final KeyboardUsage D = new KeyboardUsage(Component.Identifier.Key.D, 0x07); /* d or D */ + public static final KeyboardUsage E = new KeyboardUsage(Component.Identifier.Key.E, 0x08); /* e or E */ + public static final KeyboardUsage F = new KeyboardUsage(Component.Identifier.Key.F, 0x09); /* f or F */ + public static final KeyboardUsage G = new KeyboardUsage(Component.Identifier.Key.G, 0x0A); /* g or G */ + public static final KeyboardUsage H = new KeyboardUsage(Component.Identifier.Key.H, 0x0B); /* h or H */ + public static final KeyboardUsage I = new KeyboardUsage(Component.Identifier.Key.I, 0x0C); /* i or I */ + public static final KeyboardUsage J = new KeyboardUsage(Component.Identifier.Key.J, 0x0D); /* j or J */ + public static final KeyboardUsage K = new KeyboardUsage(Component.Identifier.Key.K, 0x0E); /* k or K */ + public static final KeyboardUsage L = new KeyboardUsage(Component.Identifier.Key.L, 0x0F); /* l or L */ + public static final KeyboardUsage M = new KeyboardUsage(Component.Identifier.Key.M, 0x10); /* m or M */ + public static final KeyboardUsage N = new KeyboardUsage(Component.Identifier.Key.N, 0x11); /* n or N */ + public static final KeyboardUsage O = new KeyboardUsage(Component.Identifier.Key.O, 0x12); /* o or O */ + public static final KeyboardUsage P = new KeyboardUsage(Component.Identifier.Key.P, 0x13); /* p or P */ + public static final KeyboardUsage Q = new KeyboardUsage(Component.Identifier.Key.Q, 0x14); /* q or Q */ + public static final KeyboardUsage R = new KeyboardUsage(Component.Identifier.Key.R, 0x15); /* r or R */ + public static final KeyboardUsage S = new KeyboardUsage(Component.Identifier.Key.S, 0x16); /* s or S */ + public static final KeyboardUsage T = new KeyboardUsage(Component.Identifier.Key.T, 0x17); /* t or T */ + public static final KeyboardUsage U = new KeyboardUsage(Component.Identifier.Key.U, 0x18); /* u or U */ + public static final KeyboardUsage V = new KeyboardUsage(Component.Identifier.Key.V, 0x19); /* v or V */ + public static final KeyboardUsage W = new KeyboardUsage(Component.Identifier.Key.W, 0x1A); /* w or W */ + public static final KeyboardUsage X = new KeyboardUsage(Component.Identifier.Key.X, 0x1B); /* x or X */ + public static final KeyboardUsage Y = new KeyboardUsage(Component.Identifier.Key.Y, 0x1C); /* y or Y */ + public static final KeyboardUsage Z = new KeyboardUsage(Component.Identifier.Key.Z, 0x1D); /* z or Z */ + public static final KeyboardUsage _1 = new KeyboardUsage(Component.Identifier.Key._1, 0x1E); /* 1 or ! */ + public static final KeyboardUsage _2 = new KeyboardUsage(Component.Identifier.Key._2, 0x1F); /* 2 or @ */ + public static final KeyboardUsage _3 = new KeyboardUsage(Component.Identifier.Key._3, 0x20); /* 3 or # */ + public static final KeyboardUsage _4 = new KeyboardUsage(Component.Identifier.Key._4, 0x21); /* 4 or $ */ + public static final KeyboardUsage _5 = new KeyboardUsage(Component.Identifier.Key._5, 0x22); /* 5 or % */ + public static final KeyboardUsage _6 = new KeyboardUsage(Component.Identifier.Key._6, 0x23); /* 6 or ^ */ + public static final KeyboardUsage _7 = new KeyboardUsage(Component.Identifier.Key._7, 0x24); /* 7 or & */ + public static final KeyboardUsage _8 = new KeyboardUsage(Component.Identifier.Key._8, 0x25); /* 8 or * */ + public static final KeyboardUsage _9 = new KeyboardUsage(Component.Identifier.Key._9, 0x26); /* 9 or ( */ + public static final KeyboardUsage _0 = new KeyboardUsage(Component.Identifier.Key._0, 0x27); /* 0 or ) */ + public static final KeyboardUsage ENTER = new KeyboardUsage(Component.Identifier.Key.RETURN, 0x28); /* Return (Enter) */ + public static final KeyboardUsage ESCAPE = new KeyboardUsage(Component.Identifier.Key.ESCAPE, 0x29); /* Escape */ + public static final KeyboardUsage BACKSPACE = new KeyboardUsage(Component.Identifier.Key.BACK, 0x2A); /* Delete (Backspace) */ + public static final KeyboardUsage TAB = new KeyboardUsage(Component.Identifier.Key.TAB, 0x2B); /* Tab */ + public static final KeyboardUsage SPACEBAR = new KeyboardUsage(Component.Identifier.Key.SPACE, 0x2C); /* Spacebar */ + public static final KeyboardUsage HYPHEN = new KeyboardUsage(Component.Identifier.Key.MINUS, 0x2D); /* - or _ */ + public static final KeyboardUsage EQUALSIGN = new KeyboardUsage(Component.Identifier.Key.EQUALS, 0x2E); /* = or + */ + public static final KeyboardUsage OPENBRACKET = new KeyboardUsage(Component.Identifier.Key.LBRACKET, 0x2F); /* [ or { */ + public static final KeyboardUsage CLOSEBRACKET = new KeyboardUsage(Component.Identifier.Key.RBRACKET, 0x30); /* ] or } */ + public static final KeyboardUsage BACKSLASH = new KeyboardUsage(Component.Identifier.Key.BACKSLASH, 0x31); /* \ or | */ + public static final KeyboardUsage NONUSPOUNT = new KeyboardUsage(Component.Identifier.Key.PERIOD, 0x32); /* Non-US # or _ */ + public static final KeyboardUsage SEMICOLON = new KeyboardUsage(Component.Identifier.Key.SEMICOLON, 0x33); /* ; or : */ + public static final KeyboardUsage QUOTE = new KeyboardUsage(Component.Identifier.Key.APOSTROPHE, 0x34); /* ' or " */ + public static final KeyboardUsage TILDE = new KeyboardUsage(Component.Identifier.Key.GRAVE, 0x35); /* Grave Accent and Tilde */ + public static final KeyboardUsage COMMA = new KeyboardUsage(Component.Identifier.Key.COMMA, 0x36); /* , or < */ + public static final KeyboardUsage PERIOD = new KeyboardUsage(Component.Identifier.Key.PERIOD, 0x37); /* . or > */ + public static final KeyboardUsage SLASH = new KeyboardUsage(Component.Identifier.Key.SLASH, 0x38); /* / or ? */ + public static final KeyboardUsage CAPSLOCK = new KeyboardUsage(Component.Identifier.Key.CAPITAL, 0x39); /* Caps Lock */ + public static final KeyboardUsage F1 = new KeyboardUsage(Component.Identifier.Key.F1, 0x3A); /* F1 */ + public static final KeyboardUsage F2 = new KeyboardUsage(Component.Identifier.Key.F2, 0x3B); /* F2 */ + public static final KeyboardUsage F3 = new KeyboardUsage(Component.Identifier.Key.F3, 0x3C); /* F3 */ + public static final KeyboardUsage F4 = new KeyboardUsage(Component.Identifier.Key.F4, 0x3D); /* F4 */ + public static final KeyboardUsage F5 = new KeyboardUsage(Component.Identifier.Key.F5, 0x3E); /* F5 */ + public static final KeyboardUsage F6 = new KeyboardUsage(Component.Identifier.Key.F6, 0x3F); /* F6 */ + public static final KeyboardUsage F7 = new KeyboardUsage(Component.Identifier.Key.F7, 0x40); /* F7 */ + public static final KeyboardUsage F8 = new KeyboardUsage(Component.Identifier.Key.F8, 0x41); /* F8 */ + public static final KeyboardUsage F9 = new KeyboardUsage(Component.Identifier.Key.F9, 0x42); /* F9 */ + public static final KeyboardUsage F10 = new KeyboardUsage(Component.Identifier.Key.F10, 0x43); /* F10 */ + public static final KeyboardUsage F11 = new KeyboardUsage(Component.Identifier.Key.F11, 0x44); /* F11 */ + public static final KeyboardUsage F12 = new KeyboardUsage(Component.Identifier.Key.F12, 0x45); /* F12 */ + public static final KeyboardUsage PRINTSCREEN = new KeyboardUsage(Component.Identifier.Key.SYSRQ, 0x46); /* PrintScreen */ + public static final KeyboardUsage SCROLLLOCK = new KeyboardUsage(Component.Identifier.Key.SCROLL, 0x47); /* Scroll Lock */ + public static final KeyboardUsage PAUSE = new KeyboardUsage(Component.Identifier.Key.PAUSE, 0x48); /* Pause */ + public static final KeyboardUsage INSERT = new KeyboardUsage(Component.Identifier.Key.INSERT, 0x49); /* Insert */ + public static final KeyboardUsage HOME = new KeyboardUsage(Component.Identifier.Key.HOME, 0x4A); /* Home */ + public static final KeyboardUsage PAGEUP = new KeyboardUsage(Component.Identifier.Key.PAGEUP, 0x4B); /* Page Up */ + public static final KeyboardUsage DELETE = new KeyboardUsage(Component.Identifier.Key.DELETE, 0x4C); /* Delete Forward */ + public static final KeyboardUsage END = new KeyboardUsage(Component.Identifier.Key.END, 0x4D); /* End */ + public static final KeyboardUsage PAGEDOWN = new KeyboardUsage(Component.Identifier.Key.PAGEDOWN, 0x4E); /* Page Down */ + public static final KeyboardUsage RIGHTARROW = new KeyboardUsage(Component.Identifier.Key.RIGHT, 0x4F); /* Right Arrow */ + public static final KeyboardUsage LEFTARROW = new KeyboardUsage(Component.Identifier.Key.LEFT, 0x50); /* Left Arrow */ + public static final KeyboardUsage DOWNARROW = new KeyboardUsage(Component.Identifier.Key.DOWN, 0x51); /* Down Arrow */ + public static final KeyboardUsage UPARROW = new KeyboardUsage(Component.Identifier.Key.UP, 0x52); /* Up Arrow */ + public static final KeyboardUsage KEYPAD_NUMLOCK = new KeyboardUsage(Component.Identifier.Key.NUMLOCK, 0x53); /* Keypad NumLock or Clear */ + public static final KeyboardUsage KEYPAD_SLASH = new KeyboardUsage(Component.Identifier.Key.DIVIDE, 0x54); /* Keypad / */ + public static final KeyboardUsage KEYPAD_ASTERICK = new KeyboardUsage(0x55); /* Keypad * */ + public static final KeyboardUsage KEYPAD_HYPHEN = new KeyboardUsage(Component.Identifier.Key.SUBTRACT, 0x56); /* Keypad - */ + public static final KeyboardUsage KEYPAD_PLUS = new KeyboardUsage(Component.Identifier.Key.ADD, 0x57); /* Keypad + */ + public static final KeyboardUsage KEYPAD_ENTER = new KeyboardUsage(Component.Identifier.Key.NUMPADENTER, 0x58); /* Keypad Enter */ + public static final KeyboardUsage KEYPAD_1 = new KeyboardUsage(Component.Identifier.Key.NUMPAD1, 0x59); /* Keypad 1 or End */ + public static final KeyboardUsage KEYPAD_2 = new KeyboardUsage(Component.Identifier.Key.NUMPAD2, 0x5A); /* Keypad 2 or Down Arrow */ + public static final KeyboardUsage KEYPAD_3 = new KeyboardUsage(Component.Identifier.Key.NUMPAD3, 0x5B); /* Keypad 3 or Page Down */ + public static final KeyboardUsage KEYPAD_4 = new KeyboardUsage(Component.Identifier.Key.NUMPAD4, 0x5C); /* Keypad 4 or Left Arrow */ + public static final KeyboardUsage KEYPAD_5 = new KeyboardUsage(Component.Identifier.Key.NUMPAD5, 0x5D); /* Keypad 5 */ + public static final KeyboardUsage KEYPAD_6 = new KeyboardUsage(Component.Identifier.Key.NUMPAD6, 0x5E); /* Keypad 6 or Right Arrow */ + public static final KeyboardUsage KEYPAD_7 = new KeyboardUsage(Component.Identifier.Key.NUMPAD7, 0x5F); /* Keypad 7 or Home */ + public static final KeyboardUsage KEYPAD_8 = new KeyboardUsage(Component.Identifier.Key.NUMPAD8, 0x60); /* Keypad 8 or Up Arrow */ + public static final KeyboardUsage KEYPAD_9 = new KeyboardUsage(Component.Identifier.Key.NUMPAD9, 0x61); /* Keypad 9 or Page Up */ + public static final KeyboardUsage KEYPAD_0 = new KeyboardUsage(Component.Identifier.Key.NUMPAD0, 0x62); /* Keypad 0 or Insert */ + public static final KeyboardUsage KEYPAD_PERIOD = new KeyboardUsage(Component.Identifier.Key.DECIMAL, 0x63); /* Keypad . or Delete */ + public static final KeyboardUsage NONUSBACKSLASH = new KeyboardUsage(Component.Identifier.Key.BACKSLASH, 0x64); /* Non-US \ or | */ + public static final KeyboardUsage APPLICATION = new KeyboardUsage(Component.Identifier.Key.APPS, 0x65); /* Application */ + public static final KeyboardUsage POWER = new KeyboardUsage(Component.Identifier.Key.POWER, 0x66); /* Power */ + public static final KeyboardUsage KEYPAD_EQUALSIGN = new KeyboardUsage(Component.Identifier.Key.NUMPADEQUAL, 0x67); /* Keypad = */ + public static final KeyboardUsage F13 = new KeyboardUsage(Component.Identifier.Key.F13, 0x68); /* F13 */ + public static final KeyboardUsage F14 = new KeyboardUsage(Component.Identifier.Key.F14, 0x69); /* F14 */ + public static final KeyboardUsage F15 = new KeyboardUsage(Component.Identifier.Key.F15, 0x6A); /* F15 */ + public static final KeyboardUsage F16 = new KeyboardUsage(0x6B); /* F16 */ + public static final KeyboardUsage F17 = new KeyboardUsage(0x6C); /* F17 */ + public static final KeyboardUsage F18 = new KeyboardUsage(0x6D); /* F18 */ + public static final KeyboardUsage F19 = new KeyboardUsage(0x6E); /* F19 */ + public static final KeyboardUsage F20 = new KeyboardUsage(0x6F); /* F20 */ + public static final KeyboardUsage F21 = new KeyboardUsage(0x70); /* F21 */ + public static final KeyboardUsage F22 = new KeyboardUsage(0x71); /* F22 */ + public static final KeyboardUsage F23 = new KeyboardUsage(0x72); /* F23 */ + public static final KeyboardUsage F24 = new KeyboardUsage(0x73); /* F24 */ + public static final KeyboardUsage EXECUTE = new KeyboardUsage(0x74); /* Execute */ + public static final KeyboardUsage HELP = new KeyboardUsage(0x75); /* Help */ + public static final KeyboardUsage MENU = new KeyboardUsage(0x76); /* Menu */ + public static final KeyboardUsage SELECT = new KeyboardUsage(0x77); /* Select */ + public static final KeyboardUsage STOP = new KeyboardUsage(Component.Identifier.Key.STOP, 0x78); /* Stop */ + public static final KeyboardUsage AGAIN = new KeyboardUsage(0x79); /* Again */ + public static final KeyboardUsage UNDO = new KeyboardUsage(0x7A); /* Undo */ + public static final KeyboardUsage CUT = new KeyboardUsage(0x7B); /* Cut */ + public static final KeyboardUsage COPY = new KeyboardUsage(0x7C); /* Copy */ + public static final KeyboardUsage PASTE = new KeyboardUsage(0x7D); /* Paste */ + public static final KeyboardUsage FIND = new KeyboardUsage(0x7E); /* Find */ + public static final KeyboardUsage MUTE = new KeyboardUsage(0x7F); /* Mute */ + public static final KeyboardUsage VOLUMEUP = new KeyboardUsage(0x80); /* Volume Up */ + public static final KeyboardUsage VOLUMEDOWN = new KeyboardUsage(0x81); /* Volume Down */ + public static final KeyboardUsage LOCKINGCAPSLOCK = new KeyboardUsage(Component.Identifier.Key.CAPITAL, 0x82); /* Locking Caps Lock */ + public static final KeyboardUsage LOCKINGNUMLOCK = new KeyboardUsage(Component.Identifier.Key.NUMLOCK, 0x83); /* Locking Num Lock */ + public static final KeyboardUsage LOCKINGSCROLLLOCK = new KeyboardUsage(Component.Identifier.Key.SCROLL, 0x84); /* Locking Scroll Lock */ + public static final KeyboardUsage KEYPAD_COMMA = new KeyboardUsage(Component.Identifier.Key.COMMA, 0x85); /* Keypad Comma */ + public static final KeyboardUsage KEYPAD_EQUALSSIGNAS400 = new KeyboardUsage(0x86); /* Keypad Equal Sign for AS/400 */ + public static final KeyboardUsage INTERNATIONAL1 = new KeyboardUsage(0x87); /* International1 */ + public static final KeyboardUsage INTERNATIONAL2 = new KeyboardUsage(0x88); /* International2 */ + public static final KeyboardUsage INTERNATIONAL3 = new KeyboardUsage(0x89); /* International3 */ + public static final KeyboardUsage INTERNATIONAL4 = new KeyboardUsage(0x8A); /* International4 */ + public static final KeyboardUsage INTERNATIONAL5 = new KeyboardUsage(0x8B); /* International5 */ + public static final KeyboardUsage INTERNATIONAL6 = new KeyboardUsage(0x8C); /* International6 */ + public static final KeyboardUsage INTERNATIONAL7 = new KeyboardUsage(0x8D); /* International7 */ + public static final KeyboardUsage INTERNATIONAL8 = new KeyboardUsage(0x8E); /* International8 */ + public static final KeyboardUsage INTERNATIONAL9 = new KeyboardUsage(0x8F); /* International9 */ + public static final KeyboardUsage LANG1 = new KeyboardUsage(0x90); /* LANG1 */ + public static final KeyboardUsage LANG2 = new KeyboardUsage(0x91); /* LANG2 */ + public static final KeyboardUsage LANG3 = new KeyboardUsage(0x92); /* LANG3 */ + public static final KeyboardUsage LANG4 = new KeyboardUsage(0x93); /* LANG4 */ + public static final KeyboardUsage LANG5 = new KeyboardUsage(0x94); /* LANG5 */ + public static final KeyboardUsage LANG6 = new KeyboardUsage(0x95); /* LANG6 */ + public static final KeyboardUsage LANG7 = new KeyboardUsage(0x96); /* LANG7 */ + public static final KeyboardUsage LANG8 = new KeyboardUsage(0x97); /* LANG8 */ + public static final KeyboardUsage LANG9 = new KeyboardUsage(0x98); /* LANG9 */ + public static final KeyboardUsage ALTERNATEERASE = new KeyboardUsage(0x99); /* AlternateErase */ + public static final KeyboardUsage SYSREQORATTENTION = new KeyboardUsage(Component.Identifier.Key.SYSRQ, 0x9A); /* SysReq/Attention */ + public static final KeyboardUsage CANCEL = new KeyboardUsage(0x9B); /* Cancel */ + public static final KeyboardUsage CLEAR = new KeyboardUsage(0x9C); /* Clear */ + public static final KeyboardUsage PRIOR = new KeyboardUsage(Component.Identifier.Key.PAGEUP, 0x9D); /* Prior */ + public static final KeyboardUsage RETURN = new KeyboardUsage(Component.Identifier.Key.RETURN, 0x9E); /* Return */ + public static final KeyboardUsage SEPARATOR = new KeyboardUsage(0x9F); /* Separator */ + public static final KeyboardUsage OUT = new KeyboardUsage(0xA0); /* Out */ + public static final KeyboardUsage OPER = new KeyboardUsage(0xA1); /* Oper */ + public static final KeyboardUsage CLEARORAGAIN = new KeyboardUsage(0xA2); /* Clear/Again */ + public static final KeyboardUsage CRSELORPROPS = new KeyboardUsage(0xA3); /* CrSel/Props */ + public static final KeyboardUsage EXSEL = new KeyboardUsage(0xA4); /* ExSel */ + /* 0xA5-0xDF Reserved */ + public static final KeyboardUsage LEFTCONTROL = new KeyboardUsage(Component.Identifier.Key.LCONTROL, 0xE0); /* Left Control */ + public static final KeyboardUsage LEFTSHIFT = new KeyboardUsage(Component.Identifier.Key.LSHIFT, 0xE1); /* Left Shift */ + public static final KeyboardUsage LEFTALT = new KeyboardUsage(Component.Identifier.Key.LALT, 0xE2); /* Left Alt */ + public static final KeyboardUsage LEFTGUI = new KeyboardUsage(Component.Identifier.Key.LWIN, 0xE3); /* Left GUI */ + public static final KeyboardUsage RIGHTCONTROL = new KeyboardUsage(Component.Identifier.Key.RCONTROL, 0xE4); /* Right Control */ + public static final KeyboardUsage RIGHTSHIFT = new KeyboardUsage(Component.Identifier.Key.RSHIFT, 0xE5); /* Right Shift */ + public static final KeyboardUsage RIGHTALT = new KeyboardUsage(Component.Identifier.Key.RALT, 0xE6); /* Right Alt */ + public static final KeyboardUsage RIGHTGUI = new KeyboardUsage(Component.Identifier.Key.RWIN, 0xE7); /* Right GUI */ + + private final int usage; + private final Component.Identifier.Key identifier; + + public final Component.Identifier.Key getIdentifier() { + return identifier; + } + + public final static KeyboardUsage map(int usage) { + if (usage < 0 || usage >= map.length) + return null; + return map[usage]; + } + + private KeyboardUsage(int usage) { + this(Component.Identifier.Key.UNKNOWN, usage); + } + + private KeyboardUsage(Component.Identifier.Key id, int usage) { + this.identifier = id; + this.usage = usage; + map[usage] = this; + } + + public final String toString() { + return "KeyboardUsage (0x" + Integer.toHexString(usage) + ")"; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXAbstractController.java b/plugins/OSX/src/java/net/java/games/input/OSXAbstractController.java new file mode 100644 index 0000000..4248c88 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXAbstractController.java @@ -0,0 +1,74 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents an OSX AbstractController +* @author elias +* @version 1.0 +*/ +final class OSXAbstractController extends AbstractController { + private final PortType port; + private final OSXHIDQueue queue; + private final Type type; + + protected OSXAbstractController(OSXHIDDevice device, OSXHIDQueue queue, Component[] components, Controller[] children, Rumbler[] rumblers, Type type) { + super(device.getProductName(), components, children, rumblers); + this.queue = queue; + this.type = type; + this.port = device.getPortType(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return OSXControllers.getNextDeviceEvent(event, queue); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + queue.setQueueDepth(size); + } + + public Type getType() { + return type; + } + + public final PortType getPortType() { + return port; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXComponent.java b/plugins/OSX/src/java/net/java/games/input/OSXComponent.java new file mode 100644 index 0000000..6533a79 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXComponent.java @@ -0,0 +1,70 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents an OSX Component +* @author elias +* @version 1.0 +*/ +class OSXComponent extends AbstractComponent { + private final OSXHIDElement element; + + public OSXComponent(Component.Identifier id, OSXHIDElement element) { + super(id.getName(), id); + this.element = element; + } + + public final boolean isRelative() { + return element.isRelative(); + } + + public boolean isAnalog() { + return element.isAnalog(); + } + + public final OSXHIDElement getElement() { + return element; + } + + protected float poll() throws IOException { + return OSXControllers.poll(element); + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXControllers.java b/plugins/OSX/src/java/net/java/games/input/OSXControllers.java new file mode 100644 index 0000000..704ccc5 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXControllers.java @@ -0,0 +1,64 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** helper methods for OSX specific Controllers +* @author elias +* @version 1.0 +*/ +final class OSXControllers { + private final static OSXEvent osx_event = new OSXEvent(); + + public final static synchronized float poll(OSXHIDElement element) throws IOException { + element.getElementValue(osx_event); + return element.convertValue(osx_event.getValue()); + } + + /* synchronized to protect osx_event */ + public final static synchronized boolean getNextDeviceEvent(Event event, OSXHIDQueue queue) throws IOException { + if (queue.getNextEvent(osx_event)) { + OSXComponent component = queue.mapEvent(osx_event); + event.set(component, component.getElement().convertValue(osx_event.getValue()), osx_event.getNanos()); + return true; + } else + return false; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXEnvironmentPlugin.java b/plugins/OSX/src/java/net/java/games/input/OSXEnvironmentPlugin.java index 41a28fc..68e42b0 100755 --- a/plugins/OSX/src/java/net/java/games/input/OSXEnvironmentPlugin.java +++ b/plugins/OSX/src/java/net/java/games/input/OSXEnvironmentPlugin.java @@ -38,447 +38,194 @@ *****************************************************************************/ package net.java.games.input; -import java.security.AccessController; +import java.io.IOException; +import java.util.List; +import java.util.Map; import java.util.ArrayList; import java.util.Iterator; -import java.util.HashMap; +import java.util.StringTokenizer; -import net.java.games.input.Controller; -import net.java.games.input.ControllerEnvironment; import net.java.games.util.plugins.Plugin; +import java.security.AccessController; +import java.security.PrivilegedAction; -/** OSX HIDManager implementation of controller environment +/** OSX HIDManager implementation +* @author elias * @author gregorypierce * @version 1.0 */ -public class OSXEnvironmentPlugin extends ControllerEnvironment implements Plugin -{ - - - public static final int HID_DEVICE_MOUSE = 0x02; - public static final int HID_DEVICE_JOYSTICK = 0x04; - public static final int HID_DEVICE_GAMEPAD = 0x05; - public static final int HID_DEVICE_KEYBOARD = 0x06; - - - public static final int HID_USAGE_POINTER = 0x01; - public static final int HID_USAGE_XAXIS = 0x30; - public static final int HID_USAGE_YAXIS = 0x31; - public static final int HID_USAGE_ZAXIS = 0x32; - public static final int HID_USAGE_XAXIS_ROTATION = 0x33; - public static final int HID_USAGE_YAXIS_ROTATION = 0x34; - public static final int HID_USAGE_ZAXIS_ROTATION = 0x35; - public static final int HID_USAGE_SLIDER = 0x36; - public static final int HID_USAGE_DIAL = 0x37; - public static final int HID_USAGE_WHEEL = 0x38; - public static final int HID_USAGE_HAT = 0x39; - public static final int HID_USAGE_DPAD_UP = 0x90; - public static final int HID_USAGE_DPAD_DOWN = 0x91; - public static final int HID_USAGE_DPAD_LEFT = 0x92; - public static final int HID_USAGE_DPAD_RIGHT = 0x93; - - - public static final int HID_USAGE_KEYBOARD_ERRORROLLOVER = 0x01; /* ErrorRollOver */ - public static final int HID_USAGE_KEYBOARD_POSTFAIL = 0x02; /* POSTFail */ - public static final int HID_USAGE_KEYBOARD_ERRORUNDEFINED = 0x03; /* ErrorUndefined */ - public static final int HID_USAGE_KEYBOARD_A = 0x04; /* a or A */ - public static final int HID_USAGE_KEYBOARD_B = 0x05; /* b or B */ - public static final int HID_USAGE_KEYBOARD_C = 0x06; /* c or C */ - public static final int HID_USAGE_KEYBOARD_D = 0x07; /* d or D */ - public static final int HID_USAGE_KEYBOARD_E = 0x08; /* e or E */ - public static final int HID_USAGE_KEYBOARD_F = 0x09; /* f or F */ - public static final int HID_USAGE_KEYBOARD_G = 0x0A; /* g or G */ - public static final int HID_USAGE_KEYBOARD_H = 0x0B; /* h or H */ - public static final int HID_USAGE_KEYBOARD_I = 0x0C; /* i or I */ - public static final int HID_USAGE_KEYBOARD_J = 0x0D; /* j or J */ - public static final int HID_USAGE_KEYBOARD_K = 0x0E; /* k or K */ - public static final int HID_USAGE_KEYBOARD_L = 0x0F; /* l or L */ - public static final int HID_USAGE_KEYBOARD_M = 0x10; /* m or M */ - public static final int HID_USAGE_KEYBOARD_N = 0x11; /* n or N */ - public static final int HID_USAGE_KEYBOARD_O = 0x12; /* o or O */ - public static final int HID_USAGE_KEYBOARD_P = 0x13; /* p or P */ - public static final int HID_USAGE_KEYBOARD_Q = 0x14; /* q or Q */ - public static final int HID_USAGE_KEYBOARD_R = 0x15; /* r or R */ - public static final int HID_USAGE_KEYBOARD_S = 0x16; /* s or S */ - public static final int HID_USAGE_KEYBOARD_T = 0x17; /* t or T */ - public static final int HID_USAGE_KEYBOARD_U = 0x18; /* u or U */ - public static final int HID_USAGE_KEYBOARD_V = 0x19; /* v or V */ - public static final int HID_USAGE_KEYBOARD_W = 0x1A; /* w or W */ - public static final int HID_USAGE_KEYBOARD_X = 0x1B; /* x or X */ - public static final int HID_USAGE_KEYBOARD_Y = 0x1C; /* y or Y */ - public static final int HID_USAGE_KEYBOARD_Z = 0x1D; /* z or Z */ - public static final int HID_USAGE_KEYBOARD_1 = 0x1E; /* 1 or ! */ - public static final int HID_USAGE_KEYBOARD_2 = 0x1F; /* 2 or @ */ - public static final int HID_USAGE_KEYBOARD_3 = 0x20; /* 3 or # */ - public static final int HID_USAGE_KEYBOARD_4 = 0x21; /* 4 or $ */ - public static final int HID_USAGE_KEYBOARD_5 = 0x22; /* 5 or % */ - public static final int HID_USAGE_KEYBOARD_6 = 0x23; /* 6 or ^ */ - public static final int HID_USAGE_KEYBOARD_7 = 0x24; /* 7 or & */ - public static final int HID_USAGE_KEYBOARD_8 = 0x25; /* 8 or * */ - public static final int HID_USAGE_KEYBOARD_9 = 0x26; /* 9 or ( */ - public static final int HID_USAGE_KEYBOARD_0 = 0x27; /* 0 or ) */ - public static final int HID_USAGE_KEYBOARD_ENTER = 0x28; /* Return (Enter) */ - public static final int HID_USAGE_KEYBOARD_ESCAPE = 0x29; /* Escape */ - public static final int HID_USAGE_KEYBOARD_BACKSPACE = 0x2A; /* Delete (Backspace) */ - public static final int HID_USAGE_KEYBOARD_TAB = 0x2B; /* Tab */ - public static final int HID_USAGE_KEYBOARD_SPACEBAR = 0x2C; /* Spacebar */ - public static final int HID_USAGE_KEYBOARD_HYPHEN = 0x2D; /* - or _ */ - public static final int HID_USAGE_KEYBOARD_EQUALSIGN = 0x2E; /* = or + */ - public static final int HID_USAGE_KEYBOARD_OPENBRACKET = 0x2F; /* [ or { */ - public static final int HID_USAGE_KEYBOARD_CLOSEBRACKET = 0x30; /* ] or } */ - public static final int HID_USAGE_KEYBOARD_BACKSLASH = 0x31; /* \ or | */ - public static final int HID_USAGE_KEYBOARD_NONUSPOUNT = 0x32; /* Non-US # or _ */ - public static final int HID_USAGE_KEYBOARD_SEMICOLON = 0x33; /* ; or : */ - public static final int HID_USAGE_KEYBOARD_QUOTE = 0x34; /* ' or " */ - public static final int HID_USAGE_KEYBOARD_TILDE = 0x35; /* Grave Accent and Tilde */ - public static final int HID_USAGE_KEYBOARD_COMMA = 0x36; /* , or < */ - public static final int HID_USAGE_KEYBOARD_PERIOD = 0x37; /* . or > */ - public static final int HID_USAGE_KEYBOARD_SLASH = 0x38; /* / or ? */ - public static final int HID_USAGE_KEYBOARD_CAPSLOCK = 0x39; /* Caps Lock */ - public static final int HID_USAGE_KEYBOARD_F1 = 0x3A; /* F1 */ - public static final int HID_USAGE_KEYBOARD_F2 = 0x3B; /* F2 */ - public static final int HID_USAGE_KEYBOARD_F3 = 0x3C; /* F3 */ - public static final int HID_USAGE_KEYBOARD_F4 = 0x3D; /* F4 */ - public static final int HID_USAGE_KEYBOARD_F5 = 0x3E; /* F5 */ - public static final int HID_USAGE_KEYBOARD_F6 = 0x3F; /* F6 */ - public static final int HID_USAGE_KEYBOARD_F7 = 0x40; /* F7 */ - public static final int HID_USAGE_KEYBOARD_F8 = 0x41; /* F8 */ - public static final int HID_USAGE_KEYBOARD_F9 = 0x42; /* F9 */ - public static final int HID_USAGE_KEYBOARD_F10 = 0x43; /* F10 */ - public static final int HID_USAGE_KEYBOARD_F11 = 0x44; /* F11 */ - public static final int HID_USAGE_KEYBOARD_F12 = 0x45; /* F12 */ - public static final int HID_USAGE_KEYBOARD_PRINTSCREEN = 0x46; /* Print Screen */ - public static final int HID_USAGE_KEYBOARD_SCROLLLOCK = 0x47; /* Scroll Lock */ - public static final int HID_USAGE_KEYBOARD_PAUSE = 0x48; /* Pause */ - public static final int HID_USAGE_KEYBOARD_INSERT = 0x49; /* Insert */ - public static final int HID_USAGE_KEYBOARD_HOME = 0x4A; /* Home */ - public static final int HID_USAGE_KEYBOARD_PAGEUP = 0x4B; /* Page Up */ - public static final int HID_USAGE_KEYBOARD_DELETE = 0x4C; /* Delete Forward */ - public static final int HID_USAGE_KEYBOARD_END = 0x4D; /* End */ - public static final int HID_USAGE_KEYBOARD_PAGEDOWN = 0x4E; /* Page Down */ - public static final int HID_USAGE_KEYBOARD_RIGHTARROW = 0x4F; /* Right Arrow */ - public static final int HID_USAGE_KEYBOARD_LEFTARROW = 0x50; /* Left Arrow */ - public static final int HID_USAGE_KEYBOARD_DOWNARROW = 0x51; /* Down Arrow */ - public static final int HID_USAGE_KEYBOARD_UPARROW = 0x52; /* Up Arrow */ - public static final int HID_USAGE_KEYPAD_NUMLOCK = 0x53; /* Keypad NumLock or Clear */ - public static final int HID_USAGE_KEYPAD_SLASH = 0x54; /* Keypad / */ - public static final int HID_USAGE_KEYPAD_ASTERICK = 0x55; /* Keypad * */ - public static final int HID_USAGE_KEYPAD_HYPHEN = 0x56; /* Keypad - */ - public static final int HID_USAGE_KEYPAD_PLUS = 0x57; /* Keypad + */ - public static final int HID_USAGE_KEYPAD_ENTER = 0x58; /* Keypad Enter */ - public static final int HID_USAGE_KEYPAD_1 = 0x59; /* Keypad 1 or End */ - public static final int HID_USAGE_KEYPAD_2 = 0x5A; /* Keypad 2 or Down Arrow */ - public static final int HID_USAGE_KEYPAD_3 = 0x5B; /* Keypad 3 or Page Down */ - public static final int HID_USAGE_KEYPAD_4 = 0x5C; /* Keypad 4 or Left Arrow */ - public static final int HID_USAGE_KEYPAD_5 = 0x5D; /* Keypad 5 */ - public static final int HID_USAGE_KEYPAD_6 = 0x5E; /* Keypad 6 or Right Arrow */ - public static final int HID_USAGE_KEYPAD_7 = 0x5F; /* Keypad 7 or Home */ - public static final int HID_USAGE_KEYPAD_8 = 0x60; /* Keypad 8 or Up Arrow */ - public static final int HID_USAGE_KEYPAD_9 = 0x61; /* Keypad 9 or Page Up */ - public static final int HID_USAGE_KEYPAD_0 = 0x62; /* Keypad 0 or Insert */ - public static final int HID_USAGE_KEYPAD_PERIOD = 0x63; /* Keypad . or Delete */ - public static final int HID_USAGE_KEYBOARD_NONUSBACKSLASH = 0x64; /* Non-US \ or | */ - public static final int HID_USAGE_KEYBOARD_APPLICATION = 0x65; /* Application */ - public static final int HID_USAGE_KEYBOARD_POWER = 0x66; /* Power */ - public static final int HID_USAGE_KEYPAD_EQUALSIGN = 0x67; /* Keypad = */ - public static final int HID_USAGE_KEYBOARD_F13 = 0x68; /* F13 */ - public static final int HID_USAGE_KEYBOARD_F14 = 0x69; /* F14 */ - public static final int HID_USAGE_KEYBOARD_F15 = 0x6A; /* F15 */ - public static final int HID_USAGE_KEYBOARD_F16 = 0x6B; /* F16 */ - public static final int HID_USAGE_KEYBOARD_F17 = 0x6C; /* F17 */ - public static final int HID_USAGE_KEYBOARD_F18 = 0x6D; /* F18 */ - public static final int HID_USAGE_KEYBOARD_F19 = 0x6E; /* F19 */ - public static final int HID_USAGE_KEYBOARD_F20 = 0x6F; /* F20 */ - public static final int HID_USAGE_KEYBOARD_F21 = 0x70; /* F21 */ - public static final int HID_USAGE_KEYBOARD_F22 = 0x71; /* F22 */ - public static final int HID_USAGE_KEYBOARD_F23 = 0x72; /* F23 */ - public static final int HID_USAGE_KEYBOARD_F24 = 0x73; /* F24 */ - public static final int HID_USAGE_KEYBOARD_EXECUTE = 0x74; /* Execute */ - public static final int HID_USAGE_KEYBOARD_HELP = 0x75; /* Help */ - public static final int HID_USAGE_KEYBOARD_MENU = 0x76; /* Menu */ - public static final int HID_USAGE_KEYBOARD_SELECT = 0x77; /* Select */ - public static final int HID_USAGE_KEYBOARD_STOP = 0x78; /* Stop */ - public static final int HID_USAGE_KEYBOARD_AGAIN = 0x79; /* Again */ - public static final int HID_USAGE_KEYBOARD_UNDO = 0x7A; /* Undo */ - public static final int HID_USAGE_KEYBOARD_CUT = 0x7B; /* Cut */ - public static final int HID_USAGE_KEYBOARD_COPY = 0x7C; /* Copy */ - public static final int HID_USAGE_KEYBOARD_PASTE = 0x7D; /* Paste */ - public static final int HID_USAGE_KEYBOARD_FIND = 0x7E; /* Find */ - public static final int HID_USAGE_KEYBOARD_MUTE = 0x7F; /* Mute */ - public static final int HID_USAGE_KEYBOARD_VOLUMEUP = 0x80; /* Volume Up */ - public static final int HID_USAGE_KEYBOARD_VOLUMEDOWN = 0x81; /* Volume Down */ - public static final int HID_USAGE_KEYBOARD_LOCKINGCAPSLOCK = 0x82; /* Locking Caps Lock */ - public static final int HID_USAGE_KEYBOARD_LOCKINGNUMLOCK = 0x83; /* Locking Num Lock */ - public static final int HID_USAGE_KEYBOARD_LOCKINGSCROLLLOCK = 0x84; /* Locking Scroll Lock */ - public static final int HID_USAGE_KEYPAD_COMMA = 0x85; /* Keypad Comma */ - public static final int HID_USAGE_KEYPAD_EQUALSSIGNAS400 = 0x86; /* Keypad Equal Sign for AS/400 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL1 = 0x87; /* International1 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL2 = 0x88; /* International2 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL3 = 0x89; /* International3 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL4 = 0x8A; /* International4 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL5 = 0x8B; /* International5 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL6 = 0x8C; /* International6 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL7 = 0x8D; /* International7 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL8 = 0x8E; /* International8 */ - public static final int HID_USAGE_KEYBOARD_INTERNATIONAL9 = 0x8F; /* International9 */ - public static final int HID_USAGE_KEYBOARD_LANG1 = 0x90; /* LANG1 */ - public static final int HID_USAGE_KEYBOARD_LANG2 = 0x91; /* LANG2 */ - public static final int HID_USAGE_KEYBOARD_LANG3 = 0x92; /* LANG3 */ - public static final int HID_USAGE_KEYBOARD_LANG4 = 0x93; /* LANG4 */ - public static final int HID_USAGE_KEYBOARD_LANG5 = 0x94; /* LANG5 */ - public static final int HID_USAGE_KEYBOARD_LANG6 = 0x95; /* LANG6 */ - public static final int HID_USAGE_KEYBOARD_LANG7 = 0x96; /* LANG7 */ - public static final int HID_USAGE_KEYBOARD_LANG8 = 0x97; /* LANG8 */ - public static final int HID_USAGE_KEYBOARD_LANG9 = 0x98; /* LANG9 */ - public static final int HID_USAGE_KEYBOARD_ALTERNATEERASE = 0x99; /* AlternateErase */ - public static final int HID_USAGE_KEYBOARD_SYSREQORATTENTION = 0x9A; /* SysReq/Attention */ - public static final int HID_USAGE_KEYBOARD_CANCEL = 0x9B; /* Cancel */ - public static final int HID_USAGE_KEYBOARD_CLEAR = 0x9C; /* Clear */ - public static final int HID_USAGE_KEYBOARD_PRIOR = 0x9D; /* Prior */ - public static final int HID_USAGE_KEYBOARD_RETURN = 0x9E; /* Return */ - public static final int HID_USAGE_KEYBOARD_SEPARATOR = 0x9F; /* Separator */ - public static final int HID_USAGE_KEYBOARD_OUT = 0xA0; /* Out */ - public static final int HID_USAGE_KEYBOARD_OPER = 0xA1; /* Oper */ - public static final int HID_USAGE_KEYBOARD_CLEARORAGAIN = 0xA2; /* Clear/Again */ - public static final int HID_USAGE_KEYBOARD_CRSELORPROPS = 0xA3; /* CrSel/Props */ - public static final int HID_USAGE_KEYBOARD_EXSEL = 0xA4; /* ExSel */ - /* 0xA5-0xDF Reserved */ - public static final int HID_USAGE_KEYBOARD_LEFTCONTROL = 0xE0; /* Left Control */ - public static final int HID_USAGE_KEYBOARD_LEFTSHIFT = 0xE1; /* Left Shift */ - public static final int HID_USAGE_KEYBOARD_LEFTALT = 0xE2; /* Left Alt */ - public static final int HID_USAGE_KEYBOARD_LEFTGUI = 0xE3; /* Left GUI */ - public static final int HID_USAGE_KEYBOARD_RIGHTCONTROL = 0xE4; /* Right Control */ - public static final int HID_USAGE_KEYBOARD_RIGHTSHIFT = 0xE5; /* Right Shift */ - public static final int HID_USAGE_KEYBOARD_RIGHTALT = 0xE6; /* Right Alt */ - public static final int HID_USAGE_KEYBOARD_RIGHTGUI = 0xE7; /* Right GUI */ - /* 0xE8-0xFFFF Reserved */ - public static final int HID_USAGE_KEYBOARD__RESERVED = 0xFFFF; - - - public static final int HID_USAGEPAGE_UNDEFINED = 0x00; - public static final int HID_USAGEPAGE_GENERICDESKTOP = 0x01; - public static final int HID_USAGEPAGE_SIMULATION = 0x02; - public static final int HID_USAGEPAGE_VR = 0x03; - public static final int HID_USAGEPAGE_SPORT = 0x04; - public static final int HID_USAGEPAGE_GAME = 0x05; - public static final int HID_USAGEPAGE_KEYBOARD = 0x07; /* USB Device Class Definition for Human Interface Devices (HID). Note: the usage type for all key codes is Selector (Sel). */ - public static final int HID_USAGEPAGE_LED = 0x08; - public static final int HID_USAGEPAGE_BUTTON = 0x09; - public static final int HID_USAGEPAGE_ORDINAL = 0x0A; - public static final int HID_USAGEPAGE_TELEPHONY = 0x0B; - public static final int HID_USAGEPAGE_CONSUMER = 0x0C; - public static final int HID_USAGEPAGE_DIGITIZER = 0x0D; - public static final int HID_USAGEPAGE_PID = 0x0F; /* USB Physical Interface Device definitions for force feedback and related devices. */ - public static final int HID_USAGEPAGE_UNICODE = 0x10; - public static final int HID_USAGEPAGE_ALPHANUMERIC_DISPLAY = 0x14; - public static final int HID_USAGEPAGE_POWERDEVICE = 0x84; /* Power Device Page */ - public static final int HID_USAGEPAGE_BATTERY_SYSTEM = 0x85; /* Battery System Page */ - public static final int HID_USAGEPAGE_BARCODE_SCANNER = 0x8C; /* (Point of Sale) USB Device Class Definition for Bar Code Scanner Devices */ - public static final int HID_USAGEPAGE_SCALE = 0x8D; /* (Point of Sale) USB Device Class Definition for Scale Devices */ - public static final int HID_USAGEPAGE_CAMERA_CONTROL = 0x90; /* USB Device Class Definition for Image Class Devices */ - public static final int HID_USAGEPAGE_ARCADE = 0x91; /* OAAF Definitions for arcade and coinop related Devices */ - public static final int HID_USAGEPAGE_VENDOR_DEFINED_START = 0xFF00; - - - public static final int HID_ELEMENTTYPE_INPUT_MISC = 1; - public static final int HID_ELEMENTTYPE_INPUT_BUTTON = 2; - public static final int HID_ELEMENTTYPE_INPUT_AXIS = 3; - public static final int HID_ELEMENTTYPE_INPUT_SCANCODES = 4; - public static final int HID_ELEMENTTYPE_OUTPUT = 129; - public static final int HID_ELEMENTTYPE_FEATURE = 257; - public static final int HID_ELEMENTTYPE_COLLECTION = 513; - - - - - - - static - { - System.loadLibrary("jinput"); - } - - public native void hidCreate(); - public native void hidDispose(); - public native void enumDevices(); - - /** - * Opens an input device and returns the address of the input queue for that device - */ - public native long openDevice( long lpDevice, int queueDepth ); - public native void closeDevice( long lpDevice, long lpQueue ); - - - /** - * Polls a device and returns the element top most on the input queue. The elements that - * are returned are only those that have had their hidCookies registered with registerDeviceElement. - * @param lpQueue - * @return - */ - public native int pollDevice( long lpQueue ); - public native int pollElement( long lpDevice, long hidCookie ); - public native void registerDeviceElement( long lpQueue, long hidCookie ); - public native void deregisterDeviceElement( long lpQueue, long hidCookie ); - - - private HashMap devices = new HashMap(); - - - public OSXEnvironmentPlugin() - { - System.out.println("net.java.games.input.OSXEnvironmentPlugin instance created"); - - System.out.println("Creating HID engine"); - hidCreate(); - - System.out.println("Enumerating devices"); - enumDevices(); - } - - public void finalize() - { - System.out.println("Disposing HID engine"); - hidDispose(); - } - - public Controller[] getControllers() - { - return (Controller[])(devices.values().toArray( new Controller[0])); - } - - public Controller createController( long lpDevice, String productName, int usage ) - { - - switch (usage) - { - case (HID_DEVICE_MOUSE): - System.out.println("Found mouse [" + productName + "] device address [" + lpDevice + "]"); - return new OSXMouse( this, lpDevice, productName ); - case (HID_DEVICE_JOYSTICK): - System.out.println("Found joystick [" + productName + "] device address [" + lpDevice + "]"); - return new OSXJoystick( this, lpDevice, productName ); - case (HID_DEVICE_GAMEPAD): - System.out.println("Found gamepad [" + productName + "] device address [" + lpDevice + "]"); - return new OSXGamepad( this, lpDevice, productName ); - case (HID_DEVICE_KEYBOARD): - System.out.println("Found keyboard [" + productName + "] device address [" + lpDevice + "]"); - return new OSXKeyboard( this, lpDevice, productName ); - - default: - System.out.println("Found device of unknown or unsupported type. Usage[" + usage + "], ProductName[" + productName + "] - ignoring"); - return null; - } - } - - /** - * Add a controller to the device list - * @param lpDevice - * @param productName - * @param usage - */ - private void addController( long lpDevice, String productName, int usage ) - { - Controller controller = null; - - controller = createController( lpDevice, productName, usage ); - - if ( controller != null ) - { - devices.put( new Long(lpDevice), controller ); - } - } - - /** - * Adds an InputControllerElement to a device. This method is invoked from native code. - * @param lpDevice - * @param elementCookie - * @param elementType - * @param usage - * @param usagePage - * @param rawMin - * @param rawMax - * @param scaledMin - * @param scaledMax - * @param dataBitSize - * @param isRelative - * @param isWrapping - * @param isNonLinear - * @param hasPreferredState - * @param hasNullState - */ - private void addControllerElement( long lpDevice, - long elementCookie, - int elementType, - int usage, - int usagePage, - int rawMin, - int rawMax, - int scaledMin, - int scaledMax, - int dataBitSize, - boolean isRelative, - boolean isWrapping, - boolean isNonLinear, - boolean hasPreferredState, - boolean hasNullState) - { - InputControllerElement element = new InputControllerElement( elementCookie, elementType, usage, usagePage, - rawMin, rawMax, scaledMin, scaledMax, - dataBitSize, isRelative, isWrapping, isNonLinear, - hasPreferredState, hasNullState ); - - - InputController inputController = (InputController)devices.get( new Long( lpDevice) ); - if ( inputController != null ) - { - inputController.addControllerElement( element ); - } - } - - - - public void testDevice( long lpDevice ) - { - System.out.println("Opening device "); - long lpQueue = openDevice( lpDevice, 32 ); - - for ( int i = 0; i < 50; i++ ) - { - try - { - pollDevice( lpQueue ); - Thread.sleep(10); - } - catch( Exception e ) - { - System.out.println("Interrupted" + e ); - } - } - - System.out.println("Closing device"); - closeDevice( lpDevice, lpQueue ); - } - - public static void main (String args[]) - { - System.out.println("Started net.java.games.input.OSXEnvironmentPlugin"); - OSXEnvironmentPlugin newjni = new OSXEnvironmentPlugin(); - - //newjni.hidCreate(); - - //newjni.enumDevices(); - - - Controller[] controllers = newjni.getControllers(); - - for ( int i = 0; i < controllers.length; i++ ) - { - System.out.println("Controller [" + controllers[i].getName() +"] enumerated..."); - } - - //newjni.hidDispose(); - - System.out.println("Done"); +public final class OSXEnvironmentPlugin extends ControllerEnvironment implements Plugin { + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + if (isMacOSXEqualsOrBetterThan(10, 4)) { + System.loadLibrary("jinput-osx"); + } else { + // If we're not on 10.4 or later, try to load the legacy library first + try { + System.loadLibrary("jinput-osx-legacy"); + } catch (UnsatisfiedLinkError e) { + System.loadLibrary("jinput-osx"); + } + } + return null; + } + }); } -}
\ No newline at end of file + private final static boolean isMacOSXEqualsOrBetterThan(int major_required, int minor_required) { + String os_version = System.getProperty("os.version"); + StringTokenizer version_tokenizer = new StringTokenizer(os_version, "."); + int major; + int minor; + try { + String major_str = version_tokenizer.nextToken(); + String minor_str = version_tokenizer.nextToken(); + major = Integer.parseInt(major_str); + minor = Integer.parseInt(minor_str); + } catch (Exception e) { + ControllerEnvironment.logln("Exception occurred while trying to determine OS version: " + e); + // Best guess, no + return false; + } + return major > major_required || (major == major_required && minor >= minor_required); + } + + private final Controller[] controllers; + + public OSXEnvironmentPlugin() { + this.controllers = enumerateControllers(); + } + + public final Controller[] getControllers() { + return controllers; + } + + private final static void addElements(OSXHIDQueue queue, List elements, List components, boolean map_mouse_buttons) throws IOException { + Iterator it = elements.iterator(); + while (it.hasNext()) { + OSXHIDElement element = (OSXHIDElement)it.next(); + Component.Identifier id = element.getIdentifier(); + if (id == null) + continue; + if (map_mouse_buttons) { + if (id == Component.Identifier.Button._0) { + id = Component.Identifier.Button.LEFT; + } else if (id == Component.Identifier.Button._1) { + id = Component.Identifier.Button.RIGHT; + } else if (id == Component.Identifier.Button._2) { + id = Component.Identifier.Button.MIDDLE; + } + } + OSXComponent component = new OSXComponent(id, element); + components.add(component); + queue.addElement(element, component); + } + } + + private final static Keyboard createKeyboardFromDevice(OSXHIDDevice device, List elements) throws IOException { + List components = new ArrayList(); + OSXHIDQueue queue = device.createQueue(AbstractController.EVENT_QUEUE_DEPTH); + try { + addElements(queue, elements, components, false); + } catch (IOException e) { + queue.release(); + throw e; + } + Component[] components_array = new Component[components.size()]; + components.toArray(components_array); + Keyboard keyboard = new OSXKeyboard(device, queue, components_array, new Controller[]{}, new Rumbler[]{}); + return keyboard; + } + + private final static Mouse createMouseFromDevice(OSXHIDDevice device, List elements) throws IOException { + List components = new ArrayList(); + OSXHIDQueue queue = device.createQueue(AbstractController.EVENT_QUEUE_DEPTH); + try { + addElements(queue, elements, components, true); + } catch (IOException e) { + queue.release(); + throw e; + } + Component[] components_array = new Component[components.size()]; + components.toArray(components_array); + Mouse mouse = new OSXMouse(device, queue, components_array, new Controller[]{}, new Rumbler[]{}); + if (mouse.getLeft() != null && mouse.getX() != null && mouse.getY() != null) { + return mouse; + } else { + queue.release(); + return null; + } + } + + private final static AbstractController createControllerFromDevice(OSXHIDDevice device, List elements, Controller.Type type) throws IOException { + List components = new ArrayList(); + OSXHIDQueue queue = device.createQueue(AbstractController.EVENT_QUEUE_DEPTH); + try { + addElements(queue, elements, components, false); + } catch (IOException e) { + queue.release(); + throw e; + } + Component[] components_array = new Component[components.size()]; + components.toArray(components_array); + AbstractController controller = new OSXAbstractController(device, queue, components_array, new Controller[]{}, new Rumbler[]{}, type); + return controller; + } + + private final static void createControllersFromDevice(OSXHIDDevice device, List controllers) throws IOException { + UsagePair usage_pair = device.getUsagePair(); + if (usage_pair == null) + return; + List elements = device.getElements(); + if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP && (usage_pair.getUsage() == GenericDesktopUsage.MOUSE || + usage_pair.getUsage() == GenericDesktopUsage.POINTER)) { + Controller mouse = createMouseFromDevice(device, elements); + if (mouse != null) + controllers.add(mouse); + } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP && (usage_pair.getUsage() == GenericDesktopUsage.KEYBOARD || + usage_pair.getUsage() == GenericDesktopUsage.KEYPAD)) { + Controller keyboard = createKeyboardFromDevice(device, elements); + if (keyboard != null) + controllers.add(keyboard); + } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP && usage_pair.getUsage() == GenericDesktopUsage.JOYSTICK) { + Controller joystick = createControllerFromDevice(device, elements, Controller.Type.STICK); + if (joystick != null) + controllers.add(joystick); + } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP && usage_pair.getUsage() == GenericDesktopUsage.GAME_PAD) { + Controller game_pad = createControllerFromDevice(device, elements, Controller.Type.GAMEPAD); + if (game_pad != null) + controllers.add(game_pad); + } + } + + private final static Controller[] enumerateControllers() { + List controllers = new ArrayList(); + try { + OSXHIDDeviceIterator it = new OSXHIDDeviceIterator(); + try { + OSXHIDDevice device; + while ((device = it.next()) != null) { + boolean device_used = false; + try { + int old_size = controllers.size(); + createControllersFromDevice(device, controllers); + device_used = old_size != controllers.size(); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to create controllers from device: " + device.getProductName()); + } + if (!device_used) + device.release(); + } + } finally { + it.close(); + } + } catch (IOException e) { + ControllerEnvironment.log("Failed to enumerate device: " + e.getMessage()); + return new Controller[]{}; + } + Controller[] controllers_array = new Controller[controllers.size()]; + controllers.toArray(controllers_array); + return controllers_array; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXEvent.java b/plugins/OSX/src/java/net/java/games/input/OSXEvent.java new file mode 100644 index 0000000..9db46e6 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXEvent.java @@ -0,0 +1,73 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +/** OSX Event structure corresponding to IOHIDEventStruct +* @author elias +* @version 1.0 +*/ +class OSXEvent { + private long type; + private long cookie; + private int value; + private long nanos; + + public void set(long type, long cookie, int value, long nanos) { + this.type = type; + this.cookie = cookie; + this.value = value; + this.nanos = nanos; + } + + public long getType() { + return type; + } + + public long getCookie() { + return cookie; + } + + public int getValue() { + return value; + } + + public long getNanos() { + return nanos; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXGamepad.java b/plugins/OSX/src/java/net/java/games/input/OSXGamepad.java deleted file mode 100644 index d739b6c..0000000 --- a/plugins/OSX/src/java/net/java/games/input/OSXGamepad.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.java.games.input; - -/** - * Created by IntelliJ IDEA. - * User: gpierce - * Date: Aug 2, 2003 - * Time: 3:59:09 PM - * To change this template use Options | File Templates. - */ -public class OSXGamepad extends AbstractController implements InputController -{ - private OSXEnvironmentPlugin plugin; - private long lpDevice; - private long lpQueue; - - public OSXGamepad( OSXEnvironmentPlugin plugin, long lpDevice, String productName ) - { - super( productName ); - - this.plugin = plugin; - this.lpDevice = lpDevice; - - openDevice(); - } - public boolean poll() - { - plugin.pollDevice( lpQueue ); - - return true; - } - - public void openDevice() - { - this.lpQueue = plugin.openDevice( this.lpDevice, 32 ); - } - - public void closeDevice() - { - plugin.closeDevice( this.lpDevice, this.lpQueue ); - } - - public void pollDevice() - { - plugin.pollDevice( this.lpQueue ); - } - - public void addControllerElement(InputControllerElement element) - { - switch ( element.getElementType() ) - { - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_MISC: - System.out.println("*Adding misc component"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_BUTTON: - System.out.println("*Adding button"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_AXIS: - System.out.println("*Adding axis"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_SCANCODES: - System.out.println("*Adding scancode"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_OUTPUT: - System.out.println("*Adding forcefeedback"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_FEATURE: - - System.out.println("*Adding feature"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_COLLECTION: - System.out.println("*Adding collection"); - break; - - } - } -} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXHIDDevice.java b/plugins/OSX/src/java/net/java/games/input/OSXHIDDevice.java new file mode 100644 index 0000000..27102ca --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXHIDDevice.java @@ -0,0 +1,318 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.Iterator; + +/** OSX HIDManager implementation +* @author elias +* @author gregorypierce +* @version 1.0 +*/ +final class OSXHIDDevice { + private final static int AXIS_DEFAULT_MIN_VALUE = 0; + private final static int AXIS_DEFAULT_MAX_VALUE = 64*1024; + + private final static String kIOHIDTransportKey = "Transport"; + private final static String kIOHIDVendorIDKey = "VendorID"; + private final static String kIOHIDVendorIDSourceKey = "VendorIDSource"; + private final static String kIOHIDProductIDKey = "ProductID"; + private final static String kIOHIDVersionNumberKey = "VersionNumber"; + private final static String kIOHIDManufacturerKey = "Manufacturer"; + private final static String kIOHIDProductKey = "Product"; + private final static String kIOHIDSerialNumberKey = "SerialNumber"; + private final static String kIOHIDCountryCodeKey = "CountryCode"; + private final static String kIOHIDLocationIDKey = "LocationID"; + private final static String kIOHIDDeviceUsageKey = "DeviceUsage"; + private final static String kIOHIDDeviceUsagePageKey = "DeviceUsagePage"; + private final static String kIOHIDDeviceUsagePairsKey = "DeviceUsagePairs"; + private final static String kIOHIDPrimaryUsageKey = "PrimaryUsage"; + private final static String kIOHIDPrimaryUsagePageKey = "PrimaryUsagePage"; + private final static String kIOHIDMaxInputReportSizeKey = "MaxInputReportSize"; + private final static String kIOHIDMaxOutputReportSizeKey = "MaxOutputReportSize"; + private final static String kIOHIDMaxFeatureReportSizeKey = "MaxFeatureReportSize"; + + private final static String kIOHIDElementKey = "Elements"; + + private final static String kIOHIDElementCookieKey = "ElementCookie"; + private final static String kIOHIDElementTypeKey = "Type"; + private final static String kIOHIDElementCollectionTypeKey = "CollectionType"; + private final static String kIOHIDElementUsageKey = "Usage"; + private final static String kIOHIDElementUsagePageKey = "UsagePage"; + private final static String kIOHIDElementMinKey = "Min"; + private final static String kIOHIDElementMaxKey = "Max"; + private final static String kIOHIDElementScaledMinKey = "ScaledMin"; + private final static String kIOHIDElementScaledMaxKey = "ScaledMax"; + private final static String kIOHIDElementSizeKey = "Size"; + private final static String kIOHIDElementReportSizeKey = "ReportSize"; + private final static String kIOHIDElementReportCountKey = "ReportCount"; + private final static String kIOHIDElementReportIDKey = "ReportID"; + private final static String kIOHIDElementIsArrayKey = "IsArray"; + private final static String kIOHIDElementIsRelativeKey = "IsRelative"; + private final static String kIOHIDElementIsWrappingKey = "IsWrapping"; + private final static String kIOHIDElementIsNonLinearKey = "IsNonLinear"; + private final static String kIOHIDElementHasPreferredStateKey = "HasPreferredState"; + private final static String kIOHIDElementHasNullStateKey = "HasNullState"; + private final static String kIOHIDElementUnitKey = "Unit"; + private final static String kIOHIDElementUnitExponentKey = "UnitExponent"; + private final static String kIOHIDElementNameKey = "Name"; + private final static String kIOHIDElementValueLocationKey = "ValueLocation"; + private final static String kIOHIDElementDuplicateIndexKey = "DuplicateIndex"; + private final static String kIOHIDElementParentCollectionKey = "ParentCollection"; + + private final long device_address; + private final long device_interface_address; + private final Map properties; + + private boolean released; + + public OSXHIDDevice(long device_address, long device_interface_address) throws IOException { + this.device_address = device_address; + this.device_interface_address = device_interface_address; + this.properties = getDeviceProperties(); + open(); + } + + public final Controller.PortType getPortType() { + String transport = (String)properties.get(kIOHIDTransportKey); + if (transport == null) + return Controller.PortType.UNKNOWN; + if (transport.equals("USB")) { + return Controller.PortType.USB; + } else { + return Controller.PortType.UNKNOWN; + } + } + + public final String getProductName() { + return (String)properties.get(kIOHIDProductKey); + } + + private final OSXHIDElement createElementFromElementProperties(Map element_properties) { + /* long size = getLongFromProperties(element_properties, kIOHIDElementSizeKey); + // ignore elements that can't fit into the 32 bit value field of a hid event + if (size > 32) + return null;*/ + long element_cookie = getLongFromProperties(element_properties, kIOHIDElementCookieKey); + int element_type_id = getIntFromProperties(element_properties, kIOHIDElementTypeKey); + ElementType element_type = ElementType.map(element_type_id); + int min = (int)getLongFromProperties(element_properties, kIOHIDElementMinKey, AXIS_DEFAULT_MIN_VALUE); + int max = (int)getLongFromProperties(element_properties, kIOHIDElementMaxKey, AXIS_DEFAULT_MAX_VALUE); +/* long scaled_min = getLongFromProperties(element_properties, kIOHIDElementScaledMinKey, Long.MIN_VALUE); + long scaled_max = getLongFromProperties(element_properties, kIOHIDElementScaledMaxKey, Long.MAX_VALUE);*/ + UsagePair device_usage_pair = getUsagePair(); + boolean default_relative = device_usage_pair != null && (device_usage_pair.getUsage() == GenericDesktopUsage.POINTER || device_usage_pair.getUsage() == GenericDesktopUsage.MOUSE); + + boolean is_relative = getBooleanFromProperties(element_properties, kIOHIDElementIsRelativeKey, default_relative); +/* boolean is_wrapping = getBooleanFromProperties(element_properties, kIOHIDElementIsWrappingKey); + boolean is_non_linear = getBooleanFromProperties(element_properties, kIOHIDElementIsNonLinearKey); + boolean has_preferred_state = getBooleanFromProperties(element_properties, kIOHIDElementHasPreferredStateKey); + boolean has_null_state = getBooleanFromProperties(element_properties, kIOHIDElementHasNullStateKey);*/ + int usage = getIntFromProperties(element_properties, kIOHIDElementUsageKey); + int usage_page = getIntFromProperties(element_properties, kIOHIDElementUsagePageKey); + UsagePair usage_pair = createUsagePair(usage_page, usage); + if (usage_pair == null || (element_type != ElementType.INPUT_MISC && element_type != ElementType.INPUT_BUTTON && element_type != ElementType.INPUT_AXIS)) { +//System.out.println("element_type = 0x" + element_type + " | usage = " + usage + " | usage_page = " + usage_page); + return null; + } else { + return new OSXHIDElement(this, usage_pair, element_cookie, element_type, min, max, is_relative); + } + } + + private final void addElements(List elements, Map properties) { + Object[] elements_properties = (Object[])properties.get(kIOHIDElementKey); + if (elements_properties == null) + return; + for (int i = 0; i < elements_properties.length; i++) { + Map element_properties = (Map)elements_properties[i]; + OSXHIDElement element = createElementFromElementProperties(element_properties); + if (element != null) { + elements.add(element); + } + addElements(elements, element_properties); + } + } + + public final List getElements() { + List elements = new ArrayList(); + addElements(elements, properties); + return elements; + } + + private final static long getLongFromProperties(Map properties, String key, long default_value) { + Long long_obj = (Long)properties.get(key); + if (long_obj == null) + return default_value; + return long_obj.longValue(); + } + + private final static boolean getBooleanFromProperties(Map properties, String key, boolean default_value) { + return getLongFromProperties(properties, key, default_value ? 1 : 0) != 0; + } + + private final static int getIntFromProperties(Map properties, String key) { + return (int)getLongFromProperties(properties, key); + } + + private final static long getLongFromProperties(Map properties, String key) { + Long long_obj = (Long)properties.get(key); + return long_obj.longValue(); + } + + private final static UsagePair createUsagePair(int usage_page_id, int usage_id) { + UsagePage usage_page = UsagePage.map(usage_page_id); + if (usage_page != null) { + Usage usage = usage_page.mapUsage(usage_id); + if (usage != null) + return new UsagePair(usage_page, usage); + } + return null; + } + + public final UsagePair getUsagePair() { + int usage_page_id = getIntFromProperties(properties, kIOHIDPrimaryUsagePageKey); + int usage_id = getIntFromProperties(properties, kIOHIDPrimaryUsageKey); + return createUsagePair(usage_page_id, usage_id); + } + +/* + public final List getUsagePairs() { + List usage_pairs_list = new ArrayList(); + Object[] usage_pairs = (Object[])properties.get(kIOHIDDeviceUsagePairsKey); + if (usage_pairs == null) { + int usage_page_id = getIntFromProperties(properties, kIOHIDPrimaryUsagePageKey); + int usage_id = getIntFromProperties(properties, kIOHIDPrimaryUsageKey); + UsagePair pair = createUsagePair(usage_page_id, usage_id); + if (pair != null) + usage_pairs_list.add(pair); + } + for (int i = 0; i < usage_pairs.length; i++) { + Map usage_pair = (Map)usage_pairs[i]; + int usage_page_id = getIntFromProperties(usage_pair, kIOHIDDeviceUsagePageKey); + int usage_id = getIntFromProperties(usage_pair, kIOHIDDeviceUsageKey); + UsagePair pair = createUsagePair(usage_page_id, usage_id); + if (pair != null) + usage_pairs_list.add(pair); + } + return usage_pairs_list; + } +*/ + private final void dumpProperties() { + System.out.println(toString()); + dumpMap("", properties); + } + + private final static void dumpArray(String prefix, Object[] array) { + System.out.println(prefix + "{"); + for (int i = 0; i < array.length; i++) { + dumpObject(prefix + "\t", array[i]); + System.out.println(prefix + ","); + } + System.out.println(prefix + "}"); + } + + private final static void dumpMap(String prefix, Map map) { + Iterator keys = map.keySet().iterator(); + while (keys.hasNext()) { + Object key = keys.next(); + Object value = map.get(key); + dumpObject(prefix, key); + dumpObject(prefix + "\t", value); + } + } + + private final static void dumpObject(String prefix, Object obj) { + if (obj instanceof Long) { + Long l = (Long)obj; + System.out.println(prefix + "0x" + Long.toHexString(l.longValue())); + } else if (obj instanceof Map) + dumpMap(prefix, (Map)obj); + else if (obj.getClass().isArray()) + dumpArray(prefix, (Object[])obj); + else + System.out.println(prefix + obj); + } + + private final Map getDeviceProperties() throws IOException { + return nGetDeviceProperties(device_address); + } + private final static native Map nGetDeviceProperties(long device_address) throws IOException; + + public final synchronized void release() throws IOException { + try { + close(); + } finally { + released = true; + nReleaseDevice(device_address, device_interface_address); + } + } + private final static native void nReleaseDevice(long device_address, long device_interface_address); + + public final synchronized void getElementValue(long element_cookie, OSXEvent event) throws IOException { + checkReleased(); + nGetElementValue(device_interface_address, element_cookie, event); + } + private final static native void nGetElementValue(long device_interface_address, long element_cookie, OSXEvent event) throws IOException; + + public final synchronized OSXHIDQueue createQueue(int queue_depth) throws IOException { + checkReleased(); + long queue_address = nCreateQueue(device_interface_address); + return new OSXHIDQueue(queue_address, queue_depth); + } + private final static native long nCreateQueue(long device_interface_address) throws IOException; + + private final void open() throws IOException { + nOpen(device_interface_address); + } + private final static native void nOpen(long device_interface_address) throws IOException; + + private final void close() throws IOException { + nClose(device_interface_address); + } + private final static native void nClose(long device_interface_address) throws IOException; + + private final void checkReleased() throws IOException { + if (released) + throw new IOException(); + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXHIDDeviceIterator.java b/plugins/OSX/src/java/net/java/games/input/OSXHIDDeviceIterator.java new file mode 100644 index 0000000..1070c58 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXHIDDeviceIterator.java @@ -0,0 +1,65 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** OSX HIDManager implementation +* @author elias +* @author gregorypierce +* @version 1.0 +*/ +final class OSXHIDDeviceIterator { + private final long iterator_address; + + public OSXHIDDeviceIterator() throws IOException { + this.iterator_address = nCreateIterator(); + } + private final static native long nCreateIterator(); + + public final void close(){ + nReleaseIterator(iterator_address); + } + private final static native void nReleaseIterator(long iterator_address); + + public final OSXHIDDevice next() throws IOException { + return nNext(iterator_address); + } + private final static native OSXHIDDevice nNext(long iterator_address) throws IOException; +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXHIDElement.java b/plugins/OSX/src/java/net/java/games/input/OSXHIDElement.java new file mode 100644 index 0000000..a8c0907 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXHIDElement.java @@ -0,0 +1,143 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents an OSX HID Element +* @author elias +* @author gregorypierce +* @version 1.0 +*/ +final class OSXHIDElement { + private final OSXHIDDevice device; + private final UsagePair usage_pair; + private final long element_cookie; + private final ElementType element_type; + private final int min; + private final int max; + private final Component.Identifier identifier; + private final boolean is_relative; + + public OSXHIDElement(OSXHIDDevice device, UsagePair usage_pair, long element_cookie, ElementType element_type, int min, int max, boolean is_relative) { + this.device = device; + this.usage_pair = usage_pair; + this.element_cookie = element_cookie; + this.element_type = element_type; + this.min = min; + this.max = max; + this.identifier = computeIdentifier(); + this.is_relative = is_relative; + } + + private final Component.Identifier computeIdentifier() { + if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP) { + return ((GenericDesktopUsage)usage_pair.getUsage()).getIdentifier(); + } else if (usage_pair.getUsagePage() == UsagePage.BUTTON) { + return ((ButtonUsage)usage_pair.getUsage()).getIdentifier(); + } else if (usage_pair.getUsagePage() == UsagePage.KEYBOARD_OR_KEYPAD) { + return ((KeyboardUsage)usage_pair.getUsage()).getIdentifier(); + } else + return null; + } + + final Component.Identifier getIdentifier() { + return identifier; + } + + final long getCookie() { + return element_cookie; + } + + final ElementType getType() { + return element_type; + } + + final boolean isRelative() { + return is_relative && identifier instanceof Component.Identifier.Axis; + } + + final boolean isAnalog() { + return identifier instanceof Component.Identifier.Axis && identifier != Component.Identifier.Axis.POV; + } + + private UsagePair getUsagePair() { + return usage_pair; + } + + final void getElementValue(OSXEvent event) throws IOException { + device.getElementValue(element_cookie, event); + } + + final float convertValue(float value) { + if (identifier == Component.Identifier.Axis.POV) { + switch ((int)value) { + case 0: + return Component.POV.UP; + case 1: + return Component.POV.UP_RIGHT; + case 2: + return Component.POV.RIGHT; + case 3: + return Component.POV.DOWN_RIGHT; + case 4: + return Component.POV.DOWN; + case 5: + return Component.POV.DOWN_LEFT; + case 6: + return Component.POV.LEFT; + case 7: + return Component.POV.UP_LEFT; + case 8: + return Component.POV.OFF; + default: + return Component.POV.OFF; + } + } else if (identifier instanceof Component.Identifier.Axis && !is_relative) { + if (min == max) + return 0; + else if (value > max) + value = max; + else if (value < min) + value = min; + return 2*(value - min)/(max - min) - 1; + } else + return value; + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXHIDQueue.java b/plugins/OSX/src/java/net/java/games/input/OSXHIDQueue.java new file mode 100644 index 0000000..884c76a --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/OSXHIDQueue.java @@ -0,0 +1,141 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; +import java.util.Map; +import java.util.HashMap; + +/** +* @author elias +* @version 1.0 +*/ +final class OSXHIDQueue { + private final Map map = new HashMap(); + private final long queue_address; + + private boolean released; + + public OSXHIDQueue(long address, int queue_depth) throws IOException { + this.queue_address = address; + try { + createQueue(queue_depth); + } catch (IOException e) { + release(); + throw e; + } + } + + public final synchronized void setQueueDepth(int queue_depth) throws IOException { + checkReleased(); + stop(); + close(); + createQueue(queue_depth); + } + + private final void createQueue(int queue_depth) throws IOException { + open(queue_depth); + try { + start(); + } catch (IOException e) { + close(); + throw e; + } + } + + public final OSXComponent mapEvent(OSXEvent event) { + return (OSXComponent)map.get(new Long(event.getCookie())); + } + + private final void open(int queue_depth) throws IOException { + nOpen(queue_address, queue_depth); + } + private final static native void nOpen(long queue_address, int queue_depth) throws IOException; + + private final void close() throws IOException { + nClose(queue_address); + } + private final static native void nClose(long queue_address) throws IOException; + + private final void start() throws IOException { + nStart(queue_address); + } + private final static native void nStart(long queue_address) throws IOException; + + private final void stop() throws IOException { + nStop(queue_address); + } + private final static native void nStop(long queue_address) throws IOException; + + public final synchronized void release() throws IOException { + if (!released) { + released = true; + try { + stop(); + close(); + } finally { + nReleaseQueue(queue_address); + } + } + } + private final static native void nReleaseQueue(long queue_address) throws IOException; + + public final void addElement(OSXHIDElement element, OSXComponent component) throws IOException { + nAddElement(queue_address, element.getCookie()); + map.put(new Long(element.getCookie()), component); + } + private final static native void nAddElement(long queue_address, long cookie) throws IOException; + + public final void removeElement(OSXHIDElement element) throws IOException { + nRemoveElement(queue_address, element.getCookie()); + map.remove(new Long(element.getCookie())); + } + private final static native void nRemoveElement(long queue_address, long cookie) throws IOException; + + public final synchronized boolean getNextEvent(OSXEvent event) throws IOException { + checkReleased(); + return nGetNextEvent(queue_address, event); + } + private final static native boolean nGetNextEvent(long queue_address, OSXEvent event) throws IOException; + + private final void checkReleased() throws IOException { + if (released) + throw new IOException("Queue is released"); + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXJoystick.java b/plugins/OSX/src/java/net/java/games/input/OSXJoystick.java deleted file mode 100644 index f20fb57..0000000 --- a/plugins/OSX/src/java/net/java/games/input/OSXJoystick.java +++ /dev/null @@ -1,280 +0,0 @@ -package net.java.games.input; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Joystick class which recognizes most of the enhanced joystick features - * including: - * x, y, and z axis - * x, y axis rotation - * slider - * hat - * - */ -public class OSXJoystick extends AbstractController implements InputController -{ - private OSXEnvironmentPlugin plugin; - private long lpDevice; - private long lpQueue; - private int buttonCount = 0; - private List buttons = new ArrayList(); - - private Axis xAxis = null; - private Axis yAxis = null; - private Axis zAxis = null; - private Axis xAxisRotation = null; - private Axis yAxisRotation = null; - private Axis zAxisRotation = null; - private Axis slider = null; - private Axis hat = null; - - public OSXJoystick( OSXEnvironmentPlugin plugin, long lpDevice, String productName ) - { - super( productName ); - - this.plugin = plugin; - this.lpDevice = lpDevice; - - openDevice(); - } - - /** - * Returns the type of the Controller. - */ - public Type getType() { - return Type.STICK; - } - - public boolean poll() - { - plugin.pollDevice( lpQueue ); - - return true; - } - - public void openDevice() - { - this.lpQueue = plugin.openDevice( this.lpDevice, 32 ); - } - - public void closeDevice() - { - plugin.closeDevice( this.lpDevice, this.lpQueue ); - } - - public void pollDevice() - { - plugin.pollDevice( this.lpQueue ); - } - - public Component[] getComponents() { - List cpList = new ArrayList(buttons); - if (xAxis != null) cpList.add(xAxis); - if (yAxis != null) cpList.add(yAxis); - if (zAxis != null) cpList.add(zAxis); - if (xAxisRotation != null) cpList.add(xAxisRotation); - if (yAxisRotation != null) cpList.add(yAxisRotation); - if (zAxisRotation != null) cpList.add(zAxisRotation); - if (slider != null) cpList.add(slider); - if (hat != null) cpList.add(hat); - Component[] ca = new Component[cpList.size()]; - return (Component[]) cpList.toArray(ca); - } - - - public void addControllerElement(InputControllerElement element) - { - - switch ( element.getElementType() ) - { - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_BUTTON: - Button button = null; - switch (buttonCount) { - case 0: - button = new Button(Component.Identifier.Button.TRIGGER, element); - break; - case 1: - button = new Button(Component.Identifier.Button._2, element); - break; - case 2: - button = new Button(Component.Identifier.Button._3, element); - break; - case 3: - button = new Button(Component.Identifier.Button._4, element); - break; - case 4: - button = new Button(Component.Identifier.Button._5, element); - break; - case 5: - button = new Button(Component.Identifier.Button._6, element); - break; - case 6: - button = new Button(Component.Identifier.Button._7, element); - break; - case 7: - button = new Button(Component.Identifier.Button._8, element); - break; - case 8: - button = new Button(Component.Identifier.Button._9, element); - break; - default: - String name = String.valueOf(buttonCount + 1); - button = new Button(new Component.Identifier.Button(name), element); - break; - } - buttons.add(button); - buttonCount++; - System.out.println("Adding button [" + buttonCount + "]"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_MISC: - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_AXIS: - switch (element.getUsage()) { - case OSXEnvironmentPlugin.HID_USAGE_XAXIS: - xAxis = new Axis(Component.Identifier.Axis.X, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_YAXIS: - yAxis = new Axis(Component.Identifier.Axis.Y, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_ZAXIS: - zAxis = new Axis(Component.Identifier.Axis.Z, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_XAXIS_ROTATION: - xAxisRotation = new Axis(Component.Identifier.Axis.RX, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_YAXIS_ROTATION: - yAxisRotation = new Axis(Component.Identifier.Axis.RY, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_ZAXIS_ROTATION: - zAxisRotation = new Axis(Component.Identifier.Axis.RZ, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_SLIDER: - slider = new Axis(Component.Identifier.Axis.SLIDER, element); - break; - case OSXEnvironmentPlugin.HID_USAGE_HAT: - hat = new Axis(Component.Identifier.Axis.POV, element); - break; - default: - System.out.println("*Unknown axis"); - break; - } - - System.out.println("*Adding axis"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_SCANCODES: - System.out.println("*Adding scancode"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_OUTPUT: - System.out.println("*Adding forcefeedback"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_FEATURE: - - System.out.println("*Adding feature"); - break; - - case OSXEnvironmentPlugin.HID_ELEMENTTYPE_COLLECTION: - System.out.println("*Adding collection"); - break; - - } - } - - /** - * Mouse button axis implementation - */ - class Button extends AbstractComponent - { - - private long hidCookie; - private boolean isRelative; - - - - /** Public constructor - * @param id An ID of a button to create an obejct to represent. - * - */ - public Button(Component.Identifier.Button id, InputControllerElement element) - { - super(id.getName(), id); - this.hidCookie = element.getHidCookie(); - this.isRelative = element.isRelative(); - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return state of controller. (Note: DX8 mice actually - * queue state so what is returned is the next state, - * not necessarily the most current one.) - */ - public float getPollData() - { - return (float) plugin.pollElement( lpDevice, hidCookie ); - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if data is relative, otherwise false. - */ - public boolean isRelative() - { - return isRelative; - } - } - - - /** - * Mouse button axis implementation - */ - class Axis extends AbstractComponent - { - - private long hidCookie; - private boolean isRelative; - - /** Public constructor - * @param id An ID of a button to create an obejct to represent. - * - */ - public Axis(Component.Identifier id, InputControllerElement element) - { - super(id.getName(), id); - this.hidCookie = element.getHidCookie(); - this.isRelative = element.isRelative(); - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return state of controller. (Note: DX8 mice actually - * queue state so what is returned is the next state, - * not necessarily the most current one.) - */ - public float getPollData() - { - return (float) plugin.pollElement( lpDevice, hidCookie ); - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if data is relative, otherwise false. - */ - public boolean isRelative() - { - return isRelative; - } - } - - -} diff --git a/plugins/OSX/src/java/net/java/games/input/OSXKeyboard.java b/plugins/OSX/src/java/net/java/games/input/OSXKeyboard.java index c717f8a..f545264 100644 --- a/plugins/OSX/src/java/net/java/games/input/OSXKeyboard.java +++ b/plugins/OSX/src/java/net/java/games/input/OSXKeyboard.java @@ -1,253 +1,68 @@ -package net.java.games.input; - -import java.util.HashMap; - -/** - * Created by IntelliJ IDEA. - * User: gpierce - * Date: Aug 2, 2003 - * Time: 3:57:58 PM - * To change this template use Options | File Templates. +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ -public class OSXKeyboard extends StandardKeyboard implements InputController -{ - - private final static int[] CROSSTABLE = { - 0x00, // VOID - 0x29, // ESCAPE - 0x1E, // _1 - 0x1F, // _2 - 0x20, // _3 - 0x21, // _4 - 0x22, // _5 - 0x23, // _6 - 0x24, // _7 - 0x25, // _8 - 0x26, // _9 - 0x27, // _0 - 0x2D, // MINUS - 0x2E, // EQUALS - 0x2A, // BACK - 0x2B, // TAB - 0x14, // Q - 0x1A, // W - 0x08, // E - 0x15, // R - 0x17, // T - 0x1C, // Y - 0x18, // U - 0x0C, // I - 0x12, // O - 0x13, // P - 0x2F, // [ - 0x30, // ] - 0x28, // RETURN - 0xE0, // LEFT CONTROL - 0x04, // A - 0x16, // S - 0x07, // D - 0x09, // F - 0x0A, // G - 0x0B, // H - 0x0D, // J - 0x0E, // K - 0x0F, // L - 0x33, // ; - 0x34, // ' - 0x35, // ~ - 0xE1, // / - 0x31, // BACKSLASH (\) - 0x1D, // Z - 0x1B, // X - 0x06, // C - 0x19, // V - 0x05, // B - 0x11, // N - 0x10, // M - 0x36, // , - 0x37, // . - 0x38, // SLASH (/) - 0xE5, // RSHIFT - 0x55, // MULT (*) - 0xE2, // LEFT ALT - 0x2C, // SPACE - 0x39, // CAPSLOCK - 0x3A, // F1 - 0x3B, // F2 - 0x3C, // F3 - 0x3D, // F4 - 0x3E, // F5 - 0x3F, // F6 - 0x40, // F7 - 0x41, // F8 - 0x42, // F9 - 0x43, // F10 - 0x53, // NUMLOCK - 0x47, // SCROLLLOCK - 0x5F, // NUMPAD7 - 0x60, // NUMPAD8 - 0x61, // NUMPAD9 - 0x56, // SUBTRACT (KEYPAD -) - 0x5C, // NUMPAD4 - 0x5D, // NUMPAD5 - 0x5E, // NUMPAD6 - 0x57, // ADD (KEYPAD +) - 0x59, // NUMPAD1 - 0x5A, // NUMPAD2 - 0x5B, // NUMPAD3 - 0x62, // NUMPAD0 - 0x63, // DECIMAL (KEYPAD .) - 0x44, // F11 - 0x45, // F12 - 0x68, // F13 - 0x69, // F14 - 0x6A, // F15 - 0x87, // KANA - 0x88, // CONVERT - 0x89, // NONCONVERT - 0x8A, // YEN - 0x67, // NUMPAD= - 0x8B, // CIRCUMFLEX - 0x8C, // AT - 0x8D, // COLON - 0x9F, // UNDERLINE - 0x8E, // KANJI - 0x78, // STOP - 0x8F, // AX - 0x90, // UNLABELED - 0x58, // NUMPAD ENTER - 0xE4, // RIGHT CONTROL - 0x85, // NUMPAD COMMA - 0x54, // DIVIDE ( NUMPAD /) - 0x9A, // SYSREQ - 0xE6, // RIGHT ALT - 0x48, // PAUSE - 0x4A, // HOME - 0x52, // UP - 0x9D, // PRIOR - 0x50, // LEFT - 0x4F, // RIGHT - 0x4D, // END - 0x51, // DOWN - 0xA2, // NEXT - 0x49, // INSERT - 0x4C, // DELETE - 0xE3, // LEFT WIN - 0xE7, // RIGHT WIN - 0x65, // APPS - 0x66, // POWER - 0x66 // SLEEP - }; - - private OSXEnvironmentPlugin plugin; - private long lpDevice; - private long lpQueue; - private HashMap keys = new HashMap(); - - private static int[] COOKIETABLE = new int[CROSSTABLE.length ]; - - public OSXKeyboard( OSXEnvironmentPlugin plugin, long lpDevice, String productName ) - { - super( productName ); - - this.plugin = plugin; - this.lpDevice = lpDevice; - - openDevice(); - } - - public void openDevice() - { - this.lpQueue = plugin.openDevice( this.lpDevice, 256 ); - } - - public void closeDevice() - { - plugin.closeDevice( this.lpDevice, this.lpQueue ); - } - - public void addControllerElement(InputControllerElement element) - { - System.out.println("Adding keyboard elements usage page[" + element.getUsagePage() + "] usage [" + element.getUsage() + "] type [" + element.getElementType() + "]" ); - - switch( element.getUsagePage() ) - { - case OSXEnvironmentPlugin.HID_USAGEPAGE_KEYBOARD: - - System.out.println("Found keyboard element"); - - if ( element.getElementType() == OSXEnvironmentPlugin.HID_ELEMENTTYPE_INPUT_BUTTON ) - { - // register this key with the queue system as all buttons are retrieved from the - // input controllers queue - // - System.out.println("Registering button-key (usage page [" + element.getUsagePage() + "], usage[" + element.getUsage() + "], elementType [" + element.getElementType() + "], hidCookie [" + element.getHidCookie() + "])"); - - - if ( keys.get( new Long( element.getUsage() )) == null ) - { - plugin.registerDeviceElement( lpQueue, element.getHidCookie() ); - - keys.put( new Long( element.getUsage() ), element ); - System.out.println("Registered key [" + element.getHidCookie() + "]"); - } - else - { - System.out.println("Ignoring key [" + element.getHidCookie() + "] already enumerated."); - } - } - else - { - System.out.println("Ignoring non-button-key (usage page [" + element.getUsagePage() + "], usage[" + element.getUsage() + "], elementType [" + element.getElementType() + "], hidCookie [" + element.getHidCookie() + "])"); - } - break; - - default: - } - } - - public boolean poll() - { - plugin.pollDevice( lpQueue ); - - - return true; - } - - - /** Returns whether or not the given key has been pressed since the last - * call to poll. - * @param key The key whose state to check. - * @return true if this key has changed state since last read of its state, false otherwise. - */ - protected boolean isKeyPressed(Keyboard.Key key) - { - Component.Identifier.Key id = (Component.Identifier.Key) key.getIdentifier(); - int keyIndex = id.getKeyIndex(); - - // get that key code out of the crosstable and find the proper InputControllerElement/button for that key - // - //TODO: Optimize this - put the usages in another array the same size as the crosstable so the hidCookies - // can be retrieved directly without the Long creation - int usage = CROSSTABLE[keyIndex]; - InputControllerElement element = (InputControllerElement) keys.get( new Long(usage) ); - - - if ( element != null ) - { - int value = plugin.pollElement( lpDevice, element.getHidCookie() ); - - System.out.println("Key Poll result [" + value + "]"); - if ( value == 1 ) - { - return true; - } - else - { - return false; - } - } +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; - return false; - } +import java.io.IOException; + +/** Represents an OSX Keyboard +* @author elias +* @version 1.0 +*/ +final class OSXKeyboard extends Keyboard { + private final PortType port; + private final OSXHIDQueue queue; + + protected OSXKeyboard(OSXHIDDevice device, OSXHIDQueue queue, Component[] components, Controller[] children, Rumbler[] rumblers) { + super(device.getProductName(), components, children, rumblers); + this.queue = queue; + this.port = device.getPortType(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return OSXControllers.getNextDeviceEvent(event, queue); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + queue.setQueueDepth(size); + } + + public final PortType getPortType() { + return port; + } } diff --git a/plugins/OSX/src/java/net/java/games/input/OSXMouse.java b/plugins/OSX/src/java/net/java/games/input/OSXMouse.java index 2abeb67..8f5244b 100644 --- a/plugins/OSX/src/java/net/java/games/input/OSXMouse.java +++ b/plugins/OSX/src/java/net/java/games/input/OSXMouse.java @@ -1,251 +1,68 @@ -package net.java.games.input; - -/** - * Created by IntelliJ IDEA. - * User: gpierce - * Date: Aug 2, 2003 - * Time: 3:57:00 PM - * To change this template use Options | File Templates. +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ -public class OSXMouse extends Mouse implements InputController -{ - private OSXEnvironmentPlugin plugin; - private long lpDevice; - private long lpQueue; - private int buttonCount = 0; - - - public OSXMouse( OSXEnvironmentPlugin plugin, long lpDevice, String productName ) - { - super( productName ); - - this.plugin = plugin; - this.lpDevice = lpDevice; - - openDevice(); - - buttons = new ButtonsImpl(); - ball = new BallImpl(); - } - - public void openDevice() - { - this.lpQueue = plugin.openDevice( this.lpDevice, 32 ); - } - - public void closeDevice() - { - plugin.closeDevice( this.lpDevice, this.lpQueue ); - } - - public boolean poll() - { - plugin.pollDevice( this.lpQueue ); - - return true; - } - - public void addControllerElement(InputControllerElement element) - { - - switch ( element.getUsagePage() ) - { - case OSXEnvironmentPlugin.HID_USAGEPAGE_BUTTON: - buttonCount ++; - System.out.println("Adding button [" + buttonCount + "]"); - ((ButtonsImpl)buttons).addButton(element); - break; - - - case OSXEnvironmentPlugin.HID_USAGEPAGE_GENERICDESKTOP: - switch( element.getUsage() ) - { - case OSXEnvironmentPlugin.HID_USAGE_POINTER: - System.out.println("Adding pointer - this will contain axis"); - break; - - case OSXEnvironmentPlugin.HID_USAGE_XAXIS: - ((BallImpl)ball).addXAxis(element); - System.out.println("Adding X Axis") ; - break; - - case OSXEnvironmentPlugin.HID_USAGE_YAXIS: - ((BallImpl)ball).addYAxis(element); - System.out.println("Adding Y Axis"); - break; - - case OSXEnvironmentPlugin.HID_USAGE_WHEEL: - ((BallImpl)ball).addWheelAxis(element); - System.out.println("Adding wheel"); - break; - - default: - - } - break; - - - default: - - } - } - - /** - * Implementation class representing the mouse ball - */ - class BallImpl extends Ball - { - /** - * Public constructor - */ - public BallImpl() - { - super(OSXMouse.this.getName() + " ball"); - } - - public void addXAxis( InputControllerElement element ) - { - x = new BallAxis(Component.Identifier.Axis.X, element ); - } - - public void addYAxis( InputControllerElement element ) - { - y = new BallAxis( Component.Identifier.Axis.Y, element ); - } - - public void addWheelAxis( InputControllerElement element ) - { - wheel = new BallAxis( Component.Identifier.Axis.SLIDER, element ); - } - } - - - /** - * Implementation class representing the mouse buttons - */ - class ButtonsImpl extends Buttons - { - /** - * Public constructor - */ - public ButtonsImpl() - { - super(OSXMouse.this.getName() + " buttons"); - } - - public void addButton( InputControllerElement element ) - { - if ( left == null ) - { - left = new ButtonImpl( Component.Identifier.Button.LEFT, element ); - } - else if ( right == null ) - { - right = new ButtonImpl( Component.Identifier.Button.RIGHT, element ); - } - else if ( middle == null ) - { - middle = new ButtonImpl( Component.Identifier.Button.MIDDLE, element ); - } - } - } - - /** - * Mouse button axis implementation - */ - class ButtonImpl extends Button - { - - private long hidCookie; - private boolean isRelative; - - - /** Public constructor - * @param id An ID of a button to create an obejct to represent. - * - */ - public ButtonImpl(Component.Identifier.Button id, InputControllerElement element) - { - super(id.getName(), id); - this.hidCookie = element.getHidCookie(); - this.isRelative = element.isRelative(); - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return state of controller. (Note: DX8 mice actually - * queue state so what is returned is the next state, - * not necessarily the most current one.) - */ - public float getPollData() - { - return (float) plugin.pollElement( lpDevice, hidCookie ); - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if data is relative, otherwise false. - */ - public boolean isRelative() - { - return isRelative; - } - } - - - /** - * Mouse ball axis implementation - */ - class BallAxis extends AbstractComponent - { - - private long hidCookie; - private boolean isRelative; - - /** Public constructor - * @param id An ID for a mouse axis to create an object to represent. - */ - public BallAxis(Component.Identifier.Axis id, InputControllerElement element) - { - super(id.getName(), id); - - this.hidCookie = element.getHidCookie(); - this.isRelative = element.isRelative(); - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return data. (Note that mice queue state in DX8 so what - * is returned is the next stae in the queue, not - * necessarily the most current one.) - */ - public float getPollData() - { - return (float) plugin.pollElement( lpDevice, hidCookie ); - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return true if relative, otherwise false. - */ - public boolean isRelative() - { - return isRelative; - } - - /** Returns whether or not the axis is analog, or false if it is digital. - * @return true if analog, false if digital - */ - public boolean isAnalog() - { - return true; - } - } +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; +import java.io.IOException; + +/** Represents an OSX Mouse +* @author elias +* @version 1.0 +*/ +final class OSXMouse extends Mouse { + private final PortType port; + private final OSXHIDQueue queue; + + protected OSXMouse(OSXHIDDevice device, OSXHIDQueue queue, Component[] components, Controller[] children, Rumbler[] rumblers) { + super(device.getProductName(), components, children, rumblers); + this.queue = queue; + this.port = device.getPortType(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return OSXControllers.getNextDeviceEvent(event, queue); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + queue.setQueueDepth(size); + } + + public final PortType getPortType() { + return port; + } } diff --git a/plugins/OSX/src/java/net/java/games/input/Usage.java b/plugins/OSX/src/java/net/java/games/input/Usage.java new file mode 100644 index 0000000..8b79b3a --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/Usage.java @@ -0,0 +1,46 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +/** Generic Desktop Usages +* @author elias +* @version 1.0 +*/ +public interface Usage { +} diff --git a/plugins/OSX/src/java/net/java/games/input/UsagePage.java b/plugins/OSX/src/java/net/java/games/input/UsagePage.java new file mode 100644 index 0000000..bd50eab --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/UsagePage.java @@ -0,0 +1,114 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.lang.reflect.Method; + +/** HID Usage pages +* @author elias +* @version 1.0 +*/ +final class UsagePage { + private final static UsagePage[] map = new UsagePage[0xFF]; + + public final static UsagePage UNDEFINED = new UsagePage(0x00); + public final static UsagePage GENERIC_DESKTOP = new UsagePage(0x01, GenericDesktopUsage.class); + public final static UsagePage SIMULATION = new UsagePage(0x02); + public final static UsagePage VR = new UsagePage(0x03); + public final static UsagePage SPORT = new UsagePage(0x04); + public final static UsagePage GAME = new UsagePage(0x05); + /* Reserved 0x06 */ + public final static UsagePage KEYBOARD_OR_KEYPAD = new UsagePage(0x07, KeyboardUsage.class); /* USB Device Class Definition for Human Interface Devices (HID). Note: the usage type for all key codes is Selector (Sel). */ + public final static UsagePage LEDS = new UsagePage(0x08); + public final static UsagePage BUTTON = new UsagePage(0x09, ButtonUsage.class); + public final static UsagePage ORDINAL = new UsagePage(0x0A); + public final static UsagePage TELEPHONY = new UsagePage(0x0B); + public final static UsagePage CONSUMER = new UsagePage(0x0C); + public final static UsagePage DIGITIZER = new UsagePage(0x0D); + /* Reserved 0x0E */ + public final static UsagePage PID = new UsagePage(0x0F); /* USB Physical Interface Device definitions for force feedback and related devices. */ + public final static UsagePage UNICODE = new UsagePage(0x10); + /* Reserved 0x11 - 0x13 */ + public final static UsagePage ALPHANUMERIC_DISPLAY = new UsagePage(0x14); + /* Reserved 0x15 - 0x7F */ + /* Monitor 0x80 - 0x83 USB Device Class Definition for Monitor Devices */ + /* Power 0x84 - 0x87 USB Device Class Definition for Power Devices */ + public final static UsagePage POWER_DEVICE = new UsagePage(0x84); /* Power Device Page */ + public final static UsagePage BATTERY_SYSTEM = new UsagePage(0x85); /* Battery System Page */ + /* Reserved 0x88 - 0x8B */ + public final static UsagePage BAR_CODE_SCANNER = new UsagePage(0x8C); /* (Point of Sale) USB Device Class Definition for Bar Code Scanner Devices */ + public final static UsagePage SCALE = new UsagePage(0x8D); /* (Point of Sale) USB Device Class Definition for Scale Devices */ + /* ReservedPointofSalepages 0x8E - 0X8F */ + public final static UsagePage CAMERACONTROL= new UsagePage(0x90); /* USB Device Class Definition for Image Class Devices */ + public final static UsagePage ARCADE = new UsagePage(0x91); /* OAAF Definitions for arcade and coinop related Devices */ + private final Class usage_class; + private final int usage_page_id; + + public final static UsagePage map(int page_id) { + if (page_id < 0 || page_id >= map.length) + return null; + return map[page_id]; + } + + private UsagePage(int page_id, Class usage_class) { + map[page_id] = this; + this.usage_class = usage_class; + this.usage_page_id = page_id; + } + + private UsagePage(int page_id) { + this(page_id, null); + } + + public final String toString() { + return "UsagePage (0x" + Integer.toHexString(usage_page_id) + ")"; + } + + public final Usage mapUsage(int usage_id) { + if (usage_class == null) + return null; + try { + Method map_method = usage_class.getMethod("map", new Class[]{int.class}); + Object result = map_method.invoke(null, new Object[]{new Integer(usage_id)}); + return (Usage)result; + } catch (Exception e) { + throw new Error(e); + } + } +} diff --git a/plugins/OSX/src/java/net/java/games/input/UsagePair.java b/plugins/OSX/src/java/net/java/games/input/UsagePair.java new file mode 100644 index 0000000..8d0b883 --- /dev/null +++ b/plugins/OSX/src/java/net/java/games/input/UsagePair.java @@ -0,0 +1,76 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +/** Usage/Page pair +* @author elias +* @version 1.0 +*/ +class UsagePair { + private final UsagePage usage_page; + private final Usage usage; + + public UsagePair(UsagePage usage_page, Usage usage) { + this.usage_page = usage_page; + this.usage = usage; + } + + public final UsagePage getUsagePage() { + return usage_page; + } + + public final Usage getUsage() { + return usage; + } + + public final int hashCode() { + return usage.hashCode() ^ usage_page.hashCode(); + } + + public final boolean equals(Object other) { + if (!(other instanceof UsagePair)) + return false; + UsagePair other_pair = (UsagePair)other; + return other_pair.usage.equals(usage) && other_pair.usage_page.equals(usage_page); + } + + public final String toString() { + return "UsagePair: (page = " + usage_page + ", usage = " + usage + ")"; + } +} diff --git a/plugins/OSX/src/native/build.xml b/plugins/OSX/src/native/build.xml index b88c856..9b338da 100644 --- a/plugins/OSX/src/native/build.xml +++ b/plugins/OSX/src/native/build.xml @@ -1,23 +1,67 @@ <?xml version="1.0" ?> <project name="OS X Plugin, Native code" basedir="." default="compileNativeJinputLib"> - <description>OSX JInput Native Plugin</description> - <property name="src" location="src" /> - <property name="build" location="classes" /> - <property name="dist" location="../../dist" /> - <property name="plugins" location="plugins" /> - - <target name="init"> - <mkdir dir="build"/> - </target> + <description>OSX JInput Native Plugin</description> - <target name="compileNativeJinputLib" depends="init"> - <exec dir="." executable="cc" os="Mac OS X"> - - <arg line="-c -I${java.home}/include jinputjnilib.c"/> - </exec> - <exec dir="." executable="cc" os="Mac OS X"> - <arg line="-bundle -o libjinput.jnilib jinputjnilib.o -framework JavaVM -framework CoreFoundation -framework IOKit "/> - </exec> - </target> + <target name="init"> + <mkdir dir="universal"/> + <mkdir dir="legacy"/> + </target> + + <target name="clean"> + <delete failonerror="false"> + <fileset dir="universal"/> + <fileset dir="legacy"/> + </delete> + </target> + <target name="compile"> + <apply dir="${dstdir}" executable="${compiler}" os="Mac OS X" skipemptyfilesets="true" failonerror="true" dest="${dstdir}"> + <arg line="${cflags} -O2 -Wall -c -fPIC -I${sdkroot}/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -I../../../../common/src/native -I.."/> + <mapper type="glob" from="*.c" to="*.o"/> + <fileset dir="." includes="*.c"/> + <fileset dir="../../../common/src/native" includes="*.c"/> + </apply> + </target> + + <target name="link"> + <apply dir="." parallel="true" executable="${linker}" os="Mac OS X" failonerror="true"> + <arg line="${linkerflags} -dynamiclib -o ${libname} -framework JavaVM -framework CoreFoundation -framework IOKit -framework CoreServices"/> + <fileset dir="${objdir}" includes="*.o"/> + </apply> + <apply dir="." parallel="true" executable="strip" os="Mac OS X" failonerror="true"> + <arg line="-S -X"/> + <fileset dir="." includes="*.jnilib"/> + </apply> + </target> + + <target name="compileNativeJinputLib" depends="init"> + <property name="universal_sdkroot" location="/Developer/SDKs/MacOSX10.4u.sdk"/> + <property name="legacy_sdkroot" location="/Developer/SDKs/MacOSX10.3.9.sdk"/> + <property name="universal_flags" value="-isysroot ${universal_sdkroot} -arch i386 -arch ppc"/> + <antcall target="compile"> + <param name="dstdir" location="universal"/> + <param name="compiler" value="gcc-4.0"/> + <param name="sdkroot" location="${universal_sdkroot}"/> + <param name="cflags" value="${universal_flags}"/> + </antcall> + <antcall target="link"> + <param name="objdir" location="universal"/> + <param name="libname" value="libjinput-osx.jnilib"/> + <param name="linker" value="gcc-4.0"/> + <!-- <param name="linkerflags" value="${universal_flags} -Wl,-syslibroot,${universal_sdkroot}"/>--> + <param name="linkerflags" value="${universal_flags}"/> + </antcall> + <antcall target="compile"> + <param name="dstdir" location="legacy"/> + <param name="compiler" value="gcc-3.3"/> + <param name="sdkroot" location="${legacy_sdkroot}"/> + <param name="cflags" value=""/> + </antcall> + <antcall target="link"> + <param name="objdir" location="legacy"/> + <param name="libname" value="libjinput-osx-legacy.jnilib"/> + <param name="linker" value="gcc-3.3"/> + <param name="linkerflags" value=""/> + </antcall> + </target> </project> diff --git a/plugins/OSX/src/native/jinputjnilib.c b/plugins/OSX/src/native/jinputjnilib.c deleted file mode 100644 index 86c7347..0000000 --- a/plugins/OSX/src/native/jinputjnilib.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - * %W% %E% - * - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -/***************************************************************************** -* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* - Redistribution of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* - Redistribution in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materails provided with the distribution. -* -* Neither the name Sun Microsystems, Inc. or the names of the contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* This software is provided "AS IS," without a warranty of any kind. -* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING -* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR -* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND -* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS -* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS -* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST -* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, -* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY -* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, -* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -* -* You acknowledge that this software is not designed or intended for us in -* the design, construction, operation or maintenance of any nuclear facility -* -*****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <ctype.h> -#include <sys/errno.h> -#include <sysexits.h> -#include <mach/mach.h> -#include <mach/mach_error.h> -#include <IOKit/IOKitLib.h> -#include <IOKit/IOCFPlugIn.h> -#include <IOKit/hid/IOHIDLib.h> -#include <IOKit/hid/IOHIDKeys.h> -#include <CoreFoundation/CoreFoundation.h> -#include <Carbon/Carbon.h> -#include "net_java_games_input_OSXEnvironmentPlugin.h" - -Boolean init( JNIEnv * env ); -void createMasterPort(); -void disposeMasterPort(); - - -void createHIDDevice(io_object_t hidDevice, IOHIDDeviceInterface ***hidDeviceInterface); -IOReturn openDevice(IOHIDDeviceInterface ***hidDeviceInterface); -IOReturn closeDevice(IOHIDDeviceInterface ***hidDeviceInterface); - - -Boolean showDictionaryElement (CFDictionaryRef dictionary, CFStringRef key); -void showProperty(const void * key, const void * value); -void displayCFProperty(CFStringRef object, CFTypeRef value); -void CFObjectShow( CFTypeRef value ); -void CFObjectSend( CFTypeRef value ); - -jclass CLASS_JNIWrapper = NULL; -jmethodID MID_AddController = NULL; -jmethodID MID_AddControllerElement = NULL; -mach_port_t masterPort = NULL; -io_iterator_t hidObjectIterator; - -long elementCookie; -long elementType; -long usage; -long usagePage; -long min; -long max; -long scaledMin; -long scaledMax; -long size; -jboolean isRelative; -jboolean isWrapping; -jboolean isNonLinear; - - -JNIEnv * lpEnv; -jlong lpDevice; -jobject lpObj; -jboolean completeElement = JNI_FALSE; - - - - -Boolean showDictionaryElement (CFDictionaryRef dictionary, CFStringRef key) -{ - CFTypeRef value = CFDictionaryGetValue (dictionary, key); - if (value) - { - const char * c = CFStringGetCStringPtr (key, CFStringGetSystemEncoding ()); - if (c) - { - printf ("%s", c); - } - else - { - CFIndex bufferSize = CFStringGetLength (key) + 1; - char * buffer = (char *)malloc (bufferSize); - if (buffer) - { - if (CFStringGetCString (key, buffer, bufferSize, CFStringGetSystemEncoding ())) - printf ("%s", buffer); - free(buffer); - } - } - - printf("="); - - CFObjectShow( value ); - - printf("\n"); - } - return (value != NULL); -} - -static void showCFArray (const void * value, void * parameter) -{ - if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) - { - return; - } - - CFObjectShow(value); -} - -void CFObjectShow( CFTypeRef value ) -{ - CFTypeID type = CFGetTypeID(value); - if (type == CFArrayGetTypeID()) - { - CFRange range = {0, CFArrayGetCount (value)}; - - //Show an element array containing one or more element dictionaries - CFArrayApplyFunction (value, range, showCFArray, 0); - } - else if (type == CFBooleanGetTypeID()) - { - printf(CFBooleanGetValue(value) ? "true" : "false"); - } - else if (type == CFDictionaryGetTypeID()) - { - printf("Map\n"); - - - showDictionaryElement (value, CFSTR(kIOHIDElementCookieKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementCollectionTypeKey)); - - showDictionaryElement (value, CFSTR(kIOHIDElementMinKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementMaxKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementScaledMinKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementScaledMaxKey)); - - showDictionaryElement (value, CFSTR(kIOHIDElementSizeKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementIsRelativeKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementIsWrappingKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementIsNonLinearKey)); -#ifdef kIOHIDElementHasPreferredStateKey - showDictionaryElement (value, CFSTR(kIOHIDElementHasPreferredStateKey)); -#else - showDictionaryElement (value, CFSTR(kIOHIDElementHasPreferedStateKey)); -#endif - showDictionaryElement (value, CFSTR(kIOHIDElementHasNullStateKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementVendorSpecificKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementUnitKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementUnitExponentKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementNameKey)); - showDictionaryElement (value, CFSTR(kIOHIDElementKey)); - - printf("\n\n\n"); - } - else if (type == CFNumberGetTypeID()) - { - long number; - if (CFNumberGetValue (value, kCFNumberLongType, &number)) - { - printf("0x%lx (%ld)", number, number); - } - } - else if (type == CFStringGetTypeID()) - { - const char * c = CFStringGetCStringPtr (value, CFStringGetSystemEncoding ()); - if (c) - { - printf ("%s", c); - } - else - { - CFIndex bufferSize = CFStringGetLength (value) + 1; - char * buffer = (char *)malloc (bufferSize); - if (buffer) - { - if (CFStringGetCString (value, buffer, bufferSize, CFStringGetSystemEncoding ())) - { - printf ("%s", buffer); - } - - free(buffer); - } - } - } -} - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// - -Boolean init(JNIEnv* env) -{ - CLASS_JNIWrapper = (*env)->FindClass(env,"net/java/games/input/OSXEnvironmentPlugin"); - if ( CLASS_JNIWrapper == NULL ) - { - printf("Class OSXEnvironmentPlugin not found... \n"); - return FALSE; - } - - MID_AddController = (*env)->GetMethodID(env, CLASS_JNIWrapper, "addController", "(JLjava/lang/String;I)V"); - if (MID_AddController == NULL) - { - printf("Method addController not found... \n"); - return FALSE; - } - - MID_AddControllerElement = (*env)->GetMethodID(env, CLASS_JNIWrapper, "addControllerElement", "(JJIIIIIIIIZZZZZ)V"); - if (MID_AddControllerElement == NULL) - { - printf("Method addControllerElement not found... \n"); - return FALSE; - } - - return TRUE; -} - -void createMasterPort() -{ - IOReturn ioReturnValue = kIOReturnSuccess; - - //Get a Mach port to initiate communication with I/O Kit. - // - ioReturnValue = IOMasterPort(bootstrap_port, &masterPort); -} - -void disposeMasterPort() -{ - //Free master port if we created one. - // - if (masterPort) - { - mach_port_deallocate(mach_task_self(), masterPort); - } -} - -void createHIDDevice( io_object_t hidDevice, IOHIDDeviceInterface ***hidDeviceInterface ) -{ - io_name_t className; - IOCFPlugInInterface **plugInInterface = NULL; - HRESULT plugInResult = S_OK; - SInt32 score = 0; - IOReturn ioReturnValue = kIOReturnSuccess; - - ioReturnValue = IOObjectGetClass(hidDevice, className); - if ( ioReturnValue != kIOReturnSuccess ) - { - printf("Failed to get IOObject class name."); - } - - printf("Found device type [%s]\n", className); - - ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score); - - if (ioReturnValue == kIOReturnSuccess) - { - //Call a method of the intermediate plug-in to create the device - //interface - // - plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, - CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), - (LPVOID) hidDeviceInterface); - if ( plugInResult != S_OK ) - { - printf("Couldn't create HID class device interface"); - } - - (*plugInInterface)->Release(plugInInterface); - } -} - -IOReturn openDevice(IOHIDDeviceInterface ***hidDeviceInterface) -{ - IOReturn ioReturnValue = kIOReturnSuccess; - - //todo, change this to be controlled from the java layer at each device - // - ioReturnValue = (**hidDeviceInterface)->open(*hidDeviceInterface, 0 ); - if ( ioReturnValue != kIOReturnSuccess ) - { - printf("Unable to open device - return [%d]\n", ioReturnValue ); - } - else - { - printf("Successfully opened device \n"); - } - - return ioReturnValue; -} - -IOReturn closeDevice(IOHIDDeviceInterface ***hidDeviceInterface) -{ - IOReturn ioReturnValue = kIOReturnSuccess; - - ioReturnValue = (**hidDeviceInterface)->close(*hidDeviceInterface); - if ( ioReturnValue != kIOReturnSuccess ) - { - printf("Unable to close device - return [%d]\n", ioReturnValue ); - } - else - { - printf("Successfully closed device \n"); - } - - // release the device interface - // - (**hidDeviceInterface)->Release(*hidDeviceInterface); - - return ioReturnValue; -} - -static void sendCFArray(const void * value, void * parameter) -{ - if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) - { - return; - } - - CFObjectSend(value); -} - -void CFObjectSend( CFTypeRef value ) -{ - CFTypeID type = CFGetTypeID(value); - if (type == CFArrayGetTypeID()) - { - CFRange range = {0, CFArrayGetCount (value)}; - - //Show an element array containing one or more element dictionaries - CFArrayApplyFunction (value, range, sendCFArray, 0); - } - else if (type == CFDictionaryGetTypeID()) - { -// printf("Sending Map\n"); - - - CFTypeRef val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementCookieKey) ); - if ( val ) - { - CFNumberGetValue ( val , kCFNumberLongType, &elementCookie); - printf("ElementCookie - 0x%lx (%ld) \n", elementCookie, elementCookie); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementTypeKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &elementType); - printf("element Type - 0x%lx (%ld) \n", elementType, elementType); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementUsageKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &usage); - printf("usage - 0x%lx (%ld) \n", usage, usage); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementUsagePageKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &usagePage); - printf("usage page- 0x%lx (%ld) \n", usagePage, usagePage); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementMinKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &min); - //printf("min - 0x%lx (%ld) \n", min, min); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementMaxKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &max); - //printf("max - 0x%lx (%ld) \n", max, max); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementScaledMinKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &scaledMin); - //printf("scaledMin - 0x%lx (%ld) \n", scaledMin, scaledMin); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementScaledMaxKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &scaledMax); - //printf("scaledMax - 0x%lx (%ld) \n", scaledMax, scaledMax); - } - - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementSizeKey) ); - if ( val ) - { - CFNumberGetValue ( val, kCFNumberLongType, &size); - //printf("Size - 0x%lx (%ld) \n", size, size); - } - - jboolean isRelative = JNI_FALSE; - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementIsRelativeKey) ); - if ( val ) - { - isRelative = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE); - } - - - jboolean isWrapping = JNI_FALSE; - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementIsWrappingKey) ); - if ( val ) - { - isWrapping = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE); - } - - - jboolean isNonLinear = JNI_FALSE; - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementIsNonLinearKey) ); - if ( val ) - { - isNonLinear = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE); - } - - - jboolean hasPreferredState = JNI_FALSE; -#ifdef kIOHIDElementHasPreferredStateKey - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementHasPreferredStateKey) ); - if ( val ) - { - hasPreferredState = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE); - } -#else - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementHasPreferedStateKey) ); - if ( val ) - { - hasPreferredState = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE); - } -#endif - - jboolean hasNullState = JNI_FALSE; - val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementHasNullStateKey) ); - if ( val ) - { - hasNullState = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE); - } - - (*lpEnv)->CallVoidMethod(lpEnv, lpObj, MID_AddControllerElement, - (jlong)(long)lpDevice, - (jlong)(long)elementCookie, - (jint)(long)elementType, - (jint)(long)usage, - (jint)(long)usagePage, - (jint)(long)min, - (jint)(long)max, - (jint)(long)scaledMin, - (jint)(long)scaledMax, - (jint)(long)size, - (jboolean)isRelative, - (jboolean)isWrapping, - (jboolean)isNonLinear, - (jboolean)hasPreferredState, - (jboolean)hasNullState); - -// printf("End of element definition \n"); - - - - CFTypeRef object = CFDictionaryGetValue (value, CFSTR(kIOHIDElementKey)); - if (object) - { - CFObjectSend( object ); - } - - printf("\n\n\n"); - } -} - -void addControllerElements( CFMutableDictionaryRef dictionary, CFStringRef key ) -{ - printf("Adding controller elements\n"); - - CFTypeRef value = CFDictionaryGetValue (dictionary, key); - if (value) - { - CFRange range = {0, CFArrayGetCount (value)}; - CFArrayApplyFunction (value, range, sendCFArray, 0); - } -} - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: hidCreate - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_hidCreate - (JNIEnv * env, jobject obj) -{ - if ( init( env ) ) - { - createMasterPort(); - } -} -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: hidDispose - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_hidDispose - (JNIEnv * env, jobject obj) -{ - disposeMasterPort(); -} - - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: enumDevices - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_enumDevices - (JNIEnv * env, jobject obj) -{ - - lpEnv = env; - lpObj = obj; - - CFMutableDictionaryRef hidMatchDictionary = NULL; - IOReturn ioReturnValue = kIOReturnSuccess; - Boolean noMatchingDevices = false; - - // Set up a matching dictionary to search the I/O Registry by class - // name for all HID class devices - // - hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); - - // Now search I/O Registry for matching devices. - // - ioReturnValue = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, &hidObjectIterator); - - noMatchingDevices = ((ioReturnValue != kIOReturnSuccess) | (hidObjectIterator == NULL)); - - // If search is unsuccessful, print message . - // - if (noMatchingDevices) - { - printf("No matching HID class devices found."); - return; - } - - // IOServiceGetMatchingServices consumes a reference to the - // dictionary, so we don't need to release the dictionary ref. - // - hidMatchDictionary = NULL; - - io_object_t hidDevice = NULL; - IOHIDDeviceInterface **hidDeviceInterface = NULL; - CFMutableDictionaryRef properties = 0; - char path[512]; - kern_return_t result; - - - while ((hidDevice = IOIteratorNext(hidObjectIterator))) - { - result = IORegistryEntryGetPath(hidDevice, kIOServicePlane, path); - - if ( result == KERN_SUCCESS ) - { - result = IORegistryEntryCreateCFProperties(hidDevice, - &properties, - kCFAllocatorDefault, - kNilOptions); - } - - if ((result == KERN_SUCCESS) && properties) - { - //showDictionaryElement(properties, CFSTR(kIOHIDTransportKey)); - //showDictionaryElement(properties, CFSTR(kIOHIDVendorKey)); - //printf("ProductID: "); showDictionaryElement(properties, CFSTR(kIOHIDProductIDKey)); - //printf("VersionNumber: "); showDictionaryElement(properties, CFSTR(kIOHIDVersionNumberKey)); - //printf("Manufacturer: "); showDictionaryElement(properties, CFSTR(kIOHIDManufacturerKey)); - //printf("ProductKey: "); showDictionaryElement(properties, CFSTR(kIOHIDProductKey)); - //printf("SerialNumber: "); showDictionaryElement(properties, CFSTR(kIOHIDSerialNumberKey)); - //showDictionaryElement(properties, CFSTR(kIOHIDLocationIDKey)); - //printf("PrimaryUsage: "); showDictionaryElement(properties, CFSTR(kIOHIDPrimaryUsageKey)); - //showDictionaryElement(properties, CFSTR(kIOHIDPrimaryUsagePageKey)); - //showDictionaryElement(properties, CFSTR(kIOHIDElementKey)); - - - - // get the product name - // - CFTypeRef productName = CFDictionaryGetValue (properties, CFSTR(kIOHIDProductKey)); - - // get the usage for this product - // - long usage; - CFNumberGetValue ( CFDictionaryGetValue( properties, CFSTR(kIOHIDPrimaryUsageKey) ), kCFNumberLongType, &usage); - - - createHIDDevice( hidDevice, &hidDeviceInterface ); - - IOObjectRelease( hidDevice ); - - if ( hidDeviceInterface != NULL ) - { - (*env)->CallVoidMethod(env, obj, MID_AddController, - (jlong)(long)hidDeviceInterface, - (*env)->NewStringUTF( env, CFStringGetCStringPtr( productName, CFStringGetSystemEncoding()) ), - (jint)usage ); - lpEnv = env; - lpDevice = (jlong)(long)hidDeviceInterface; - - addControllerElements( properties, CFSTR(kIOHIDElementKey) ); - - - } - - //Release the properties dictionary - CFRelease(properties); - } - - } - - IOObjectRelease(hidObjectIterator); -} - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: openDevice - * Signature: (JI)J - */ -JNIEXPORT jlong JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_openDevice - (JNIEnv * env, jobject obj, jlong lpDevice, jint queueDepth) -{ - IOHIDDeviceInterface **hidDeviceInterface = NULL; - hidDeviceInterface = (IOHIDDeviceInterface **) (long)lpDevice; - openDevice( &hidDeviceInterface ); - - - IOHIDQueueInterface **queue = NULL; - queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); - - if (queue) - { - // create a queue and specify how deep they want the input queue to be - // - (*queue)->create( queue, 0, (int)queueDepth ); - printf("InputQueue created %lx with depth %d \n", (long) queue, (int)queueDepth ); - - // start the input queue - // - (*queue)->start( queue ); - } - else - { - printf("Unable to create queue for device! \n"); - } - - return (jlong)(long)queue; - -} - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: closeDevice - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_closeDevice - (JNIEnv * env, jobject obj, jlong lpDevice, jlong lpQueue) -{ - IOHIDDeviceInterface **hidDeviceInterface = NULL; - hidDeviceInterface = (IOHIDDeviceInterface **) (long)lpDevice; - - IOHIDQueueInterface **queue = NULL; - queue = (IOHIDQueueInterface **)(long)lpQueue; - - // stop the queue - // - (*queue)->stop(queue); - - // dispose of the queue - // - (*queue)->dispose(queue); - - // release the queue - // - (*queue)->Release(queue); - - // close the input device - // - closeDevice( &hidDeviceInterface ); -} - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: pollDevice - * Signature: (J)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_pollDevice - (JNIEnv * env, jobject obj, jlong lpQueue) -{ - IOHIDEventStruct event; - - IOHIDQueueInterface **queue = NULL; - queue = (IOHIDQueueInterface **)(long)lpQueue; - - AbsoluteTime zeroTime = {0,0}; - IOReturn ioReturnValue = kIOReturnSuccess; - - ioReturnValue = (*queue)->getNextEvent(queue, &event, zeroTime, 0); - if ( ioReturnValue == kIOReturnSuccess ) - { - printf("Queue getNextEvent return value: %ld\n", (long)ioReturnValue ); - } - else - { - printf("Queue event[%lx] %ld\n", (unsigned long) event.elementCookie, event.value ); - } - - return (jint) event.value; -} - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: pollDevice - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_pollElement - (JNIEnv * env, jobject obj, jlong lpDevice, jlong hidCookie) -{ - IOHIDDeviceInterface **hidDeviceInterface = NULL; - hidDeviceInterface = (IOHIDDeviceInterface **) (long)lpDevice; - - IOHIDElementCookie cookie = (IOHIDElementCookie)(long)hidCookie; - - IOHIDEventStruct event; - - IOReturn ioReturnValue = kIOReturnSuccess; - - ioReturnValue = (*hidDeviceInterface)->getElementValue(hidDeviceInterface, cookie, &event); - if ( ioReturnValue == kIOReturnSuccess ) - { - printf("Queue getNextEvent return value: %ld\n", (long)ioReturnValue ); - } - else - { - printf("Queue event[%lx] %ld\n", (unsigned long) event.elementCookie, event.value ); - } - - return (jint) event.value; -} - - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: registerDeviceElement - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_registerDeviceElement - (JNIEnv * env, jobject obj, jlong lpQueue, jlong hidCookie) -{ - IOHIDQueueInterface **queue = NULL; - queue = (IOHIDQueueInterface **)(long)lpQueue; - - IOHIDElementCookie cookie = (IOHIDElementCookie)(long)hidCookie; - IOReturn ioReturnValue = kIOReturnSuccess; - - ioReturnValue = (*queue)->addElement(queue, cookie, 0); - if ( ioReturnValue == kIOReturnSuccess ) - { - printf("Registered pollElement: %ld\n", (long)cookie ); - } - else - { - printf("Failed to add poll element: %ld\n", (long)cookie ); - } -} - -/* - * Class: net_java_games_input_OSXEnvironmentPlugin - * Method: deregisterDeviceElement - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_deregisterDeviceElement - (JNIEnv * env, jobject obj, jlong lpQueue, jlong hidCookie) -{ - IOHIDQueueInterface **queue = NULL; - queue = (IOHIDQueueInterface **)(long)lpQueue; - - IOHIDElementCookie cookie = (IOHIDElementCookie)(long)hidCookie; - - IOReturn ioReturnValue = kIOReturnSuccess; - - ioReturnValue = (*queue)->removeElement(queue, cookie ); - if ( ioReturnValue == kIOReturnSuccess ) - { - printf("Removed pollElement: %ld\n", (long)cookie ); - } - else - { - printf("Failed to remove poll element: %ld\n", (long)cookie ); - } -} - - - diff --git a/plugins/OSX/src/native/macosxutil.c b/plugins/OSX/src/native/macosxutil.c new file mode 100644 index 0000000..81b5cc6 --- /dev/null +++ b/plugins/OSX/src/native/macosxutil.c @@ -0,0 +1,197 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <CoreServices/CoreServices.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <jni.h> +#include "util.h" +#include "macosxutil.h" + +typedef struct { + JNIEnv *env; + jobject map; +} dict_context_t; + +typedef struct { + JNIEnv *env; + jobjectArray array; + jsize index; +} array_context_t; + +static jobject createObjectFromCFObject(JNIEnv *env, CFTypeRef cfobject); + +static jstring createStringFromCFString(JNIEnv *env, CFStringRef cfstring) { + CFIndex unicode_length = CFStringGetLength(cfstring); + CFIndex utf8_length = CFStringGetMaximumSizeForEncoding(unicode_length, kCFStringEncodingUTF8); + // Allocate buffer large enough, plus \0 terminator + char *buffer = (char *)malloc(utf8_length + 1); + if (buffer == NULL) + return NULL; + Boolean result = CFStringGetCString(cfstring, buffer, utf8_length + 1, kCFStringEncodingUTF8); + if (!result) { + free(buffer); + return NULL; + } + jstring str = (*env)->NewStringUTF(env, buffer); + free(buffer); + return str; +} + +static jobject createDoubleObjectFromCFNumber(JNIEnv *env, CFNumberRef cfnumber) { + double value; + Boolean result = CFNumberGetValue(cfnumber, kCFNumberDoubleType, &value); + if (!result) + return NULL; + return newJObject(env, "java/lang/Double", "(D)V", (jdouble)value); +} + +static jobject createLongObjectFromCFNumber(JNIEnv *env, CFNumberRef cfnumber) { + SInt64 value; + Boolean result = CFNumberGetValue(cfnumber, kCFNumberSInt64Type, &value); + if (!result) + return NULL; + return newJObject(env, "java/lang/Long", "(J)V", (jlong)value); +} + +static jobject createNumberFromCFNumber(JNIEnv *env, CFNumberRef cfnumber) { + CFNumberType number_type = CFNumberGetType(cfnumber); + switch (number_type) { + case kCFNumberSInt8Type: + case kCFNumberSInt16Type: + case kCFNumberSInt32Type: + case kCFNumberSInt64Type: + case kCFNumberCharType: + case kCFNumberShortType: + case kCFNumberIntType: + case kCFNumberLongType: + case kCFNumberLongLongType: + case kCFNumberCFIndexType: + return createLongObjectFromCFNumber(env, cfnumber); + case kCFNumberFloat32Type: + case kCFNumberFloat64Type: + case kCFNumberFloatType: + case kCFNumberDoubleType: + return createDoubleObjectFromCFNumber(env, cfnumber); + default: + return NULL; + } +} + +static void createArrayEntries(const void *value, void *context) { + array_context_t *array_context = (array_context_t *)context; + jobject jval = createObjectFromCFObject(array_context->env, value); + (*array_context->env)->SetObjectArrayElement(array_context->env, array_context->array, array_context->index++, jval); + (*array_context->env)->DeleteLocalRef(array_context->env, jval); +} + +static jobject createArrayFromCFArray(JNIEnv *env, CFArrayRef cfarray) { + jclass Object_class = (*env)->FindClass(env, "java/lang/Object"); + if (Object_class == NULL) + return NULL; + CFIndex size = CFArrayGetCount(cfarray); + CFRange range = {0, size}; + jobjectArray array = (*env)->NewObjectArray(env, size, Object_class, NULL); + array_context_t array_context; + array_context.env = env; + array_context.array = array; + array_context.index = 0; + CFArrayApplyFunction(cfarray, range, createArrayEntries, &array_context); + return array; +} + +static jobject createObjectFromCFObject(JNIEnv *env, CFTypeRef cfobject) { + CFTypeID type_id = CFGetTypeID(cfobject); + if (type_id == CFDictionaryGetTypeID()) { + return createMapFromCFDictionary(env, cfobject); + } else if (type_id == CFArrayGetTypeID()) { + return createArrayFromCFArray(env, cfobject); + } else if (type_id == CFStringGetTypeID()) { + return createStringFromCFString(env, cfobject); + } else if (type_id == CFNumberGetTypeID()) { + return createNumberFromCFNumber(env, cfobject); + } else { + return NULL; + } +} + +static void createMapKeys(const void *key, const void *value, void *context) { + dict_context_t *dict_context = (dict_context_t *)context; + + jclass Map_class = (*dict_context->env)->GetObjectClass(dict_context->env, dict_context->map); + if (Map_class == NULL) + return; + jmethodID map_put = (*dict_context->env)->GetMethodID(dict_context->env, Map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + if (map_put == NULL) + return; + jobject jkey = createObjectFromCFObject(dict_context->env, key); + jobject jvalue = createObjectFromCFObject(dict_context->env, value); + if (jkey == NULL || jvalue == NULL) + return; + (*dict_context->env)->CallObjectMethod(dict_context->env, dict_context->map, map_put, jkey, jvalue); + (*dict_context->env)->DeleteLocalRef(dict_context->env, jkey); + (*dict_context->env)->DeleteLocalRef(dict_context->env, jvalue); +} + +jobject createMapFromCFDictionary(JNIEnv *env, CFDictionaryRef dict) { + jobject map = newJObject(env, "java/util/HashMap", "()V"); + if (map == NULL) + return NULL; + dict_context_t dict_context; + dict_context.env = env; + dict_context.map = map; + CFDictionaryApplyFunction(dict, createMapKeys, &dict_context); + return map; +} + +void copyEvent(JNIEnv *env, IOHIDEventStruct *event, jobject event_return) { + jclass OSXEvent_class = (*env)->GetObjectClass(env, event_return); + if (OSXEvent_class == NULL) { + return; + } + + jmethodID OSXEvent_set = (*env)->GetMethodID(env, OSXEvent_class, "set", "(JJIJ)V"); + if (OSXEvent_set == NULL) { + return; + } + Nanoseconds nanos = AbsoluteToNanoseconds(event->timestamp); + uint64_t nanos64= *((uint64_t *)&nanos); + (*env)->CallVoidMethod(env, event_return, OSXEvent_set, (jlong)event->type, (jlong)(intptr_t)event->elementCookie, (jint)event->value, (jlong)nanos64); +} diff --git a/plugins/OSX/src/native/macosxutil.h b/plugins/OSX/src/native/macosxutil.h new file mode 100644 index 0000000..ed2722c --- /dev/null +++ b/plugins/OSX/src/native/macosxutil.h @@ -0,0 +1,48 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <jni.h> +#include <CoreFoundation/CoreFoundation.h> +#include <IOKit/hid/IOHIDLib.h> + +extern jobject createMapFromCFDictionary(JNIEnv *env, CFDictionaryRef dict); +extern void copyEvent(JNIEnv *env, IOHIDEventStruct *event, jobject event_return); diff --git a/plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c b/plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c new file mode 100644 index 0000000..cef6701 --- /dev/null +++ b/plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c @@ -0,0 +1,118 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <IOKit/IOTypes.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/hid/IOHIDKeys.h> +#include <CoreFoundation/CoreFoundation.h> +#include "net_java_games_input_OSXHIDDevice.h" +#include "util.h" +#include "macosxutil.h" + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nReleaseDevice(JNIEnv *env, jclass unused, jlong device_address, jlong interface_address) { + io_object_t hidDevice = (io_object_t)device_address; + IOHIDDeviceInterface **device_interface = (IOHIDDeviceInterface **)(intptr_t)interface_address;; + (*device_interface)->Release(device_interface); + IOObjectRelease(hidDevice); +} + +JNIEXPORT jobject JNICALL Java_net_java_games_input_OSXHIDDevice_nGetDeviceProperties(JNIEnv *env, jclass unused, jlong device_address) { + io_object_t hidDevice = (io_object_t)device_address; + CFMutableDictionaryRef properties; + + kern_return_t result = IORegistryEntryCreateCFProperties(hidDevice, + &properties, + kCFAllocatorDefault, + kNilOptions); + if (result != KERN_SUCCESS) { + throwIOException(env, "Failed to create properties for device (%ld)", result); + return NULL; + } + jobject map = createMapFromCFDictionary(env, properties); + CFRelease(properties); + return map; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nOpen + (JNIEnv * env, jclass unused, jlong lpDevice) { + IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)lpDevice; + IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, 0); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Device open failed: %d", ioReturnValue); + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nClose + (JNIEnv * env, jclass unused, jlong lpDevice) { + IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)lpDevice; + IOReturn ioReturnValue = (*hidDeviceInterface)->close(hidDeviceInterface); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Device close failed: %d", ioReturnValue); + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nGetElementValue + (JNIEnv * env, jclass unused, jlong lpDevice, jlong hidCookie, jobject event_return) { + IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)lpDevice; + IOHIDElementCookie cookie = (IOHIDElementCookie)(intptr_t)hidCookie; + IOHIDEventStruct event; + + IOReturn ioReturnValue = (*hidDeviceInterface)->getElementValue(hidDeviceInterface, cookie, &event); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Device getElementValue failed: %d", ioReturnValue); + return; + } + copyEvent(env, &event, event_return); + if (event.longValue != NULL) { + free(event.longValue); + } +} + +JNIEXPORT jlong JNICALL Java_net_java_games_input_OSXHIDDevice_nCreateQueue(JNIEnv *env, jclass unused, jlong device_address) { + IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)device_address; + IOHIDQueueInterface **queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); + + if (queue == NULL) { + throwIOException(env, "Could not allocate queue"); + return 0; + } + return (jlong)(intptr_t)queue; +} diff --git a/plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c b/plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c new file mode 100644 index 0000000..e76363f --- /dev/null +++ b/plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c @@ -0,0 +1,143 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <IOKit/IOTypes.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/hid/IOHIDKeys.h> +#include <CoreFoundation/CoreFoundation.h> +#include "net_java_games_input_OSXHIDDeviceIterator.h" +#include "util.h" + +JNIEXPORT jlong JNICALL Java_net_java_games_input_OSXHIDDeviceIterator_nCreateIterator(JNIEnv *env, jclass unused) { + io_iterator_t hidObjectIterator; + // Set up a matching dictionary to search the I/O Registry by class + // name for all HID class devices + // + CFMutableDictionaryRef hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); + + // Now search I/O Registry for matching devices. + // IOServiceGetMatchingServices consumes a reference to the dictionary so we don't have to release it + IOReturn ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); + + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Failed to create iterator (%ld)\n", ioReturnValue); + return 0; + } + + if (hidObjectIterator == IO_OBJECT_NULL) { + throwIOException(env, "Failed to create iterator\n"); + return 0; + } + return (jlong)hidObjectIterator; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDeviceIterator_nReleaseIterator(JNIEnv *env, jclass unused, jlong address) { + io_iterator_t iterator = (io_iterator_t)address; + IOObjectRelease(iterator); +} + +static IOHIDDeviceInterface **createHIDDevice(JNIEnv *env, io_object_t hidDevice) { +// io_name_t className; + IOHIDDeviceInterface **hidDeviceInterface; + IOCFPlugInInterface **plugInInterface; + SInt32 score; + +/* ioReturnValue = IOObjectGetClass(hidDevice, className); + if (ioReturnValue != kIOReturnSuccess) { + printfJava(env, "Failed to get IOObject class name."); + } + + printfJava(env, "Found device type [%s]\n", className); + */ + IOReturn ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugInInterface, + &score); + + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Couldn't create plugin for device interface (%ld)\n", ioReturnValue); + return NULL; + } + //Call a method of the intermediate plug-in to create the device + //interface + // + HRESULT plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, + CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), + (LPVOID)&hidDeviceInterface); + (*plugInInterface)->Release(plugInInterface); + if (plugInResult != S_OK) { + throwIOException(env, "Couldn't create HID class device interface (%ld)\n", plugInResult); + return NULL; + } + return hidDeviceInterface; +} + +JNIEXPORT jobject JNICALL Java_net_java_games_input_OSXHIDDeviceIterator_nNext(JNIEnv *env, jclass unused, jlong address) { + io_iterator_t iterator = (io_iterator_t)address; + io_object_t hidDevice; +// io_string_t path; +// kern_return_t result; + + hidDevice = IOIteratorNext(iterator); + if (hidDevice == MACH_PORT_NULL) + return NULL; +/* IOResult result = IORegistryEntryGetPath(hidDevice, kIOServicePlane, path); + + if (result != KERN_SUCCESS) { + IOObjectRelease(hidDevice); + throwIOException("Failed to get device path (%ld)\n", result); + return NULL; + } +*/ + IOHIDDeviceInterface **device_interface = createHIDDevice(env, hidDevice); + if (device_interface == NULL) { + IOObjectRelease(hidDevice); + return NULL; + } + jobject device_object = newJObject(env, "net/java/games/input/OSXHIDDevice", "(JJ)V", (jlong)hidDevice, (jlong)(intptr_t)device_interface); + if (device_object == NULL) { + (*device_interface)->Release(device_interface); + IOObjectRelease(hidDevice); + return NULL; + } + return device_object; +} diff --git a/plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c b/plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c new file mode 100644 index 0000000..12dbd0a --- /dev/null +++ b/plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c @@ -0,0 +1,135 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <IOKit/IOTypes.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/hid/IOHIDKeys.h> +#include <CoreFoundation/CoreFoundation.h> +#include "net_java_games_input_OSXHIDQueue.h" +#include "util.h" +#include "macosxutil.h" + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nOpen(JNIEnv *env, jclass unused, jlong address, jint queue_depth) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOReturn ioReturnValue = (*queue)->create(queue, 0, queue_depth); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue open failed: %d\n", ioReturnValue); + return; + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nStart(JNIEnv *env, jclass unused, jlong address) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOReturn ioReturnValue = (*queue)->start(queue); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue start failed: %d\n", ioReturnValue); + return; + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nStop(JNIEnv *env, jclass unused, jlong address) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOReturn ioReturnValue = (*queue)->stop(queue); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue stop failed: %d\n", ioReturnValue); + return; + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nClose(JNIEnv *env, jclass unused, jlong address) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOReturn ioReturnValue = (*queue)->dispose(queue); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue dispose failed: %d\n", ioReturnValue); + return; + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nReleaseQueue(JNIEnv *env, jclass unused, jlong address) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOReturn ioReturnValue = (*queue)->Release(queue); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue Release failed: %d\n", ioReturnValue); + return; + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nAddElement(JNIEnv *env, jclass unused, jlong address, jlong cookie_address) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOHIDElementCookie cookie = (IOHIDElementCookie)(intptr_t)cookie_address; + + IOReturn ioReturnValue = (*queue)->addElement(queue, cookie, 0); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue addElement failed: %d\n", ioReturnValue); + return; + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nRemoveElement(JNIEnv *env, jclass unused, jlong address, jlong cookie_address) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOHIDElementCookie cookie = (IOHIDElementCookie)(intptr_t)cookie_address; + + IOReturn ioReturnValue = (*queue)->removeElement(queue, cookie); + if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue removeElement failed: %d\n", ioReturnValue); + return; + } +} + + +JNIEXPORT jboolean JNICALL Java_net_java_games_input_OSXHIDQueue_nGetNextEvent(JNIEnv *env, jclass unused, jlong address, jobject event_return) { + IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address; + IOHIDEventStruct event; + + AbsoluteTime zeroTime = {0, 0}; + IOReturn ioReturnValue = (*queue)->getNextEvent(queue, &event, zeroTime, 0); + if (ioReturnValue == kIOReturnUnderrun) { + return JNI_FALSE; + } else if (ioReturnValue != kIOReturnSuccess) { + throwIOException(env, "Queue getNextEvent failed: %d\n", ioReturnValue); + return JNI_FALSE; + } + copyEvent(env, &event, event_return); + if (event.longValue != NULL) { + free(event.longValue); + } + return JNI_TRUE; +} diff --git a/plugins/awt/build.xml b/plugins/awt/build.xml index 6531ec3..431ad63 100644 --- a/plugins/awt/build.xml +++ b/plugins/awt/build.xml @@ -9,23 +9,19 @@ <target depends="init" name="compile"> <javac debug="true" deprecation="true" destdir="classes" source="1.4" target="1.4" srcdir="src"> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> - <pathelement location="../../coreAPI/lib/jutils.jar"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> </classpath> </javac> </target> <target depends="init,compile" name="jar"> <jar jarfile="bin/awtinput.jar" compress="true" basedir="classes"> - <exclude name="**/*.java"/> - <exclude name="awtinput.jar"/> - <exclude name="apidoc"/> + <include name="**/*.class"/> </jar> - <copy file="bin/awtinput.jar" todir="../../coreAPI/src/tests/controller" /> </target> <target depends="jar" description="Build everything." name="all"> - <echo message="Application built."/> </target> <target name="javadoc" depends="init" description="Javadoc for AWT plugin for JInput."> @@ -38,21 +34,18 @@ <pathelement location="src"/> </sourcepath> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> - <pathelement location="../../coreAPI/lib/jutils.jar"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> </classpath> </javadoc> </target> <target description="Clean all build products." name="clean"> <delete failonerror="no"> - <fileset dir="classes"> - <include name="**/*.class"/> - </fileset> + <fileset dir="classes"/> </delete> - <delete file="bin/awtinput.jar" failonerror="no"/> - <delete file="../../coreAPI/src/tests/controller/awtinput.jar" failonerror="no" /> - <delete file="apidoc" failonerror="no"/> + <delete dir="bin/awtinput.jar" failonerror="no"/> + <delete dir="apidoc" failonerror="no"/> </target> </project> diff --git a/plugins/awt/src/net/java/games/input/AWTButton.java b/plugins/awt/src/net/java/games/input/AWTButton.java deleted file mode 100644 index 6e36d16..0000000 --- a/plugins/awt/src/net/java/games/input/AWTButton.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (C) 2004 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ -package net.java.games.input; - -/** - * @author Jeremy - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates - */ -public class AWTButton extends AbstractComponent { - - private boolean value = false; - - /** - * @param name - * @param id - */ - protected AWTButton(String name, Identifier id) { - super(name, id); - } - - /* (non-Javadoc) - * @see net.java.games.input.Component#isRelative() - */ - public boolean isRelative() { - return false; - } - - /** - * Returns whether or not the axis is analog, or false if it is digital. - * @return false by default, can be overridden - */ - public boolean isAnalog() { - return false; - } - - /** - * Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return 0.0f by default, can be overridden - */ - public float getPollData() { - if(value) { - return 1.0f; - } else { - return 0.0f; - } - } - - void setValue(boolean value) { - this.value = value; - } -} diff --git a/plugins/awt/src/net/java/games/input/AWTEnvironmentPlugin.java b/plugins/awt/src/net/java/games/input/AWTEnvironmentPlugin.java index a155db5..96e5986 100644 --- a/plugins/awt/src/net/java/games/input/AWTEnvironmentPlugin.java +++ b/plugins/awt/src/net/java/games/input/AWTEnvironmentPlugin.java @@ -31,24 +31,16 @@ import net.java.games.util.plugins.Plugin; /** * @author Jeremy - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates + * @author elias */ public class AWTEnvironmentPlugin extends ControllerEnvironment implements Plugin { - - /** The two controllers */ - private Controller[] controllers = new Controller[2]; + private final Controller[] controllers; + + public AWTEnvironmentPlugin() { + this.controllers = new Controller[]{new AWTKeyboard(), new AWTMouse()}; + } - /* (non-Javadoc) - * @see net.java.games.input.ControllerEnvironment#getControllers() - */ public Controller[] getControllers() { - if((controllers[0] == null) && (controllers[1] == null)) { - controllers[0] = new AWTKeyboard("AWTKeyboard"); - controllers[1] = new AWTMouse("AWTMouse"); - } return controllers; } - } diff --git a/plugins/awt/src/net/java/games/input/AWTKeyMap.java b/plugins/awt/src/net/java/games/input/AWTKeyMap.java new file mode 100644 index 0000000..cb0c548 --- /dev/null +++ b/plugins/awt/src/net/java/games/input/AWTKeyMap.java @@ -0,0 +1,289 @@ +/** + * Copyright (C) 2004 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +import java.awt.event.KeyEvent; + +/** + * @author Jeremy + * @author elias + */ +final class AWTKeyMap { + public final static Component.Identifier.Key mapKeyCode(int key_code) { + switch (key_code) { + case KeyEvent.VK_0: + return Component.Identifier.Key._0; + case KeyEvent.VK_1: + return Component.Identifier.Key._1; + case KeyEvent.VK_2: + return Component.Identifier.Key._2; + case KeyEvent.VK_3: + return Component.Identifier.Key._3; + case KeyEvent.VK_4: + return Component.Identifier.Key._4; + case KeyEvent.VK_5: + return Component.Identifier.Key._5; + case KeyEvent.VK_6: + return Component.Identifier.Key._6; + case KeyEvent.VK_7: + return Component.Identifier.Key._7; + case KeyEvent.VK_8: + return Component.Identifier.Key._8; + case KeyEvent.VK_9: + return Component.Identifier.Key._9; + + case KeyEvent.VK_Q: + return Component.Identifier.Key.Q; + case KeyEvent.VK_W: + return Component.Identifier.Key.W; + case KeyEvent.VK_E: + return Component.Identifier.Key.E; + case KeyEvent.VK_R: + return Component.Identifier.Key.R; + case KeyEvent.VK_T: + return Component.Identifier.Key.T; + case KeyEvent.VK_Y: + return Component.Identifier.Key.Y; + case KeyEvent.VK_U: + return Component.Identifier.Key.U; + case KeyEvent.VK_I: + return Component.Identifier.Key.I; + case KeyEvent.VK_O: + return Component.Identifier.Key.O; + case KeyEvent.VK_P: + return Component.Identifier.Key.P; + case KeyEvent.VK_A: + return Component.Identifier.Key.A; + case KeyEvent.VK_S: + return Component.Identifier.Key.S; + case KeyEvent.VK_D: + return Component.Identifier.Key.D; + case KeyEvent.VK_F: + return Component.Identifier.Key.F; + case KeyEvent.VK_G: + return Component.Identifier.Key.G; + case KeyEvent.VK_H: + return Component.Identifier.Key.H; + case KeyEvent.VK_J: + return Component.Identifier.Key.J; + case KeyEvent.VK_K: + return Component.Identifier.Key.K; + case KeyEvent.VK_L: + return Component.Identifier.Key.L; + case KeyEvent.VK_Z: + return Component.Identifier.Key.Z; + case KeyEvent.VK_X: + return Component.Identifier.Key.X; + case KeyEvent.VK_C: + return Component.Identifier.Key.C; + case KeyEvent.VK_V: + return Component.Identifier.Key.V; + case KeyEvent.VK_B: + return Component.Identifier.Key.B; + case KeyEvent.VK_N: + return Component.Identifier.Key.N; + case KeyEvent.VK_M: + return Component.Identifier.Key.M; + + case KeyEvent.VK_F1: + return Component.Identifier.Key.F1; + case KeyEvent.VK_F2: + return Component.Identifier.Key.F2; + case KeyEvent.VK_F3: + return Component.Identifier.Key.F3; + case KeyEvent.VK_F4: + return Component.Identifier.Key.F4; + case KeyEvent.VK_F5: + return Component.Identifier.Key.F5; + case KeyEvent.VK_F6: + return Component.Identifier.Key.F6; + case KeyEvent.VK_F7: + return Component.Identifier.Key.F7; + case KeyEvent.VK_F8: + return Component.Identifier.Key.F8; + case KeyEvent.VK_F9: + return Component.Identifier.Key.F9; + case KeyEvent.VK_F10: + return Component.Identifier.Key.F10; + case KeyEvent.VK_F11: + return Component.Identifier.Key.F11; + case KeyEvent.VK_F12: + return Component.Identifier.Key.F12; + + case KeyEvent.VK_ESCAPE: + return Component.Identifier.Key.ESCAPE; + case KeyEvent.VK_MINUS: + return Component.Identifier.Key.MINUS; + case KeyEvent.VK_EQUALS: + return Component.Identifier.Key.EQUALS; + case KeyEvent.VK_BACK_SPACE: + return Component.Identifier.Key.BACKSLASH; + case KeyEvent.VK_TAB: + return Component.Identifier.Key.TAB; + case KeyEvent.VK_OPEN_BRACKET: + return Component.Identifier.Key.LBRACKET; + case KeyEvent.VK_CLOSE_BRACKET: + return Component.Identifier.Key.RBRACKET; + case KeyEvent.VK_SEMICOLON: + return Component.Identifier.Key.SEMICOLON; + case KeyEvent.VK_QUOTE: + return Component.Identifier.Key.APOSTROPHE; + case KeyEvent.VK_NUMBER_SIGN: + return Component.Identifier.Key.GRAVE; + case KeyEvent.VK_BACK_SLASH: + return Component.Identifier.Key.BACKSLASH; + case KeyEvent.VK_PERIOD: + return Component.Identifier.Key.PERIOD; + case KeyEvent.VK_SLASH: + return Component.Identifier.Key.SLASH; + case KeyEvent.VK_MULTIPLY: + return Component.Identifier.Key.MULTIPLY; + case KeyEvent.VK_SPACE: + return Component.Identifier.Key.SPACE; + case KeyEvent.VK_CAPS_LOCK: + return Component.Identifier.Key.CAPITAL; + case KeyEvent.VK_NUM_LOCK: + return Component.Identifier.Key.NUMLOCK; + case KeyEvent.VK_SCROLL_LOCK: + return Component.Identifier.Key.SCROLL; + case KeyEvent.VK_NUMPAD7: + return Component.Identifier.Key.NUMPAD7; + case KeyEvent.VK_NUMPAD8: + return Component.Identifier.Key.NUMPAD8; + case KeyEvent.VK_NUMPAD9: + return Component.Identifier.Key.NUMPAD9; + case KeyEvent.VK_SUBTRACT: + return Component.Identifier.Key.SUBTRACT; + case KeyEvent.VK_NUMPAD4: + return Component.Identifier.Key.NUMPAD4; + case KeyEvent.VK_NUMPAD5: + return Component.Identifier.Key.NUMPAD5; + case KeyEvent.VK_NUMPAD6: + return Component.Identifier.Key.NUMPAD6; + case KeyEvent.VK_ADD: + return Component.Identifier.Key.ADD; + case KeyEvent.VK_NUMPAD1: + return Component.Identifier.Key.NUMPAD1; + case KeyEvent.VK_NUMPAD2: + return Component.Identifier.Key.NUMPAD2; + case KeyEvent.VK_NUMPAD3: + return Component.Identifier.Key.NUMPAD3; + case KeyEvent.VK_NUMPAD0: + return Component.Identifier.Key.NUMPAD0; + case KeyEvent.VK_DECIMAL: + return Component.Identifier.Key.DECIMAL; + + case KeyEvent.VK_KANA: + return Component.Identifier.Key.KANA; + case KeyEvent.VK_CONVERT: + return Component.Identifier.Key.CONVERT; + case KeyEvent.VK_NONCONVERT: + return Component.Identifier.Key.NOCONVERT; + + case KeyEvent.VK_CIRCUMFLEX: + return Component.Identifier.Key.CIRCUMFLEX; + case KeyEvent.VK_AT: + return Component.Identifier.Key.AT; + case KeyEvent.VK_COLON: + return Component.Identifier.Key.COLON; + case KeyEvent.VK_UNDERSCORE: + return Component.Identifier.Key.UNDERLINE; + case KeyEvent.VK_KANJI: + return Component.Identifier.Key.KANJI; + + case KeyEvent.VK_STOP: + return Component.Identifier.Key.STOP; + + case KeyEvent.VK_DIVIDE: + return Component.Identifier.Key.DIVIDE; + + case KeyEvent.VK_PAUSE: + return Component.Identifier.Key.PAUSE; + case KeyEvent.VK_HOME: + return Component.Identifier.Key.HOME; + case KeyEvent.VK_UP: + return Component.Identifier.Key.UP; + case KeyEvent.VK_PAGE_UP: + return Component.Identifier.Key.PAGEUP; + case KeyEvent.VK_LEFT: + return Component.Identifier.Key.LEFT; + case KeyEvent.VK_RIGHT: + return Component.Identifier.Key.RIGHT; + case KeyEvent.VK_END: + return Component.Identifier.Key.END; + case KeyEvent.VK_DOWN: + return Component.Identifier.Key.DOWN; + case KeyEvent.VK_PAGE_DOWN: + return Component.Identifier.Key.PAGEDOWN; + case KeyEvent.VK_INSERT: + return Component.Identifier.Key.INSERT; + case KeyEvent.VK_DELETE: + return Component.Identifier.Key.DELETE; + default: + return Component.Identifier.Key.UNKNOWN; + } + } + + public final static Component.Identifier.Key map(KeyEvent event) { + int key_code = event.getKeyCode(); + int key_location = event.getKeyLocation(); + switch (key_code) { + case KeyEvent.VK_CONTROL: + if (key_location == KeyEvent.KEY_LOCATION_RIGHT) + return Component.Identifier.Key.RCONTROL; + else + return Component.Identifier.Key.LCONTROL; + case KeyEvent.VK_SHIFT: + if (key_location == KeyEvent.KEY_LOCATION_RIGHT) + return Component.Identifier.Key.RSHIFT; + else + return Component.Identifier.Key.LSHIFT; + case KeyEvent.VK_ALT: + if (key_location == KeyEvent.KEY_LOCATION_RIGHT) + return Component.Identifier.Key.RALT; + else + return Component.Identifier.Key.LALT; + //this is 1.5 only +/* case KeyEvent.VK_WINDOWS: + if (key_location == KeyEvent.KEY_LOCATION_RIGHT) + return Component.Identifier.Key.RWIN; + else + return Component.Identifier.Key.LWIN;*/ + case KeyEvent.VK_ENTER: + if (key_location == KeyEvent.KEY_LOCATION_NUMPAD) + return Component.Identifier.Key.NUMPADENTER; + else + return Component.Identifier.Key.RETURN; + case KeyEvent.VK_COMMA: + if (key_location == KeyEvent.KEY_LOCATION_NUMPAD) + return Component.Identifier.Key.NUMPADCOMMA; + else + return Component.Identifier.Key.COMMA; + default: + return mapKeyCode(key_code); + } + } +} diff --git a/plugins/awt/src/net/java/games/input/AWTKeyboard.java b/plugins/awt/src/net/java/games/input/AWTKeyboard.java index dba9b0e..dafd4df 100644 --- a/plugins/awt/src/net/java/games/input/AWTKeyboard.java +++ b/plugins/awt/src/net/java/games/input/AWTKeyboard.java @@ -30,233 +30,142 @@ import java.awt.Toolkit; import java.awt.event.AWTEventListener; import java.awt.event.KeyEvent; +import java.util.List; +import java.util.ArrayList; + +import java.io.IOException; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + /** * @author Jeremy - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates + * @author elias */ -public class AWTKeyboard extends StandardKeyboard implements AWTEventListener { - - private boolean[] buttonValues; +final class AWTKeyboard extends Keyboard implements AWTEventListener { + private final List awt_events = new ArrayList(); + private Event[] processed_events; + private int processed_events_index; - private int[] buttonMap; - - /** - * @param name - */ - protected AWTKeyboard(String name) { - super(name); - - buttonValues = new boolean[getComponents().length]; - buttonMap = new int[65535]; //has to be this big, as the values of KeyEvent keys are large - - buttonMap[KeyEvent.VK_0] = Component.Identifier.Key._0.getKeyIndex(); - buttonMap[KeyEvent.VK_1] = Component.Identifier.Key._1.getKeyIndex(); - buttonMap[KeyEvent.VK_2] = Component.Identifier.Key._2.getKeyIndex(); - buttonMap[KeyEvent.VK_3] = Component.Identifier.Key._3.getKeyIndex(); - buttonMap[KeyEvent.VK_4] = Component.Identifier.Key._4.getKeyIndex(); - buttonMap[KeyEvent.VK_5] = Component.Identifier.Key._5.getKeyIndex(); - buttonMap[KeyEvent.VK_6] = Component.Identifier.Key._6.getKeyIndex(); - buttonMap[KeyEvent.VK_7] = Component.Identifier.Key._7.getKeyIndex(); - buttonMap[KeyEvent.VK_8] = Component.Identifier.Key._8.getKeyIndex(); - buttonMap[KeyEvent.VK_9] = Component.Identifier.Key._9.getKeyIndex(); - - buttonMap[KeyEvent.VK_Q] = Component.Identifier.Key.Q.getKeyIndex(); - buttonMap[KeyEvent.VK_W] = Component.Identifier.Key.W.getKeyIndex(); - buttonMap[KeyEvent.VK_E] = Component.Identifier.Key.E.getKeyIndex(); - buttonMap[KeyEvent.VK_R] = Component.Identifier.Key.R.getKeyIndex(); - buttonMap[KeyEvent.VK_T] = Component.Identifier.Key.T.getKeyIndex(); - buttonMap[KeyEvent.VK_Y] = Component.Identifier.Key.Y.getKeyIndex(); - buttonMap[KeyEvent.VK_U] = Component.Identifier.Key.U.getKeyIndex(); - buttonMap[KeyEvent.VK_I] = Component.Identifier.Key.I.getKeyIndex(); - buttonMap[KeyEvent.VK_O] = Component.Identifier.Key.O.getKeyIndex(); - buttonMap[KeyEvent.VK_P] = Component.Identifier.Key.P.getKeyIndex(); - buttonMap[KeyEvent.VK_A] = Component.Identifier.Key.A.getKeyIndex(); - buttonMap[KeyEvent.VK_S] = Component.Identifier.Key.S.getKeyIndex(); - buttonMap[KeyEvent.VK_D] = Component.Identifier.Key.D.getKeyIndex(); - buttonMap[KeyEvent.VK_F] = Component.Identifier.Key.F.getKeyIndex(); - buttonMap[KeyEvent.VK_G] = Component.Identifier.Key.G.getKeyIndex(); - buttonMap[KeyEvent.VK_H] = Component.Identifier.Key.H.getKeyIndex(); - buttonMap[KeyEvent.VK_J] = Component.Identifier.Key.J.getKeyIndex(); - buttonMap[KeyEvent.VK_K] = Component.Identifier.Key.K.getKeyIndex(); - buttonMap[KeyEvent.VK_L] = Component.Identifier.Key.L.getKeyIndex(); - buttonMap[KeyEvent.VK_Z] = Component.Identifier.Key.Z.getKeyIndex(); - buttonMap[KeyEvent.VK_X] = Component.Identifier.Key.X.getKeyIndex(); - buttonMap[KeyEvent.VK_C] = Component.Identifier.Key.C.getKeyIndex(); - buttonMap[KeyEvent.VK_V] = Component.Identifier.Key.V.getKeyIndex(); - buttonMap[KeyEvent.VK_B] = Component.Identifier.Key.B.getKeyIndex(); - buttonMap[KeyEvent.VK_N] = Component.Identifier.Key.N.getKeyIndex(); - buttonMap[KeyEvent.VK_M] = Component.Identifier.Key.M.getKeyIndex(); - - buttonMap[KeyEvent.VK_F1] = Component.Identifier.Key.F1.getKeyIndex(); - buttonMap[KeyEvent.VK_F2] = Component.Identifier.Key.F2.getKeyIndex(); - buttonMap[KeyEvent.VK_F3] = Component.Identifier.Key.F3.getKeyIndex(); - buttonMap[KeyEvent.VK_F4] = Component.Identifier.Key.F4.getKeyIndex(); - buttonMap[KeyEvent.VK_F5] = Component.Identifier.Key.F5.getKeyIndex(); - buttonMap[KeyEvent.VK_F6] = Component.Identifier.Key.F6.getKeyIndex(); - buttonMap[KeyEvent.VK_F7] = Component.Identifier.Key.F7.getKeyIndex(); - buttonMap[KeyEvent.VK_F8] = Component.Identifier.Key.F8.getKeyIndex(); - buttonMap[KeyEvent.VK_F9] = Component.Identifier.Key.F9.getKeyIndex(); - buttonMap[KeyEvent.VK_F10] = Component.Identifier.Key.F10.getKeyIndex(); - buttonMap[KeyEvent.VK_F11] = Component.Identifier.Key.F11.getKeyIndex(); - buttonMap[KeyEvent.VK_F12] = Component.Identifier.Key.F12.getKeyIndex(); - - buttonMap[KeyEvent.VK_ESCAPE] = Component.Identifier.Key.ESCAPE.getKeyIndex(); - buttonMap[KeyEvent.VK_MINUS] = Component.Identifier.Key.MINUS.getKeyIndex(); - buttonMap[KeyEvent.VK_EQUALS] = Component.Identifier.Key.EQUALS.getKeyIndex(); - buttonMap[KeyEvent.VK_BACK_SPACE] = Component.Identifier.Key.BACKSLASH.getKeyIndex(); - buttonMap[KeyEvent.VK_TAB] = Component.Identifier.Key.TAB.getKeyIndex(); - buttonMap[KeyEvent.VK_OPEN_BRACKET] = Component.Identifier.Key.LBRACKET.getKeyIndex(); - buttonMap[KeyEvent.VK_CLOSE_BRACKET] = Component.Identifier.Key.RBRACKET.getKeyIndex(); - //Enter is a special one - //Control is a special one - buttonMap[KeyEvent.VK_SEMICOLON] = Component.Identifier.Key.SEMICOLON.getKeyIndex(); - buttonMap[KeyEvent.VK_QUOTE] = Component.Identifier.Key.APOSTROPHE.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMBER_SIGN] = Component.Identifier.Key.GRAVE.getKeyIndex(); - //Shift is a special one - buttonMap[KeyEvent.VK_BACK_SLASH] = Component.Identifier.Key.BACKSLASH.getKeyIndex(); - //Comma is special - buttonMap[KeyEvent.VK_PERIOD] = Component.Identifier.Key.PERIOD.getKeyIndex(); - buttonMap[KeyEvent.VK_SLASH] = Component.Identifier.Key.SLASH.getKeyIndex(); - buttonMap[KeyEvent.VK_MULTIPLY] = Component.Identifier.Key.MULTIPLY.getKeyIndex(); - //Alt is a special one - buttonMap[KeyEvent.VK_SPACE] = Component.Identifier.Key.SPACE.getKeyIndex(); - buttonMap[KeyEvent.VK_CAPS_LOCK] = Component.Identifier.Key.CAPITAL.getKeyIndex(); - buttonMap[KeyEvent.VK_NUM_LOCK] = Component.Identifier.Key.NUMLOCK.getKeyIndex(); - buttonMap[KeyEvent.VK_SCROLL_LOCK] = Component.Identifier.Key.SCROLL.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD7] = Component.Identifier.Key.NUMPAD7.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD8] = Component.Identifier.Key.NUMPAD8.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD9] = Component.Identifier.Key.NUMPAD9.getKeyIndex(); - buttonMap[KeyEvent.VK_SUBTRACT] = Component.Identifier.Key.SUBTRACT.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD4] = Component.Identifier.Key.NUMPAD4.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD5] = Component.Identifier.Key.NUMPAD5.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD6] = Component.Identifier.Key.NUMPAD6.getKeyIndex(); - buttonMap[KeyEvent.VK_ADD] = Component.Identifier.Key.ADD.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD1] = Component.Identifier.Key.NUMPAD1.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD2] = Component.Identifier.Key.NUMPAD2.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD3] = Component.Identifier.Key.NUMPAD3.getKeyIndex(); - buttonMap[KeyEvent.VK_NUMPAD0] = Component.Identifier.Key.NUMPAD0.getKeyIndex(); - buttonMap[KeyEvent.VK_DECIMAL] = Component.Identifier.Key.DECIMAL.getKeyIndex(); - - buttonMap[KeyEvent.VK_KANA] = Component.Identifier.Key.KANA.getKeyIndex(); - buttonMap[KeyEvent.VK_CONVERT] = Component.Identifier.Key.CONVERT.getKeyIndex(); - buttonMap[KeyEvent.VK_NONCONVERT] = Component.Identifier.Key.NOCONVERT.getKeyIndex(); + protected AWTKeyboard() { + super("AWTKeyboard", createComponents(), new Controller[]{}, new Rumbler[]{}); + Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK); + resizeEventQueue(EVENT_QUEUE_DEPTH); + } - buttonMap[KeyEvent.VK_CIRCUMFLEX] = Component.Identifier.Key.CIRCUMFLEX.getKeyIndex(); - buttonMap[KeyEvent.VK_AT] = Component.Identifier.Key.AT.getKeyIndex(); - buttonMap[KeyEvent.VK_COLON] = Component.Identifier.Key.COLON.getKeyIndex(); - buttonMap[KeyEvent.VK_UNDERSCORE] = Component.Identifier.Key.UNDERLINE.getKeyIndex(); - buttonMap[KeyEvent.VK_KANJI] = Component.Identifier.Key.KANJI.getKeyIndex(); - - buttonMap[KeyEvent.VK_STOP] = Component.Identifier.Key.STOP.getKeyIndex(); + private final static Component[] createComponents() { + List components = new ArrayList(); + Field[] vkey_fields = KeyEvent.class.getFields(); + for (int i = 0; i < vkey_fields.length; i++) { + Field vkey_field = vkey_fields[i]; + try { + if (Modifier.isStatic(vkey_field.getModifiers()) && vkey_field.getType() == int.class && + vkey_field.getName().startsWith("VK_")) { + int vkey_code = vkey_field.getInt(null); + Component.Identifier.Key key_id = AWTKeyMap.mapKeyCode(vkey_code); + if (key_id != Component.Identifier.Key.UNKNOWN) + components.add(new Key(key_id)); + } + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + components.add(new Key(Component.Identifier.Key.RCONTROL)); + components.add(new Key(Component.Identifier.Key.LCONTROL)); + components.add(new Key(Component.Identifier.Key.RSHIFT)); + components.add(new Key(Component.Identifier.Key.LSHIFT)); + components.add(new Key(Component.Identifier.Key.RALT)); + components.add(new Key(Component.Identifier.Key.LALT)); + components.add(new Key(Component.Identifier.Key.NUMPADENTER)); + components.add(new Key(Component.Identifier.Key.RETURN)); + components.add(new Key(Component.Identifier.Key.NUMPADCOMMA)); + components.add(new Key(Component.Identifier.Key.COMMA)); + return (Component[])components.toArray(new Component[]{}); + } - buttonMap[KeyEvent.VK_DIVIDE] = Component.Identifier.Key.DIVIDE.getKeyIndex(); + private final void resizeEventQueue(int size) { + processed_events = new Event[size]; + for (int i = 0; i < processed_events.length; i++) + processed_events[i] = new Event(); + processed_events_index = 0; + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + resizeEventQueue(size); + } - buttonMap[KeyEvent.VK_PAUSE] = Component.Identifier.Key.PAUSE.getKeyIndex(); - buttonMap[KeyEvent.VK_HOME] = Component.Identifier.Key.HOME.getKeyIndex(); - buttonMap[KeyEvent.VK_UP] = Component.Identifier.Key.UP.getKeyIndex(); - buttonMap[KeyEvent.VK_PAGE_UP] = Component.Identifier.Key.PAGEUP.getKeyIndex(); - buttonMap[KeyEvent.VK_LEFT] = Component.Identifier.Key.LEFT.getKeyIndex(); - buttonMap[KeyEvent.VK_RIGHT] = Component.Identifier.Key.RIGHT.getKeyIndex(); - buttonMap[KeyEvent.VK_END] = Component.Identifier.Key.END.getKeyIndex(); - buttonMap[KeyEvent.VK_DOWN] = Component.Identifier.Key.DOWN.getKeyIndex(); - buttonMap[KeyEvent.VK_PAGE_DOWN] = Component.Identifier.Key.PAGEDOWN.getKeyIndex(); - buttonMap[KeyEvent.VK_INSERT] = Component.Identifier.Key.INSERT.getKeyIndex(); - buttonMap[KeyEvent.VK_DELETE] = Component.Identifier.Key.DELETE.getKeyIndex(); - - //Windows key is a special one + public final synchronized void eventDispatched(AWTEvent event) { + if (event instanceof KeyEvent) + awt_events.add(event); + } - // start working - Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK); - } + public final synchronized void pollDevice() throws IOException { + for (int i = 0; i < awt_events.size(); i++) { + KeyEvent event = (KeyEvent)awt_events.get(i); + processEvent(event); + } + awt_events.clear(); + } - /* (non-Javadoc) - * @see net.java.games.input.Keyboard#isKeyPressed(net.java.games.input.Keyboard.Key) - */ - protected boolean isKeyPressed(Key key) { - int keyId = ((Component.Identifier.Key)key.getIdentifier()).getKeyIndex(); - return buttonValues[keyId]; + private final void processEvent(KeyEvent event) { + Component.Identifier.Key key_id = AWTKeyMap.map(event); + if (key_id == null) + return; + Key key = (Key)getComponent(key_id); + if (key == null) + return; + long nanos = event.getWhen()*1000000L; + if (event.getID() == KeyEvent.KEY_PRESSED) { + //the key was pressed + addEvent(key, 1, nanos); + } else if (event.getID() == KeyEvent.KEY_RELEASED) { + KeyEvent nextPress = (KeyEvent)Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent(KeyEvent.KEY_PRESSED); + if ((nextPress == null) || (nextPress.getWhen() != event.getWhen())) { + //the key came really came up + addEvent(key, 0, nanos); + } + } } - /* (non-Javadoc) - * @see net.java.games.input.Controller#poll() - */ - public boolean poll() { - return true; - } + private final void addEvent(Key key, float value, long nanos) { + key.setValue(value); + if (processed_events_index < processed_events.length) + processed_events[processed_events_index++].set(key, value, nanos); + } - /* (non-Javadoc) - * @see java.awt.event.AWTEventListener#eventDispatched(java.awt.AWTEvent) - */ - public void eventDispatched(AWTEvent event) { - if(event instanceof KeyEvent) { - KeyEvent keyEvent = (KeyEvent)event; - if(keyEvent.getID() == KeyEvent.KEY_PRESSED) { - //the key was pressed - //System.out.println("Key pressed KeyCode: " + keyEvent.getKeyCode() + " KeyChar: " + keyEvent.getKeyChar()); - buttonValues[findKeyIndex(keyEvent)] = true; - } else if(keyEvent.getID() == KeyEvent.KEY_RELEASED) { - KeyEvent nextPress = (KeyEvent)Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent(KeyEvent.KEY_PRESSED); - - if ((nextPress == null) || (nextPress.getWhen() != keyEvent.getWhen())) { - //the key came really came up - //System.out.println("Key released KeyCode: " + keyEvent.getKeyCode() + " KeyChar: " + keyEvent.getKeyChar()); - buttonValues[findKeyIndex(keyEvent)] = false; - } - } else { - //System.out.println("AWTKeyboard: Ignoring event " + keyEvent.getID()); - } - } else { - throw new IllegalArgumentException("AWTKeyboard not expecting event of type " + event.getClass().getName()); - } - } + protected final synchronized boolean getNextDeviceEvent(Event event) throws IOException { + if (processed_events_index == 0) + return false; + processed_events_index--; + event.set(processed_events[0]); + Event tmp = processed_events[0]; + processed_events[0] = processed_events[processed_events_index]; + processed_events[processed_events_index] = tmp; + return true; + } - private int findKeyIndex(KeyEvent keyEvent) { - int buttonIndex = 0; - if(keyEvent.getKeyCode() == KeyEvent.VK_CONTROL) { - if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { - buttonIndex = Component.Identifier.Key.LCONTROL.getKeyIndex(); - } else if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT) { - buttonIndex = Component.Identifier.Key.RCONTROL.getKeyIndex(); - } - } else if(keyEvent.getKeyCode() == KeyEvent.VK_SHIFT) { - if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { - buttonIndex = Component.Identifier.Key.LSHIFT.getKeyIndex(); - } else if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT) { - buttonIndex = Component.Identifier.Key.RSHIFT.getKeyIndex(); - } - } else if(keyEvent.getKeyCode() == KeyEvent.VK_ALT) { - if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { - buttonIndex = Component.Identifier.Key.LALT.getKeyIndex(); - } else if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT) { - buttonIndex = Component.Identifier.Key.RALT.getKeyIndex(); - } -//this is 1.5 only -/* } else if(keyEvent.getKeyCode() == KeyEvent.VK_WINDOWS) { - if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { - buttonIndex = Component.Identifier.Key.LWIN.getKeyIndex(); - } else if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT) { - buttonIndex = Component.Identifier.Key.RWIN.getKeyIndex(); - }*/ - } else if(keyEvent.getKeyCode() == KeyEvent.VK_ENTER) { - if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_NUMPAD) { - buttonIndex = Component.Identifier.Key.NUMPADENTER.getKeyIndex(); - } else { - buttonIndex = Component.Identifier.Key.RETURN.getKeyIndex(); - } - } else if(keyEvent.getKeyCode() == KeyEvent.VK_COMMA) { - if(keyEvent.getKeyLocation() == KeyEvent.KEY_LOCATION_NUMPAD) { - buttonIndex = Component.Identifier.Key.NUMPADCOMMA.getKeyIndex(); - } else { - buttonIndex = Component.Identifier.Key.COMMA.getKeyIndex(); - } - } else { - buttonIndex = buttonMap[keyEvent.getKeyCode()]; - } - if(buttonIndex == 0 ) { - System.out.println("Unrecognised key: " + keyEvent.getKeyCode() + " (" + keyEvent.getKeyLocation() + " " + keyEvent.getKeyChar() + ")"); - } - return buttonIndex; - } + + private final static class Key extends AbstractComponent { + private float value; + + public Key(Component.Identifier.Key key_id) { + super(key_id.getName(), key_id); + } + + public final void setValue(float value) { + this.value = value; + } + + protected final float poll() { + return value; + } + + public final boolean isAnalog() { + return false; + } + + public final boolean isRelative() { + return false; + } + } } diff --git a/plugins/awt/src/net/java/games/input/AWTMouse.java b/plugins/awt/src/net/java/games/input/AWTMouse.java index ed76ed6..37c8eee 100644 --- a/plugins/awt/src/net/java/games/input/AWTMouse.java +++ b/plugins/awt/src/net/java/games/input/AWTMouse.java @@ -33,165 +33,190 @@ import java.awt.event.AWTEventListener; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; +import java.util.List; +import java.util.ArrayList; + +import java.io.IOException; + /** * @author Jeremy - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates + * @author elias */ -public class AWTMouse extends Mouse implements AWTEventListener { - - private AWTAxis xMove = new AWTAxis("X", Component.Identifier.Axis.X); - private AWTAxis yMove = new AWTAxis("Y", Component.Identifier.Axis.Y); - private AWTAxis zMove = new AWTAxis("Wheel", Component.Identifier.Axis.SLIDER); - - private AWTButton button1 = new AWTButton("Left", Component.Identifier.Button.LEFT); - private AWTButton button2 = new AWTButton("Middle", Component.Identifier.Button.MIDDLE); - private AWTButton button3 = new AWTButton("Right", Component.Identifier.Button.RIGHT); - - private Point oldMouseLocation = new Point(0,0); - private Point newMouseLocation = new Point(0,0); - private int scrollAmount = 0; - private boolean button1Value = false; - private boolean button2Value = false; - private boolean button3Value = false; - - /** - * @param name - */ - protected AWTMouse(String name) { - super(name); +final class AWTMouse extends Mouse implements AWTEventListener { + private final static int EVENT_X = 1; + private final static int EVENT_Y = 2; + private final static int EVENT_BUTTON = 4; + + private final List awt_events = new ArrayList(); + private final List processed_awt_events = new ArrayList(); + + private int event_state = EVENT_X; + + protected AWTMouse() { + super("AWTMouse", createComponents(), new Controller[]{}, new Rumbler[]{}); Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK); - this.ball = new AWTMouseBall(xMove, yMove, zMove); - this.buttons = new AWTMouseButtons(new AWTMouseButton(button1), new AWTMouseButton(button2), new AWTMouseButton(button3)); } - /* (non-Javadoc) - * @see net.java.games.input.Controller#poll() - */ - public boolean poll() { - button1.setValue(button1Value); - button2.setValue(button2Value); - button3.setValue(button3Value); - - zMove.setValue(scrollAmount); - scrollAmount = 0; - - //System.out.println("old mouse location " + oldMouseLocation); - //System.out.println("new mouse location " + newMouseLocation); - yMove.setValue((float)(newMouseLocation.getY() - oldMouseLocation.getY())); - xMove.setValue((float)(newMouseLocation.getX() - oldMouseLocation.getX())); - oldMouseLocation.setLocation(newMouseLocation.getLocation()); - //newMouseLocation.setLocation(0,0); - - return true; - } + private final static Component[] createComponents() { + return new Component[]{new Axis(Component.Identifier.Axis.X), + new Axis(Component.Identifier.Axis.Y), + new Axis(Component.Identifier.Axis.Z), + new Button(Component.Identifier.Button.LEFT), + new Button(Component.Identifier.Button.MIDDLE), + new Button(Component.Identifier.Button.RIGHT)}; + } - /* (non-Javadoc) - * @see java.awt.event.AWTEventListener#eventDispatched(java.awt.AWTEvent) - */ - public void eventDispatched(AWTEvent event) { - //System.out.println("AWTMouse: From: " + arg0.getSource() + " - " + arg0); - if(event instanceof MouseWheelEvent) { + private final void processButtons(int button_enum, float value) { + Button button = getButton(button_enum); + if (button != null) + button.setValue(value); + } + + private final Button getButton(int button_enum) { + switch (button_enum) { + case MouseEvent.BUTTON1: + return (Button)getLeft(); + case MouseEvent.BUTTON2: + return (Button)getMiddle(); + case MouseEvent.BUTTON3: + return (Button)getRight(); + case MouseEvent.NOBUTTON: + default: + // Unknown button + return null; + } + } + + private final void processEvent(AWTEvent event) throws IOException { + if (event instanceof MouseWheelEvent) { MouseWheelEvent mwe = (MouseWheelEvent)event; - scrollAmount += mwe.getWheelRotation(); - //System.out.println("New scroll amount: " + scrollAmount); - } - if(event instanceof MouseEvent) { + Axis wheel = (Axis)getWheel(); + wheel.setValue(wheel.poll() + mwe.getWheelRotation()); + } else if (event instanceof MouseEvent) { MouseEvent me = (MouseEvent)event; - newMouseLocation.setLocation(me.getPoint()); - //System.out.println("Mouse moved to " + newMouseLocation); - if(me.getID() == MouseEvent.MOUSE_PRESSED) { - //System.out.println("Button was pressed"); - if(me.getButton() == MouseEvent.BUTTON1) { - //System.out.println("Button 1 was pressed"); - button1Value = true; - } else if(me.getButton() == MouseEvent.BUTTON2) { - //System.out.println("Button 2 was pressed"); - button2Value = true; - } else if(me.getButton() == MouseEvent.BUTTON3) { - //System.out.println("Button 3 was pressed"); - button3Value = true; - } - } else if(me.getID() == MouseEvent.MOUSE_RELEASED) { - //ystem.out.println("Button was released"); - if(me.getButton() == MouseEvent.BUTTON1) { - //System.out.println("Button 1 was released"); - button1Value = false; - } else if(me.getButton() == MouseEvent.BUTTON2) { - //System.out.println("Button 2 was released"); - button2Value = false; - } else if(me.getButton() == MouseEvent.BUTTON3) { - //System.out.println("Button 3 was released"); - button3Value = false; - } - } else { - //System.out.println("Mouse event ID " + me.getID() + " (" + me.getClass().getName() + ")"); - } - } else { - System.out.println("AWTMouse got an event of type " + event.getClass().getName()); - } - } + Axis x = (Axis)getX(); + Axis y = (Axis)getY(); + x.setValue(me.getX()); + y.setValue(me.getY()); + switch (me.getID()) { + case MouseEvent.MOUSE_PRESSED: + processButtons(me.getButton(), 1f); + break; + case MouseEvent.MOUSE_RELEASED: + processButtons(me.getButton(), 0f); + break; + default: + break; + } + } + } - /** Mouse ball under AWT - */ - private class AWTMouseBall extends Ball { - /** Constructs the new mouse ball - * @param x The x axis - * @param y The y axis - * @param wheel The mouse wheel axis - */ - public AWTMouseBall(Component x, Component y, Component wheel) { - super(AWTMouse.this.getName() + " ball"); - this.x = x; - this.y = y; - this.wheel = wheel; + public final synchronized void pollDevice() throws IOException { + Axis wheel = (Axis)getWheel(); + wheel.setValue(0); + for (int i = 0; i < awt_events.size(); i++) { + AWTEvent event = (AWTEvent)awt_events.get(i); + processEvent(event); + processed_awt_events.add(event); } - } + awt_events.clear(); + } - /** Mouse buttons under AWT - */ - private class AWTMouseButtons extends Buttons { - /** Creates the new mouse's buttons - * @param left Left mouse button - * @param right Right mouse button - * @param middle Middle mouse button - */ - public AWTMouseButtons(Button left, Button right, Button middle) { - super(AWTMouse.this.getName() + " buttons"); - this.left = left; - this.right = right; - this.middle = middle; - } - } + protected final synchronized boolean getNextDeviceEvent(Event event) throws IOException { + while (true) { + if (processed_awt_events.isEmpty()) + return false; + AWTEvent awt_event = (AWTEvent)processed_awt_events.get(0); + if (awt_event instanceof MouseWheelEvent) { + MouseWheelEvent awt_wheel_event = (MouseWheelEvent)awt_event; + long nanos = awt_wheel_event.getWhen()*1000000L; + event.set(getWheel(), awt_wheel_event.getWheelRotation(), nanos); + processed_awt_events.remove(0); + } else if (awt_event instanceof MouseEvent) { + MouseEvent mouse_event = (MouseEvent)awt_event; + long nanos = mouse_event.getWhen()*1000000L; + switch (event_state) { + case EVENT_X: + event_state = EVENT_Y; + event.set(getX(), mouse_event.getX(), nanos); + return true; + case EVENT_Y: + event_state = EVENT_BUTTON; + event.set(getY(), mouse_event.getY(), nanos); + return true; + case EVENT_BUTTON: + processed_awt_events.remove(0); + event_state = EVENT_X; + Button button = getButton(mouse_event.getButton()); + if (button != null) { + switch (mouse_event.getID()) { + case MouseEvent.MOUSE_PRESSED: + event.set(button, 1f, nanos); + return true; + case MouseEvent.MOUSE_RELEASED: + event.set(button, 0f, nanos); + return true; + default: + break; + } + } + break; + default: + throw new RuntimeException("Unknown event state: " + event_state); + } + } + } + } - /** AWT specific mouse buttons - */ - private class AWTMouseButton extends Mouse.Button { - /** The real Axis - */ - private Component realAxis; - - /** Construct an AWT mouse button from the given axis - * @param axis The axis that holds the data - */ - public AWTMouseButton(Component axis) { - super(axis.getName(), (Component.Identifier.Button)axis.getIdentifier()); - this.realAxis = axis; - } - - /** Returns true f this axis is relative - * @return Always returns false for a mouse button - */ - public boolean isRelative() { - return false; - } - - /** Returns the data for this mouse button - * @return Retursn this mouse buttons value - */ - public float getPollData(){ - return realAxis.getPollData(); - } - } + public final synchronized void eventDispatched(AWTEvent event) { + awt_events.add(event); + } + + final static class Axis extends AbstractComponent { + private float value; + + public Axis(Component.Identifier.Axis axis_id) { + super(axis_id.getName(), axis_id); + } + + public final boolean isRelative() { + return false; + } + + public final boolean isAnalog() { + return true; + } + + protected final void setValue(float value) { + this.value = value; + } + + protected final float poll() throws IOException { + return value; + } + } + + final static class Button extends AbstractComponent { + private float value; + + public Button(Component.Identifier.Button button_id) { + super(button_id.getName(), button_id); + } + + protected final void setValue(float value) { + this.value = value; + } + + protected final float poll() throws IOException { + return value; + } + + public final boolean isAnalog() { + return false; + } + + public final boolean isRelative() { + return false; + } + } } diff --git a/plugins/common/src/native/util.c b/plugins/common/src/native/util.c new file mode 100644 index 0000000..25c4cf7 --- /dev/null +++ b/plugins/common/src/native/util.c @@ -0,0 +1,118 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <jni.h> +#include "util.h" + +static jstring sprintfJavaString(JNIEnv *env, const char *format, va_list ap) { +#define BUFFER_SIZE 4000 + char buffer[BUFFER_SIZE]; + jstring str; +#ifdef _WIN32 + _vsnprintf(buffer, BUFFER_SIZE, format, ap); +#else + vsnprintf(buffer, BUFFER_SIZE, format, ap); +#endif + buffer[BUFFER_SIZE - 1] = '\0'; + str = (*env)->NewStringUTF(env, buffer); + return str; +} + +void printfJava(JNIEnv *env, const char *format, ...) { + jstring str; + jclass org_lwjgl_LWJGLUtil_class; + jmethodID log_method; + va_list ap; + va_start(ap, format); + str = sprintfJavaString(env, format, ap); + va_end(ap); + org_lwjgl_LWJGLUtil_class = (*env)->FindClass(env, "net/java/games/input/ControllerEnvironment"); + if (org_lwjgl_LWJGLUtil_class == NULL) + return; + log_method = (*env)->GetStaticMethodID(env, org_lwjgl_LWJGLUtil_class, "log", "(Ljava/lang/String;)V"); + if (log_method == NULL) + return; + (*env)->CallStaticVoidMethod(env, org_lwjgl_LWJGLUtil_class, log_method, str); +} + +static void throwException(JNIEnv * env, const char *exception_name, const char *format, va_list ap) { + jstring str; + jobject exception; + + if ((*env)->ExceptionCheck(env) == JNI_TRUE) + return; // The JVM crashes if we try to throw two exceptions from one native call + str = sprintfJavaString(env, format, ap); + exception = newJObject(env, exception_name, "(Ljava/lang/String;)V", str); + (*env)->Throw(env, exception); +} + +void throwRuntimeException(JNIEnv * env, const char *format, ...) { + va_list ap; + va_start(ap, format); + throwException(env, "java/lang/RuntimeException", format, ap); + va_end(ap); +} + +void throwIOException(JNIEnv * env, const char *format, ...) { + va_list ap; + va_start(ap, format); + throwException(env, "java/io/IOException", format, ap); + va_end(ap); +} + +jobject newJObject(JNIEnv * env, const char *class_name, const char *constructor_signature, ...) { + va_list ap; + jclass clazz; + jmethodID constructor; + jobject obj; + + clazz = (*env)->FindClass(env, class_name); + if (clazz == NULL) + return NULL; + constructor = (*env)->GetMethodID(env, clazz, "<init>", constructor_signature); + if (constructor == NULL) + return NULL; + va_start(ap, constructor_signature); + obj = (*env)->NewObjectV(env, clazz, constructor, ap); + va_end(ap); + return obj; +} + diff --git a/plugins/common/src/native/util.h b/plugins/common/src/native/util.h new file mode 100644 index 0000000..58a62f4 --- /dev/null +++ b/plugins/common/src/native/util.h @@ -0,0 +1,48 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <jni.h> + +extern void printfJava(JNIEnv *env, const char *format, ...); +extern void throwRuntimeException(JNIEnv * env, const char *format, ...); +extern void throwIOException(JNIEnv * env, const char *format, ...); +extern jobject newJObject(JNIEnv * env, const char *class_name, const char *constructor_signature, ...); + diff --git a/plugins/linux/build.xml b/plugins/linux/build.xml index a120a51..c2a5fa8 100644 --- a/plugins/linux/build.xml +++ b/plugins/linux/build.xml @@ -1,32 +1,32 @@ <?xml version="1.0" encoding="UTF-8"?> <project basedir="." default="all" name="Linux Plugin"> - <target name="init"> - <property name="hello" value="world"/> <mkdir dir="classes"/> <mkdir dir="bin"/> + <condition property="linux" > + <!--<os family="unix" />--> + <os name="Linux" /> + </condition> + </target> <target depends="init" name="compile"> + <!-- <ant dir="src/native" target="createNativeDefinitions.java"/>--> <javac debug="true" deprecation="true" destdir="classes" source="1.4" target="1.4" srcdir="src/java"> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> - <pathelement location="../../coreAPI/lib/jutils.jar"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> </classpath> </javac> </target> <target depends="init,compile" name="jar"> <jar jarfile="bin/linux.jar" compress="true" basedir="classes"> - <exclude name="**/*.java"/> - <exclude name="linux.jar"/> - <exclude name="apidoc"/> + <include name="**/*.class"/> </jar> - <copy file="bin/linux.jar" todir="../../coreAPI/src/tests/controller" /> </target> - <target depends="compileNativeJinputLib,jar" description="Build everything." name="all"> - <echo message="Application built. Hello ${hello}!"/> + <target depends="jar,compileNativeJinputLib" description="Build everything." name="all"> </target> <target name="javadoc" depends="init" description="Javadoc for Linux plugin for JInput."> @@ -39,43 +39,31 @@ <pathelement location="src/java"/> </sourcepath> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> <pathelement location="../../coreAPI/lib/jutils.jar"/> </classpath> </javadoc> </target> <target description="Clean all build products." name="clean"> - <delete failonerror="no"> - <fileset dir="classes"> - <include name="**/*.class"/> - </fileset> - </delete> - <delete file="bin/linux.jar" failonerror="no"/> - <delete file="src/native/libjinput-linux.so" failonerror="no"/> - <delete file="../../coreAPI/src/tests/controller/linux.jar" failonerror="no" /> - <delete file="../../coreAPI/src/tests/controller/libjinput-linux.so" failonerror="no"/> - <delete file="apidoc" failonerror="no"/> + <delete dir="classes" failonerror="no"/> + <delete dir="bin" failonerror="no"/> + <delete dir="apidocs" failonerror="no"/> + <ant inheritAll="false" antfile="src/native/build.xml" target="clean"/> </target> <target depends="init,compile" name="createJNIHeaders"> - <javah destdir="src/native"> + <javah destdir="src/native"> <classpath> - <pathelement location="../../coreAPI/bin/jinput.jar"/> - <pathelement location="bin/linux.jar"/> + <pathelement location="classes"/> </classpath> - <class name="net.java.games.input.JInputLibrary"/> - </javah> - </target> - - <target depends="init" name="createNativeDefinitions.java"> - <exec dir="." executable="./getDefinitions" os="linux" output="src/java/net/java/games/input/NativeDefinitions.java"> - <arg line="/usr/include/linux/input.h"/> - </exec> + <class name="net.java.games.input.LinuxEventDevice"/> + <class name="net.java.games.input.LinuxJoystickDevice"/> + </javah> </target> - <target depends="init" name="compileNativeJinputLib"> + <target depends="init,createJNIHeaders" name="compileNativeJinputLib" if="linux"> <ant dir="src/native" target="compileNativeJinputLib"/> - <copy file="src/native/libjinput-linux.so" todir="../../coreAPI/src/tests/controller" /> + <copy file="src/native/libjinput-linux.so" todir="bin" /> </target> </project> diff --git a/plugins/linux/src/java/net/java/games/input/JInputLibrary.java b/plugins/linux/src/java/net/java/games/input/JInputLibrary.java deleted file mode 100644 index 5dbd217..0000000 --- a/plugins/linux/src/java/net/java/games/input/JInputLibrary.java +++ /dev/null @@ -1,244 +0,0 @@ -package net.java.games.input; - -public class JInputLibrary { - static { - if(isSupported()) { - System.loadLibrary("jinput-linux"); - } - } - - private static boolean inited = false; - private static Object workerThreadMonitor = new Object(); - private static boolean shutdown = false; - private static Object shutdownThreadMonitor = new Object(); - private static boolean cleanupDone = false; - private static int rumbler = -1; - private static float force; - - public static boolean isSupported() { - System.out.println("OS name is: " + System.getProperty("os.name")); - if(System.getProperty("os.name").indexOf("Linux")!=-1) { - System.out.println("Linux plugin is supported"); - return true; - } - System.out.println("Linux plugin is not supported"); - return false; - } - - public static void init() { - if(!inited) { - System.out.println("Initing JInputLibrary"); - Thread initShutdownThread = new Thread() { - public void run() { - - nativeInit(); - inited=true; - - synchronized (workerThreadMonitor) { - workerThreadMonitor.notify(); - } - - synchronized(workerThreadMonitor) { - while(!shutdown) { - System.out.println("Waiting on monitor"); - System.out.flush(); - try { - workerThreadMonitor.wait(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - if(rumbler>=0) { - nativeRumble(rumbler,force); - rumbler =-1; - } - } - } - System.out.println("Cleaning up from shutdown thread"); - realCleanup(); - cleanupDone = true; - synchronized (shutdownThreadMonitor) { - System.out.println("Notifying on shutdownThreadMonitor after shutdown"); - System.out.flush(); - shutdownThreadMonitor.notifyAll(); - System.out.println("Notified on shutdownThreadMonitor after shutdown"); - System.out.flush(); - } - } - }; - - initShutdownThread.setDaemon(true); - initShutdownThread.start(); - - System.out.println("Shutdown thread created and run"); - - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { - cleanup(); - } - }); - - synchronized (workerThreadMonitor) { - while(!inited) { - try { - workerThreadMonitor.wait(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - } - } - } - - private static void realCleanup() { - //Give the rumblers chance to cleanup - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - System.out.println("Environment cleanup"); - for(int i=0;i<JInputLibrary.getNumberOfDevices();i++) { - if(JInputLibrary.getFFEnabled(i)) { - JInputLibrary.nativeRumble(i, 0f); - } - JInputLibrary.nativeCleanup(i); - } - } - - public static void rumble(int rumblerNo, float forceValue) { - rumbler = rumblerNo; - force = forceValue; - synchronized (workerThreadMonitor) { - System.out.println("Notifying clean up thread"); - System.out.flush(); - workerThreadMonitor.notify(); - } - } - - private static void cleanup() { - shutdown = true; - System.out.println("Trying to notify for cleanup"); - System.out.flush(); - synchronized (workerThreadMonitor) { - System.out.println("Notifying clean up thread"); - System.out.flush(); - workerThreadMonitor.notify(); - } - - while(!cleanupDone) { - synchronized (shutdownThreadMonitor) { - try { - System.out.println("cleanup waiting on shutdownThreadMonitor"); - System.out.flush(); - shutdownThreadMonitor.wait(); - System.out.println("cleanup done waiting on shutdownThreadMonitor"); - System.out.flush(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } - - /** Call to poll the device at the native library - * @param deviceID The native device ID - * @param buttonData Array to populate with button values - * @param relAxesData Array to populate with relative axes values - * @param absAxesData Array to populate with absolute axes values - * @return the number of events read - */ - public static int safePoll(int deviceID, int buttonData[], int relAxesData[], int absAxesData[]) { - if(!shutdown) { - return poll(deviceID, buttonData, relAxesData, absAxesData); - } - - return 0; - } - - - /** Get the name of a device from the native library - * @param deviceID The device id - * @return The devices name - */ - public static native String getDeviceName(int deviceID); - /** Get the number of absolute axes for the requested device - * @param deviceID The device ID - * @return The number of abs axes - */ - public static native int getNumAbsAxes(int deviceID); - /** Get the nmber or relative axes from the native library - * @param deviceID The native device ID - * @return The number of raltive axes for the device - */ - public static native int getNumRelAxes(int deviceID); - /** Gets the number of buttons for the requested devce from the native library - * @param deviceID The device ID - * @return The number of buttons - */ - public static native int getNumButtons(int deviceID); - /** Initialises the native library - * @return <0 if something went wrong - */ - private static native int nativeInit(); - /** Gets the number of devices the native library found - * @return Th number of devices - */ - public static native int getNumberOfDevices(); - /** Native call to get the supported absolute axes for a device - * @param deviceID The native device number - * @param supportedAbsAxes aray to populate - */ - public static native void getSupportedAbsAxes(int deviceID, int supportedAbsAxes[]); - /** Native call to get the supported relative axes for a device - * @param deviceID The native device number - * @param supportedRelAxes aray to populate - */ - public static native void getSupportedRelAxes(int deviceID, int supportedRelAxes[]); - /** Native call to get the supported buttons for a device - * @param deviceID The native device ID - * @param supportedButtons The array to populate - */ - public static native void getSupportedButtons(int deviceID, int supportedButtons[]); - /** Call to poll the device at the native library - * @param deviceID The native device ID - * @param buttonData Array to populate with button values - * @param relAxesData Array to populate with relative axes values - * @param absAxesData Array to populate with absolute axes values - * @return the number of events read - */ - public static native int poll(int deviceID, int buttonData[], int relAxesData[], int absAxesData[]); - /** Returns the fuzz of an axis fro mthe native lib - * @param deviceID The native device id - * @param axisID The native axis ID - * @return The fuzz - */ - public static native int getAbsAxisFuzz(int deviceID, int axisID); - /** Gets the maximum value for an absloute axis fr omthe native library - * @param deviceID The native device ID - * @param axisID The native axis ID - * @return The Max value - */ - public static native int getAbsAxisMaximum(int deviceID, int axisID); - /** Gets the minimum value for an absloute axis from the native library - * @param deviceID The native device ID - * @param axisID The native axis number - * @return The min value - */ - public static native int getAbsAxisMinimum(int deviceID, int axisID); - /** Gets the port type from the native lib - * @param deviceID The device to get the port type for - * @return The port type - */ - public static native int getNativePortType(int deviceID); - - public static native boolean getFFEnabled(int deviceID); - - private static native void nativeRumble(int deviceID, float intensity); - - private static native void nativeCleanup(int deviceID); -} diff --git a/plugins/linux/src/native/JoystickDevice.h b/plugins/linux/src/java/net/java/games/input/LinuxAbsInfo.java index 87afa4d..a2b9456 100644 --- a/plugins/linux/src/native/JoystickDevice.h +++ b/plugins/linux/src/java/net/java/games/input/LinuxAbsInfo.java @@ -23,48 +23,47 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE */ +package net.java.games.input; -#ifndef JoystickDevice_h -#define JoystickDevice_h +/** + * @author elias + */ +final class LinuxAbsInfo { + private int value; + private int minimum; + private int maximum; + private int fuzz; + private int flat; + + public final void set(int value, int min, int max, int fuzz, int flat) { + this.value = value; + this.minimum = min; + this.maximum = max; + this.fuzz = fuzz; + this.flat = flat; + } -#include <stdint.h> -#include <linux/input.h> -#include "eventInterfaceTypes.h" -#include "Device.h" + public final String toString() { + return "AbsInfo: value = " + value + " | min = " + minimum + " | max = " + maximum + " | fuzz = " + fuzz + " | flat = " + flat; + } -class JoystickDevice : public Device { + public final int getValue() { + return value; + } - private: - int fd; - int inited; - char *name; - int numButtons; - int *absAxesData; - uint8_t *buttonData; - int numAbsAxes; + final int getMax() { + return maximum; + } - public: - JoystickDevice(char *deviceFilename); - int getNumberRelAxes(); - int getNumberAbsAxes(); - int getNumberButtons(); - const char *getName(); - int getBusType(); - int getVendorID(); - int getProductID(); - int getVersion(); - void getSupportedRelAxes(int supportedAxis[]); - void getSupportedAbsAxes(int supportedAxis[]); - void getSupportedButtons(int supportedButtons[]); - int poll(); - void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]); - int getAbsAxisMinimum(int axisNumber); - int getAbsAxisMaximum(int axisNumber); - int getAbsAxisFuzz(int axisNumber); - int isValidDevice(); - bool getFFEnabled(); - void rumble(float force); - void cleanup(); -}; + final int getMin() { + return minimum; + } + + final int getFlat() { + return flat; + } -#endif //eventInterface_eventDevice_h + final int getFuzz() { + return fuzz; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxAbstractController.java b/plugins/linux/src/java/net/java/games/input/LinuxAbstractController.java new file mode 100644 index 0000000..7efbfb1 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxAbstractController.java @@ -0,0 +1,74 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents a Linux controller +* @author elias +* @version 1.0 +*/ +final class LinuxAbstractController extends AbstractController { + private final PortType port; + private final LinuxEventDevice device; + private final Type type; + + protected LinuxAbstractController(LinuxEventDevice device, Component[] components, Controller[] children, Rumbler[] rumblers, Type type) throws IOException { + super(device.getName(), components, children, rumblers); + this.device = device; + this.port = device.getPortType(); + this.type = type; + } + + public final PortType getPortType() { + return port; + } + + public final void pollDevice() throws IOException { + device.pollKeyStates(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return LinuxControllers.getNextDeviceEvent(event, device); + } + + public Type getType() { + return type; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxAxis.java b/plugins/linux/src/java/net/java/games/input/LinuxAxis.java deleted file mode 100644 index 21f3bc5..0000000 --- a/plugins/linux/src/java/net/java/games/input/LinuxAxis.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -package net.java.games.input; - -import net.java.games.input.AbstractComponent; -import net.java.games.input.LinuxDevice; - -/** Represents an Axis absolute or relative - * - * @author Jeremy Booth ([email protected]) - */ -public class LinuxAxis extends AbstractComponent { - - /** The controller this axis is part of */ - private LinuxDevice controller; - /** The native ID of this axis */ - private int axisID; - /** The null zone, defaulted to 0 */ - private float nullZone = 0.0f; - /** Is this axis analog */ - private boolean isAnalog = true; - /** Are the values returned by getPollData normalised */ - private boolean isNormalized = false; - /** Is this a relative axis */ - private boolean isRelative = false; - /** Should we normalise the value before returning it in getPollData */ - private boolean needsNormalising = false; - /** The minimum possible axis value (not always used) */ - private float minAxisValue; - /** The maximum possibe axis value (not always used */ - private float maxAxisValue; - /** The current value of the axis */ - private float value = 0.0f; - - /** - * Creates a new instance of LinuxAxis - * @param controller The parent Controller - * @param axisID The native ID of this axis - * @param name The name of this axis - * @param id The Axis.Identifier of this axis - * @param deadzone The deadzone (null zone) of this axis - * @param isAnalog Is this axis analog - * @param isNormalized Is this axis normalised - * @param isRelative Is this axis relative - */ - public LinuxAxis(LinuxDevice controller, int axisID, String name, Identifier id, float deadzone, boolean isAnalog, boolean isNormalized, boolean isRelative) { - super(name, id); - this.controller = controller; - this.axisID = axisID; - this.nullZone = deadzone; - this.isAnalog = isAnalog; - this.isNormalized = isNormalized; - this.isRelative = isRelative; - - } - - /** Creates a new instance of LinuxAxis, it will auto normalise the data based on - * the minimum and maximum values provided - * @param controller The parent Controller - * @param axisID The native ID of this axis - * @param name The name of this axis - * @param id The Axis.Identifier of this axis - * @param deadzone The deadzone (null zone) of this axis - * @param isAnalog Is this axis analog - * @param isRelative Is this axis relative - * @param minAxisValue Minimum value that the native library will return for this axis - * @param maxAxisValue Maximum value that the native library will return for this axis - */ - public LinuxAxis(LinuxDevice controller, int axisID, String name, Identifier id, float deadzone, boolean isAnalog, boolean isRelative, float minAxisValue, float maxAxisValue) { - super(name, id); - - this.controller = controller; - this.axisID = axisID; - this.nullZone = deadzone; - this.isAnalog = isAnalog; - this.isNormalized = false; - this.isRelative = isRelative; - this.needsNormalising = true; - this.minAxisValue = minAxisValue; - this.maxAxisValue = maxAxisValue; - - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - */ - public boolean isRelative() { - return isRelative; - } - - /** Returns the suggested dead zone for this axis. Dead zone is the - * amount polled data can vary before considered a significant change - * in value. An application can safely ignore changes less than this - * value in the positive or negative direction. - * @return 0.0f by default, can be overridden - */ - public float getDeadZone() { - return nullZone; - } - - /** Returns whether or not the axis is analog, or false if it is digital. - * @return false by default, can be overridden - */ - public boolean isAnalog() { - return isAnalog; - } - - /** Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return 0.0f by default, can be overridden - */ - public float getPollData() { - if(isPolling()) { - updateValue(); - } - return value; - } - - /** Update this axis data from the latest native poll value - */ - private void updateValue() { - if(isAnalog) { - float tempVal; - - if(isRelative) { - tempVal = (float)controller.getRelAxisValue(axisID); - } else { - tempVal = (float)controller.getAbsAxisValue(axisID); - } - if(needsNormalising) { - if(isRelative) { - if(tempVal>1) { - tempVal = 1; - } else if(tempVal<-1) { - tempVal = -1; - } - value = tempVal; - } else { - //float center = (minAxisValue + maxAxisValue) / 2; - //value = (tempVal - center) / center; - float center = ((maxAxisValue - minAxisValue)/2); - value = (((tempVal - minAxisValue) - center) / center); - //System.out.println("tempVal: " + tempVal + " minAxisValue: " + minAxisValue + " maxAxisValue: " + maxAxisValue + " center: " + center + " value: " + value); - //System.out.flush(); - } - } else { - value = tempVal; - } - } else { - value = (float)controller.getButtonValue(axisID); - } - } - - /** Returns whether or not data polled from this axis is normalized - * between the values of -1.0f and 1.0f. - * @return true by default, can be overridden - */ - public boolean isNormalized() { - return (isNormalized || needsNormalising); - } - -} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxAxisDescriptor.java b/plugins/linux/src/java/net/java/games/input/LinuxAxisDescriptor.java new file mode 100644 index 0000000..d2e476d --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxAxisDescriptor.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +/** + * @author elias + */ +final class LinuxAxisDescriptor { + private int type; + private int code; + + public final void set(int type, int code) { + this.type = type; + this.code = code; + } + + public final int getType() { + return type; + } + + public final int getCode() { + return code; + } + + public final int hashCode() { + return type ^ code; + } + + public final boolean equals(Object other) { + if (!(other instanceof LinuxAxisDescriptor)) + return false; + LinuxAxisDescriptor descriptor = (LinuxAxisDescriptor)other; + return descriptor.type == type && descriptor.code == code; + } + + public final String toString() { + return "LinuxAxis: type = 0x" + Integer.toHexString(type) + ", code = 0x" + Integer.toHexString(code); + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxComponent.java b/plugins/linux/src/java/net/java/games/input/LinuxComponent.java new file mode 100644 index 0000000..8016deb --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxComponent.java @@ -0,0 +1,78 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents a linux Axis +* @author elias +* @version 1.0 +*/ +class LinuxComponent extends AbstractComponent { + private final LinuxEventComponent component; + + public LinuxComponent(LinuxEventComponent component) { + super(component.getIdentifier().getName(), component.getIdentifier()); + this.component = component; + } + + public final boolean isRelative() { + return component.isRelative(); + } + + public final boolean isAnalog() { + return component.isAnalog(); + } + + protected float poll() throws IOException { + return convertValue(LinuxControllers.poll(component), component.getDescriptor()); + } + + float convertValue(float value, LinuxAxisDescriptor descriptor) { + return getComponent().convertValue(value); + } + + public final float getDeadZone() { + return component.getDeadZone(); + } + + public final LinuxEventComponent getComponent() { + return component; + } +} diff --git a/plugins/linux/src/native/eventInterface.h b/plugins/linux/src/java/net/java/games/input/LinuxConstantFF.java index 92e421c..6610c5a 100644 --- a/plugins/linux/src/native/eventInterface.h +++ b/plugins/linux/src/java/net/java/games/input/LinuxConstantFF.java @@ -23,15 +23,20 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE */ +package net.java.games.input; -#if !defined(eventInterface_h) -#define eventInterface_h +import java.io.IOException; -#include "Device.h" - -int evGetEventInterfaceVersionNumber(); -int evInit(); -int evGetNumberDevices(); -void evGetDevices(Device **deviceList); +/** + * @author elias + */ +final class LinuxConstantFF extends LinuxForceFeedbackEffect { + public LinuxConstantFF(LinuxEventDevice device) throws IOException { + super(device); + } -#endif //eventInterface_h + protected final int upload(int id, float intensity) throws IOException { + int scaled_intensity = Math.round(intensity*0x7fff); + return getDevice().uploadConstantEffect(id, 0, 0, 0, 0, 0, scaled_intensity, 0, 0, 0, 0); + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxControllers.java b/plugins/linux/src/java/net/java/games/input/LinuxControllers.java new file mode 100644 index 0000000..e5edf81 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxControllers.java @@ -0,0 +1,81 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** helper methods for Linux specific Controllers +* @author elias +* @version 1.0 +*/ +final class LinuxControllers { + private final static LinuxEvent linux_event = new LinuxEvent(); + + /* Declared synchronized to protect linux_event */ + public final static synchronized boolean getNextDeviceEvent(Event event, LinuxEventDevice device) throws IOException { + while (device.getNextEvent(linux_event)) { + LinuxAxisDescriptor descriptor = linux_event.getDescriptor(); + LinuxComponent component = device.mapDescriptor(descriptor); + if (component != null) { + float value = component.convertValue(linux_event.getValue(), descriptor); + event.set(component, value, linux_event.getNanos()); + return true; + } + } + return false; + } + + private final static LinuxAbsInfo abs_info = new LinuxAbsInfo(); + + /* Declared synchronized to protect abs_info */ + public final static synchronized float poll(LinuxEventComponent event_component) throws IOException { + int native_type = event_component.getDescriptor().getType(); + switch (native_type) { + case NativeDefinitions.EV_KEY: + int native_code = event_component.getDescriptor().getCode(); + float state = event_component.getDevice().isKeySet(native_code) ? 1f : 0f; + return state; + case NativeDefinitions.EV_ABS: + event_component.getAbsInfo(abs_info); + return abs_info.getValue(); + default: + throw new RuntimeException("Unkown native_type: " + native_type); + } + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxDevice.java b/plugins/linux/src/java/net/java/games/input/LinuxDevice.java index 4f7c559..2f26a68 100644 --- a/plugins/linux/src/java/net/java/games/input/LinuxDevice.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxDevice.java @@ -25,680 +25,15 @@ */ package net.java.games.input; +import java.io.IOException; +import java.util.Map; +import java.util.HashMap; +import java.util.List; import java.util.ArrayList; /** - * Represents a device that is not a keyboard or mouse. - * @author Jeremy Booth ([email protected]) + * @author elias */ -public class LinuxDevice extends AbstractController { - - /** The name of the device - */ - private String name; - /** The native ID of the device - */ - private int nativeID; - /** The port type the device is attached to. - */ - private PortType portType; - /** List of buttons the device has - */ - private LinuxAxis[] buttons; - /** List of relative axes the device has - */ - private LinuxAxis[] relAxes; - /** List of absolute axes the device has - */ - private LinuxAxis[] absAxes; - /** List of coolie hats the device has - */ - private LinuxHat[] hats; - /** The id's of the coolie hat axes - */ - private int hatAxisIDs[] = new int[8]; - /** The number of buttons the device has - */ - private int numButtons; - /** The number of relative axes the device has - */ - private int numRelAxes; - /** The number of absolute axes the device has - */ - private int numAbsAxes; - /** The number of coolie hats the device has - */ - private int numHats=0; - /** The native button values. - */ - private int[] buttonData; - /** The native relative axes values - */ - private int[] relAxesData; - /** The native absolute axis values - */ - private int[] absAxesData; - /** A guess at the device type. - */ - private Type typeGuess = Type.UNKNOWN; - /** An array of the list of axes this device has - */ - private ArrayList axesArray = new ArrayList(); - - /** Creates a new instance of LinuxDevice - * @param nativeID The native ID of this device - * @param name The name of this device - * @param numButtons The number of buttons the devices has - * @param numRelAxes The number of raltive axes this device has - * @param numAbsAxes The number of absolute axes this device has - */ - public LinuxDevice(int nativeID, String name, int numButtons, int numRelAxes, int numAbsAxes, Controller.Type type) { - this(nativeID, name, numButtons, numRelAxes, numAbsAxes); - typeGuess = type; - } - - /** Creates a new instance of LinuxDevice - * @param nativeID The native ID of this device - * @param name The name of this device - * @param numButtons The number of buttons the devices has - * @param numRelAxes The number of raltive axes this device has - * @param numAbsAxes The number of absolute axes this device has - */ - public LinuxDevice(int nativeID, String name, int numButtons, int numRelAxes, int numAbsAxes) { - super(name); - - children = NO_CONTROLLERS; - rumblers = NO_RUMBLERS; - - this.nativeID = nativeID; - - portType = LinuxNativeTypesMap.getPortType(JInputLibrary.getNativePortType(nativeID)); - - for(int i=0;i<8;i++) { - hatAxisIDs[i] = -1; - } - - this.numButtons = numButtons; - this.numRelAxes = numRelAxes; - this.numAbsAxes = numAbsAxes; - this.numHats = 0; - - buttonData = new int[numButtons]; - relAxesData = new int[numRelAxes]; - absAxesData = new int[numAbsAxes]; - - createButtons(numButtons); - createRelAxes(numRelAxes); - createAbsAxes(numAbsAxes); - createHats(); - - /*ArrayList tempAxes = new ArrayList(); - for(int i=0;i<numButtons;i++) { - Axis tempAxis = buttons[i]; - if(tempAxis!=null) { - tempAxes.add(tempAxis); - } - } - for(int i=0;i<numRelAxes;i++) { - Axis tempAxis = relAxes[i]; - if(tempAxis!=null) { - tempAxes.add(tempAxis); - } - } - for(int i=0;i<numAbsAxes;i++) { - Axis tempAxis = absAxes[i]; - if(tempAxis!=null) { - tempAxes.add(tempAxis); - } - } - - axes = (Axis[]) tempAxes.toArray(axes);*/ - for(int i=0;i<numAbsAxes;i++) { - if(absAxes[i]!=null) { - axesArray.add(absAxes[i]); - } - } - for(int i=0;i<numRelAxes;i++) { - if(relAxes[i]!=null) { - axesArray.add(relAxes[i]); - } - } - for(int i=0;i<numHats;i++) { - if(hats[i]!=null) { - axesArray.add(hats[i]); - } - } - for(int i=0;i<numButtons;i++) { - if(buttons[i]!=null) { - axesArray.add(buttons[i]); - } - } - components = (Component[]) axesArray.toArray(components); - - guessType(); - - if(getFFEnabled()) { - System.out.println("Java code thinks FF is enabled for device " + name); - Rumbler[] tempRumblers = rumblers; - rumblers = new Rumbler[rumblers.length+1]; - System.arraycopy(tempRumblers,0,rumblers,0,tempRumblers.length); - rumblers[rumblers.length-1] = new LinuxDeviceRumbler(nativeID); - System.out.println("rumblers.length: " + rumblers.length); - System.out.println("getRumblers().length: " + getRumblers().length); - } else { - System.out.println("Java code thinks FF is disabled for device " + name); - } - } - - /*public Axis[] getAxes(){ - Axis retval[] = new Axis[0]; - retval = (Axis []) axesArray.toArray(retval); - return retval; - }*/ - - /** - * Returns the port type that this device is connected to. - * @return The port type - */ - public PortType getPortType() { - return portType; - } - - /** - * Returns the type of the Controller. - * @return The controller type. - */ - public Type getType() { - return typeGuess; - } - - /** Create the buttons for the device - * @param numButtons The number of buttons the device has - */ - private void createButtons(int numButtons) { - - int supportedButtons[] = new int[numButtons]; - buttons = new LinuxAxis[numButtons]; - if(numButtons>0) { - getSupportedButtons(supportedButtons); - for(int i=0;i<numButtons;i++) { - buttons[i] = createButton(i, supportedButtons[i]); - //axesArray.add(buttons[i]); - } - } - } - - /** Create the relative axes for the device - * @param numRelAxes The number of relative axes the device has - */ - private void createRelAxes(int numRelAxes) { - int supportedRelAxes[] = new int[numRelAxes]; - getSupportedRelAxes(supportedRelAxes); - relAxes = new LinuxAxis[numRelAxes]; - for(int i=0;i<numRelAxes;i++) { - relAxes[i] = createRelAxis(i, supportedRelAxes[i]); - //axesArray.add(relAxes[i]); - } - } - - /** Create the absolute axes for the device - * @param numAbsAxes The number of absolute axes the device has - */ - private void createAbsAxes(int numAbsAxes) { - int supportedAbsAxes[] = new int[numAbsAxes]; - getSupportedAbsAxes(supportedAbsAxes); - absAxes = new LinuxAxis[numAbsAxes]; - for(int i=0;i<numAbsAxes;i++) { - // Nasy code here - // Hats underlinux are 2 axis, combine them - if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT0X) { - hatAxisIDs[0] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT0Y) { - hatAxisIDs[1] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT1X) { - hatAxisIDs[2] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT1Y) { - hatAxisIDs[3] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT2X) { - hatAxisIDs[4] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT2Y) { - hatAxisIDs[5] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT3X) { - hatAxisIDs[6] = i; - } else if(supportedAbsAxes[i] == NativeDefinitions.ABS_HAT3Y) { - hatAxisIDs[7] = i; - } else { - absAxes[i] = createAbsAxis(i, supportedAbsAxes[i]); - //axesArray.add(absAxes[i]); - } - } - - } - - /** Create the coolie hats for the device - */ - private void createHats() { - LinuxHat tempHats[] = new LinuxHat[4]; - for(int i=0;i<4;i++) { - int x = i*2; - int y= x+1; - //Check we have at least one hat axis (can hats have just one axis? - if((hatAxisIDs[x]!=-1) || (hatAxisIDs[y]!=-1)) { - String hatName = "Hat " + i; - tempHats[numHats] = createHat(hatName, hatAxisIDs[x], hatAxisIDs[y]); - numHats++; - } - } - hats = new LinuxHat[numHats]; - for(int i=0;i<numHats;i++) { - hats[i] = tempHats[i]; - //axesArray.add(hats[i]); - } - } - - /** Take a guess at the device type. - */ - private void guessType() { - int joystickCharacteristic=0; - int digitiserCharacteristic=0; - int gamepadCharacteristic=0; - int miscCharacteristic=0; - int mouseCharacteristic=0; - - int supportedButtons[] = new int[numButtons]; - getSupportedButtons(supportedButtons); - - for(int i=0;i<numButtons;i++) { - switch (supportedButtons[i]) { - case NativeDefinitions.BTN_TRIGGER : - case NativeDefinitions.BTN_THUMB : - case NativeDefinitions.BTN_THUMB2 : - case NativeDefinitions.BTN_TOP : - case NativeDefinitions.BTN_TOP2 : - case NativeDefinitions.BTN_PINKIE : - case NativeDefinitions.BTN_BASE : - case NativeDefinitions.BTN_BASE2 : - case NativeDefinitions.BTN_BASE3 : - case NativeDefinitions.BTN_BASE4 : - case NativeDefinitions.BTN_BASE5 : - case NativeDefinitions.BTN_BASE6 : - case NativeDefinitions.BTN_DEAD : - joystickCharacteristic++; - break; - case NativeDefinitions.BTN_A : - case NativeDefinitions.BTN_B : - case NativeDefinitions.BTN_C : - case NativeDefinitions.BTN_X : - case NativeDefinitions.BTN_Y : - case NativeDefinitions.BTN_Z : - case NativeDefinitions.BTN_TL : - case NativeDefinitions.BTN_TR : - case NativeDefinitions.BTN_TL2 : - case NativeDefinitions.BTN_TR2 : - case NativeDefinitions.BTN_SELECT : - case NativeDefinitions.BTN_MODE : - case NativeDefinitions.BTN_THUMBL : - case NativeDefinitions.BTN_THUMBR : - gamepadCharacteristic++; - break; - case NativeDefinitions.BTN_0 : - case NativeDefinitions.BTN_1 : - case NativeDefinitions.BTN_2 : - case NativeDefinitions.BTN_3 : - case NativeDefinitions.BTN_4 : - case NativeDefinitions.BTN_5 : - case NativeDefinitions.BTN_6 : - case NativeDefinitions.BTN_7 : - case NativeDefinitions.BTN_8 : - case NativeDefinitions.BTN_9 : - miscCharacteristic++; - break; - case NativeDefinitions.BTN_LEFT : - case NativeDefinitions.BTN_RIGHT : - case NativeDefinitions.BTN_MIDDLE : - case NativeDefinitions.BTN_SIDE : - case NativeDefinitions.BTN_EXTRA : - case NativeDefinitions.BTN_FORWARD : - case NativeDefinitions.BTN_BACK : - mouseCharacteristic++; - break; - case NativeDefinitions.BTN_TOOL_PEN : - case NativeDefinitions.BTN_TOOL_RUBBER : - case NativeDefinitions.BTN_TOOL_BRUSH : - case NativeDefinitions.BTN_TOOL_PENCIL : - case NativeDefinitions.BTN_TOOL_AIRBRUSH : - case NativeDefinitions.BTN_TOOL_FINGER : - case NativeDefinitions.BTN_TOOL_MOUSE : - case NativeDefinitions.BTN_TOOL_LENS : - case NativeDefinitions.BTN_TOUCH : - case NativeDefinitions.BTN_STYLUS : - case NativeDefinitions.BTN_STYLUS2 : - digitiserCharacteristic++; - break; - default: - // no sweat, it's non of the above, erg - } - } - if((joystickCharacteristic > 0) && - (joystickCharacteristic >= digitiserCharacteristic) && - (joystickCharacteristic >= gamepadCharacteristic) && - (joystickCharacteristic >= miscCharacteristic) && - (joystickCharacteristic >= mouseCharacteristic)) { - typeGuess = Type.STICK; - } else if((gamepadCharacteristic > 0) && - (gamepadCharacteristic >= digitiserCharacteristic) && - (gamepadCharacteristic >= joystickCharacteristic) && - (gamepadCharacteristic >= miscCharacteristic) && - (gamepadCharacteristic >= mouseCharacteristic)) { - typeGuess = Type.GAMEPAD; - } else if((digitiserCharacteristic > 0) && - (digitiserCharacteristic >= gamepadCharacteristic) && - (digitiserCharacteristic >= joystickCharacteristic) && - (digitiserCharacteristic >= miscCharacteristic) && - (digitiserCharacteristic >= mouseCharacteristic)) { - typeGuess = Type.TRACKPAD; - } else if((miscCharacteristic > 0) && - (miscCharacteristic >= gamepadCharacteristic) && - (miscCharacteristic >= joystickCharacteristic) && - (miscCharacteristic >= miscCharacteristic) && - (miscCharacteristic >= mouseCharacteristic)) { - // I'm not sure what one of these would be, but it has axis other - // wise a LinuxKeyboard would have been constructed, so assume its - // some kind of stick; - typeGuess = Type.STICK; - } else if((mouseCharacteristic > 0) && - (mouseCharacteristic >= digitiserCharacteristic) && - (mouseCharacteristic >= joystickCharacteristic) && - (mouseCharacteristic >= miscCharacteristic) && - (mouseCharacteristic >= gamepadCharacteristic)) { - // We shouldn't ever get here, as a mouse should have constructed - // a LinuxMouse object, but you never know - typeGuess = Type.MOUSE; - } - if(typeGuess == Type.STICK) { - String tempName = getName().toLowerCase(); - if((tempName.indexOf("gamepad") > -1) || (tempName.indexOf("game pad") > -1)) { - typeGuess = Type.GAMEPAD; - } - } - } - - /** Create an button for the device - * @param buttonNumber The button number - * @param nativeButtonType The type of button - * @return The new button - */ - private LinuxAxis createButton(int buttonNumber, int nativeButtonType) { - Component.Identifier id = LinuxNativeTypesMap.getButtonID(nativeButtonType); - String name = LinuxNativeTypesMap.getButtonName(nativeButtonType); - if(name == null) { - name = "Uknown button"; - id = Component.Identifier.Button.UNKNOWN; - } - - return new LinuxAxis(this, buttonNumber, name, id, 0, false, true, false); - } - - /** Create a relative axis for the device - * @param axisNumber The native axis id - * @param nativeType The native type - * @return The new axis - */ - private LinuxAxis createRelAxis(int axisNumber, int nativeType) { - Component.Identifier id = LinuxNativeTypesMap.getRelAxisID(nativeType); - String name = LinuxNativeTypesMap.getRelAxisName(nativeType); - - // This is done to be like the windows version - // return new LinuxAxis(this, axisNumber, name, id, 0, true, true, 0, 0); - - // this is what should be done - return new LinuxAxis(this, axisNumber, name, id, 0, true, false, true); - } - - /** Create an absolute axis for the device - * @param axisNumber The native axis number - * @param nativeType The native tpye - * @return The new axis - */ - private LinuxAxis createAbsAxis(int axisNumber, int nativeType) { - Component.Identifier id = LinuxNativeTypesMap.getAbsAxisID(nativeType); - String name = LinuxNativeTypesMap.getAbsAxisName(nativeType); - - // Work around for a kernel level (I think) bug that incorrectly reports - // the third axis as a rudder not a throttle on analog (gameport) 3 axis - // 4 button sticks - if((getName().equals("Analog 3-axis 4-button joystick")) && (portType == Controller.PortType.GAME)) { - if((id == Component.Identifier.Axis.RZ) && (name.equals("Rudder"))) { - id = Component.Identifier.Axis.SLIDER; - name = "Throttle"; - } - } - - return new LinuxAxis(this, axisNumber, name, id, getAbsAxisFuzz(axisNumber), true, false, getAbsAxisMinimum(axisNumber), getAbsAxisMaximum(axisNumber)); - //return new LinuxAxis(this, axisNumber, name, id, getAbsAxisFuzz(axisNumber), true, false, false); - } - - /** Create a hat for the device - * @param name The name of the hat to create - * @param xAxisID The axis that is the hats X axis - * @param yAxisID The axis that is the hats Y axis - * @return The new hat - */ - private LinuxHat createHat(String name, int xAxisID, int yAxisID) { - return new LinuxHat(this, name, xAxisID, yAxisID); - } - - /** Polls axes for data. Returns false if the controller is no longer valid. - * Polling reflects the current state of the device when polled. - * @return false if the controller is no longer valid. - */ - public boolean poll() { - int retval = JInputLibrary.safePoll(nativeID, buttonData, relAxesData, absAxesData); - if(retval>=0) return true; - return false; - } - - /** - * Retursn the value of a particular button or key - * @param buttonID The button/key to check - * @return The value fo the button/key - */ - public float getButtonValue(int buttonID) { - if(buttonData[buttonID]>0) return 1.0f; - return 0.0f; - } - - /** - * Returns the value of a particular absolute axis - * @param axisID The axis id - * @return The axis value - */ - public float getAbsAxisValue(int axisID) { - return (float) absAxesData[axisID]; - } - - /** - * Returns the value of the requested relative axis. - * @param axisID The native axis ID. - * @return The value of the axis - */ - public float getRelAxisValue(int axisID) { - return (float) relAxesData[axisID]; - } - - /** - * Gets the axis fuzz, used for nullzone information - * @param axisID The axis to get the fuzz for - * @return The axis fuzz. - */ - public float getAbsAxisFuzz(int axisID) { - return (float) JInputLibrary.getAbsAxisFuzz(nativeID, axisID); - } - - /** - * Returns the maximum value for the requested axis - * @param axisID The native ID of the axis to check - * @return The maximum value - */ - public float getAbsAxisMaximum(int axisID) { - return (float) JInputLibrary.getAbsAxisMaximum(nativeID, axisID); - } - - /** - * The minimum value the requested axis can have - * @param axisID The native axis ID - * @return The minimum axis value - */ - public float getAbsAxisMinimum(int axisID) { - return (float) JInputLibrary.getAbsAxisMinimum(nativeID, axisID); - } - - /** Return the enumeration of supported button types for this device - * @param supportedButtons Array to populate - */ - private void getSupportedButtons(int supportedButtons[]) { - if(supportedButtons.length==0) { - return; - } - JInputLibrary.getSupportedButtons(nativeID, supportedButtons); - } - - /** Return the enumeration of supported absolute axis types for this device - * @param suportedAbsAxes The array to populate - */ - private void getSupportedAbsAxes(int suportedAbsAxes[]) { - JInputLibrary.getSupportedAbsAxes(nativeID, suportedAbsAxes); - } - - /** Return the enumeration of supported relative axis types for this device - * @param supportedRelAxes The array to populate - */ - private void getSupportedRelAxes(int supportedRelAxes[]) { - JInputLibrary.getSupportedRelAxes(nativeID, supportedRelAxes); - } - - /** Returns the status of FF support for this device - * - */ - private boolean getFFEnabled() { - return JInputLibrary.getFFEnabled(nativeID); - } - - /** - * A device that represents a joystick coolie hat. - * @author Jeremy Booth ([email protected]) - */ - public static class LinuxHat extends AbstractComponent { - - /** The parent controller - */ - private LinuxDevice controller; - - /** The xAxis for this hat - */ - private int xAxisID; - - /** The y axis for this hat - */ - private int yAxisID; - - /** The last polled value of this hat - */ - private float value; - - /** - * Creates a new instance of LinuxHat, coolie hats under linux are reported as - * two independant axis, this class is responsible for combining the axis values - * and returning a value appropriate for a coolie hat. - * @param controller The parent controller - * @param name The name of this hat - * @param xAxisID The X axis native axis ID - * @param yAxisID The Y axis native axis ID - */ - public LinuxHat(LinuxDevice controller, String name, int xAxisID, int yAxisID) { - super(name, Component.Identifier.Axis.POV); - - System.out.println("Creating a Hat for device " + controller.getName() + " named " + name + " from axis " + xAxisID + " and " + yAxisID); - - this.controller = controller; - this.xAxisID = xAxisID; - this.yAxisID = yAxisID; - - //System.err.println("New hat: " + name + " created"); - //System.err.flush(); - } - - /** Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - * @return Returns <code>true</code> if data returned from <code>poll</code> - * is relative to the last call, or <code>false</code> if data - * is absolute. - */ - public boolean isRelative() { - return false; - } - - /** Returns true if this axis is analog - * @return Always retursn true as coolie hats are analog under linux - */ - public boolean isAnalog() { - return false; - } - - /** - * Retursn true if this axis is normalised - * @return Always returns true as linux hats are normalised - */ - public boolean isNormalised() { - return true; - } - - /** - * Returns the current value of this axis - * @return The current axis value - */ - public float getPollData() { - //System.err.println("getPollData called, isPolling: " + isPolling()); - //System.err.flush(); - if(isPolling()) { updateData(); }; - return value; - } - - /** Gets the data fro mthe native level and combines it to the hats value - */ - private void updateData() { - //System.err.println("updateData called"); - //System.err.flush(); - int newXAxisValue = (int)controller.getAbsAxisValue(xAxisID); - int newYAxisValue = (int)controller.getAbsAxisValue(yAxisID); - - //System.err.println("newXAxisValue: " + newXAxisValue + " newYAxisValue: " + newYAxisValue); - - if((newXAxisValue == 0) && (newYAxisValue == 0)) { - value = POV.OFF; - } else if((newXAxisValue > 0) && (newYAxisValue < 0)) { - value = POV.UP_RIGHT; - } else if((newXAxisValue > 0) && (newYAxisValue == 0)) { - value = POV.RIGHT; - } else if((newXAxisValue > 0) && (newYAxisValue > 0)) { - value = POV.DOWN_RIGHT; - } else if((newXAxisValue == 0) && (newYAxisValue > 0)) { - value = POV.DOWN; - } else if((newXAxisValue < 0) && (newYAxisValue > 0)) { - value = POV.DOWN_LEFT; - } else if((newXAxisValue < 0) && (newYAxisValue == 0)) { - value = POV.LEFT; - } else if((newXAxisValue < 0) && (newYAxisValue < 0)) { - value = POV.UP_LEFT; - } else if((newXAxisValue == 0) && (newYAxisValue < 0)) { - value = POV.UP; - } - - //System.err.println("new value: " + value); - //System.err.flush(); - } - - } - +interface LinuxDevice { + void close() throws IOException; } diff --git a/plugins/linux/src/java/net/java/games/input/LinuxDeviceRumbler.java b/plugins/linux/src/java/net/java/games/input/LinuxDeviceRumbler.java deleted file mode 100644 index df8dd84..0000000 --- a/plugins/linux/src/java/net/java/games/input/LinuxDeviceRumbler.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.java.games.input; - -import net.java.games.input.Component.Identifier; - -public class LinuxDeviceRumbler implements Rumbler { - - private int deviceID; - - public LinuxDeviceRumbler(int deviceID) { - this.deviceID = deviceID; - } - - public void rumble(float intensity) { - // TODO Auto-generated method stub - JInputLibrary.rumble(deviceID, intensity); - } - - public String getAxisName() { - // TODO Auto-generated method stub - return null; - } - - public Identifier getAxisIdentifier() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxEnvironmentPlugin.java b/plugins/linux/src/java/net/java/games/input/LinuxEnvironmentPlugin.java index 8883691..628ee04 100644 --- a/plugins/linux/src/java/net/java/games/input/LinuxEnvironmentPlugin.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxEnvironmentPlugin.java @@ -26,27 +26,42 @@ package net.java.games.input; import net.java.games.util.plugins.Plugin; +import java.util.List; +import java.util.ArrayList; +import java.io.IOException; +import java.io.File; +import java.io.FilenameFilter; +import java.security.AccessController; +import java.security.PrivilegedAction; /** Environment plugin for linux + * @author elias * @author Jeremy Booth ([email protected]) */ -public class LinuxEnvironmentPlugin extends ControllerEnvironment implements Plugin { +public final class LinuxEnvironmentPlugin extends ControllerEnvironment implements Plugin { + private final Controller[] controllers; + private final List devices = new ArrayList(); - /** List of controllers - */ - private Controller[] controllers; - - /** Creates a new instance of LinuxEnvironmentPlugin */ + static { + AccessController.doPrivileged( + new PrivilegedAction() { + public final Object run() { + System.loadLibrary("jinput-linux"); + return null; + } + }); + } + public LinuxEnvironmentPlugin() { - if(JInputLibrary.isSupported()) { - LinuxNativeTypesMap.init(); - JInputLibrary.init(); - createControllers(); - } else { - controllers = new Controller[0]; - } - + this.controllers = enumerateControllers(); System.out.println("Linux plugin claims to have found " + controllers.length + " controllers"); + AccessController.doPrivileged( + new PrivilegedAction() { + public final Object run() { + Runtime.getRuntime().addShutdownHook(new ShutdownHook()); + return null; + } + }); } /** Returns a list of all controllers available to this environment, @@ -54,91 +69,283 @@ public class LinuxEnvironmentPlugin extends ControllerEnvironment implements Plu * @return Returns a list of all controllers available to this environment, * or an empty array if there are no controllers in this environment. */ - public Controller[] getControllers() { + public final Controller[] getControllers() { return controllers; } - /** Create the controllers - */ - private void createControllers() { - int numDevices = JInputLibrary.getNumberOfDevices(); - - Controller[] tempControllers = new Controller[numDevices]; - - int numRealDevices = 0; - Controller tempController; - for(int i=0;i<numDevices;i++) { - tempController = createDevice(i); - if(tempController!=null) { - if(tempController.getComponents().length>0 || tempController.getControllers().length>0) { - tempControllers[numRealDevices] = tempController; - numRealDevices++; - } - } - } - - controllers = new Controller[numRealDevices]; - - for(int i=0;i<numRealDevices;i++) { - controllers[i] = tempControllers[i]; - } - } - - /** Create a particular device - * @param deviceNumber The device ID - * @return The new device - */ - private Controller createDevice(int deviceNumber) { - String name = JInputLibrary.getDeviceName(deviceNumber); - int numAbsAxes = JInputLibrary.getNumAbsAxes(deviceNumber); - int numRelAxes = JInputLibrary.getNumRelAxes(deviceNumber); - int numButtons = JInputLibrary.getNumButtons(deviceNumber); - Controller device = null; - - System.out.println("Java working on device " + name); - - int mouseCharacteristic = 0; - int keyboardCharacteristic = 0; - int joystickCharacteristic = 0; - - // we are going to try and guess what type of controller it is now - if(name.toLowerCase().indexOf("mouse")>=0) { - mouseCharacteristic++; - } - if(name.toLowerCase().indexOf("keyboard")>=0) { - keyboardCharacteristic++; - } - if(name.toLowerCase().indexOf("joystick")>=0) { - joystickCharacteristic++; - } - - if(numRelAxes>=2) { - mouseCharacteristic++; - } else { - mouseCharacteristic--; - } - if(numAbsAxes>=2) { - joystickCharacteristic++; - } else { - joystickCharacteristic--; - } - if(numButtons>64) { - keyboardCharacteristic++; - } else { - keyboardCharacteristic--; - } - - if((mouseCharacteristic > keyboardCharacteristic) && (mouseCharacteristic > joystickCharacteristic)) { - device = new LinuxMouse(new LinuxDevice(deviceNumber, name, numButtons, numRelAxes, numAbsAxes)); - } else if((keyboardCharacteristic > mouseCharacteristic) && (keyboardCharacteristic > joystickCharacteristic)) { - device = new LinuxDevice(deviceNumber, name, numButtons, numRelAxes, numAbsAxes, Controller.Type.KEYBOARD); - } else if((joystickCharacteristic > keyboardCharacteristic) && (joystickCharacteristic > mouseCharacteristic)) { - device = new LinuxDevice(deviceNumber, name, numButtons, numRelAxes, numAbsAxes); - } else { - //Dunno what this is, but try it anyway - device = new LinuxDevice(deviceNumber, name, numButtons, numRelAxes, numAbsAxes); - } - return device; + private final static Component[] createComponents(List event_components, LinuxEventDevice device) { + LinuxEventComponent[][] povs = new LinuxEventComponent[4][2]; + List components = new ArrayList(); + for (int i = 0; i < event_components.size(); i++) { + LinuxEventComponent event_component = (LinuxEventComponent)event_components.get(i); + Component.Identifier identifier = event_component.getIdentifier(); + + if (identifier == Component.Identifier.Axis.POV) { + int native_code = event_component.getDescriptor().getCode(); + switch (native_code) { + case NativeDefinitions.ABS_HAT0X: + povs[0][0] = event_component; + break; + case NativeDefinitions.ABS_HAT0Y: + povs[0][1] = event_component; + break; + case NativeDefinitions.ABS_HAT1X: + povs[1][0] = event_component; + break; + case NativeDefinitions.ABS_HAT1Y: + povs[1][1] = event_component; + break; + case NativeDefinitions.ABS_HAT2X: + povs[2][0] = event_component; + break; + case NativeDefinitions.ABS_HAT2Y: + povs[2][1] = event_component; + break; + case NativeDefinitions.ABS_HAT3X: + povs[3][0] = event_component; + break; + case NativeDefinitions.ABS_HAT3Y: + povs[3][1] = event_component; + break; + default: + ControllerEnvironment.logln("Unknown POV instance: " + native_code); + break; + } + } else if (identifier != null) { + LinuxComponent component = new LinuxComponent(event_component); + components.add(component); + device.registerComponent(event_component.getDescriptor(), component); + } + } + for (int i = 0; i < povs.length; i++) { + LinuxEventComponent x = povs[i][0]; + LinuxEventComponent y = povs[i][1]; + if (x != null && y != null) { + LinuxComponent controller_component = new LinuxPOV(x, y); + components.add(controller_component); + device.registerComponent(x.getDescriptor(), controller_component); + device.registerComponent(y.getDescriptor(), controller_component); + } + } + Component[] components_array = new Component[components.size()]; + components.toArray(components_array); + return components_array; + } + + private final static Mouse createMouseFromDevice(LinuxEventDevice device, Component[] components) throws IOException { + Mouse mouse = new LinuxMouse(device, components, new Controller[]{}, device.getRumblers()); + if (mouse.getX() != null && mouse.getY() != null && mouse.getLeft() != null) + return mouse; + else + return null; + } + + private final static Keyboard createKeyboardFromDevice(LinuxEventDevice device, Component[] components) throws IOException { + Keyboard keyboard = new LinuxKeyboard(device, components, new Controller[]{}, device.getRumblers()); + return keyboard; + } + + private final static Controller createJoystickFromDevice(LinuxEventDevice device, Component[] components, Controller.Type type) throws IOException { + Controller joystick = new LinuxAbstractController(device, components, new Controller[]{}, device.getRumblers(), type); + return joystick; + } + + private final static Controller createControllerFromDevice(LinuxEventDevice device) throws IOException { + List event_components = device.getComponents(); + Component[] components = createComponents(event_components, device); + Controller.Type type = device.getType(); + + if (type == Controller.Type.MOUSE) { + return createMouseFromDevice(device, components); + } else if (type == Controller.Type.KEYBOARD) { + return createKeyboardFromDevice(device, components); + } else if (type == Controller.Type.STICK || type == Controller.Type.GAMEPAD) { + return createJoystickFromDevice(device, components, type); + } else + return null; + } + + private final Controller[] enumerateControllers() { + List controllers = new ArrayList(); + enumerateEventControllers(controllers); + if (controllers.size() == 0) { + /* Some linux distros, even modern ones, can't figure out + * how to give event devices proper access rights, so we'll have + * to fallback to the legacy joystick interface. + */ + enumerateJoystickControllers(controllers); + } + Controller[] controllers_array = new Controller[controllers.size()]; + controllers.toArray(controllers_array); + return controllers_array; + } + + private final static Component.Identifier.Button getButtonIdentifier(int index) { + switch (index) { + case 0: + return Component.Identifier.Button._0; + case 1: + return Component.Identifier.Button._1; + case 2: + return Component.Identifier.Button._2; + case 3: + return Component.Identifier.Button._3; + case 4: + return Component.Identifier.Button._4; + case 5: + return Component.Identifier.Button._5; + case 6: + return Component.Identifier.Button._6; + case 7: + return Component.Identifier.Button._7; + case 8: + return Component.Identifier.Button._8; + case 9: + return Component.Identifier.Button._9; + case 10: + return Component.Identifier.Button._10; + case 11: + return Component.Identifier.Button._11; + case 12: + return Component.Identifier.Button._12; + case 13: + return Component.Identifier.Button._13; + case 14: + return Component.Identifier.Button._14; + case 15: + return Component.Identifier.Button._15; + case 16: + return Component.Identifier.Button._16; + case 17: + return Component.Identifier.Button._17; + case 18: + return Component.Identifier.Button._18; + case 19: + return Component.Identifier.Button._19; + case 20: + return Component.Identifier.Button._20; + case 21: + return Component.Identifier.Button._21; + case 22: + return Component.Identifier.Button._22; + case 23: + return Component.Identifier.Button._23; + case 24: + return Component.Identifier.Button._24; + case 25: + return Component.Identifier.Button._25; + case 26: + return Component.Identifier.Button._26; + case 27: + return Component.Identifier.Button._27; + case 28: + return Component.Identifier.Button._28; + case 29: + return Component.Identifier.Button._29; + case 30: + return Component.Identifier.Button._30; + case 31: + return Component.Identifier.Button._31; + default: + return null; + } + } + + private final static Controller createJoystickFromJoystickDevice(LinuxJoystickDevice device) { + List components = new ArrayList(); + for (int i = 0; i < device.getNumButtons(); i++) { + Component.Identifier.Button button_id = getButtonIdentifier(i); + if (button_id != null) { + LinuxJoystickButton button = new LinuxJoystickButton(button_id); + device.registerButton(i, button); + components.add(button); + } + } + for (int i = 0; i < device.getNumAxes(); i++) { + Component.Identifier.Axis axis_id; + if ((i % 2) == 0) + axis_id = Component.Identifier.Axis.X; + else + axis_id = Component.Identifier.Axis.Y; + LinuxJoystickAxis axis = new LinuxJoystickAxis(axis_id); + device.registerAxis(i, axis); + components.add(axis); + } + return new LinuxJoystickAbstractController(device, (Component[])components.toArray(new Component[]{}), new Controller[]{}, new Rumbler[]{}); + } + + private final void enumerateJoystickControllers(List controllers) { + File[] joystick_device_files = enumerateJoystickDeviceFiles("/dev/input"); + if (joystick_device_files == null || joystick_device_files.length == 0) { + joystick_device_files = enumerateJoystickDeviceFiles("/dev"); + if (joystick_device_files == null) + return; + } + for (int i = 0; i < joystick_device_files.length; i++) { + File event_file = joystick_device_files[i]; + try { + LinuxJoystickDevice device = new LinuxJoystickDevice(event_file.getAbsolutePath()); + Controller controller = createJoystickFromJoystickDevice(device); + if (controller != null) { + controllers.add(controller); + devices.add(device); + } else + device.close(); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to open device (" + event_file + "): " + e.getMessage()); + } + } + } + + private final static File[] enumerateJoystickDeviceFiles(String dev_path) { + File dev = new File(dev_path); + return dev.listFiles(new FilenameFilter() { + public final boolean accept(File dir, String name) { + return name.startsWith("js"); + } + }); + } + + private final void enumerateEventControllers(List controllers) { + File dev = new File("/dev/input"); + File[] event_device_files = dev.listFiles(new FilenameFilter() { + public final boolean accept(File dir, String name) { + return name.startsWith("event"); + } + }); + if (event_device_files == null) + return; + for (int i = 0; i < event_device_files.length; i++) { + File event_file = event_device_files[i]; + try { + LinuxEventDevice device = new LinuxEventDevice(event_file.getAbsolutePath()); + try { + Controller controller = createControllerFromDevice(device); + if (controller != null) { + controllers.add(controller); + devices.add(device); + } else + device.close(); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to create Controller: " + e.getMessage()); + device.close(); + } + } catch (IOException e) { + ControllerEnvironment.logln("Failed to open device (" + event_file + "): " + e.getMessage()); + } + } } - + + private final class ShutdownHook extends Thread { + public final void run() { + for (int i = 0; i < devices.size(); i++) { + try { + LinuxDevice device = (LinuxDevice)devices.get(i); + device.close(); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to close device: " + e.getMessage()); + } + } + } + } } diff --git a/plugins/linux/src/java/net/java/games/input/LinuxEvent.java b/plugins/linux/src/java/net/java/games/input/LinuxEvent.java new file mode 100644 index 0000000..de2959c --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxEvent.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +/** + * @author elias + */ +final class LinuxEvent { + private long nanos; + private final LinuxAxisDescriptor descriptor = new LinuxAxisDescriptor(); + private int value; + + public final void set(long seconds, long microseconds, int type, int code, int value) { + this.nanos = (seconds*1000000 + microseconds)*1000; + this.descriptor.set(type, code); + this.value = value; + } + + public final int getValue() { + return value; + } + + public final LinuxAxisDescriptor getDescriptor() { + return descriptor; + } + + public final long getNanos() { + return nanos; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxEventComponent.java b/plugins/linux/src/java/net/java/games/input/LinuxEventComponent.java new file mode 100644 index 0000000..b2ad562 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxEventComponent.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +import java.io.IOException; + +/** + * @author elias + * @author Jeremy Booth ([email protected]) + */ +final class LinuxEventComponent { + private final LinuxEventDevice device; + private final Component.Identifier identifier; + private final Controller.Type button_trait; + private final boolean is_relative; + private final LinuxAxisDescriptor descriptor; + private final int min; + private final int max; + private final int flat; + + + public LinuxEventComponent(LinuxEventDevice device, Component.Identifier identifier, boolean is_relative, int native_type, int native_code) throws IOException { + this.device = device; + this.identifier = identifier; + if (native_type == NativeDefinitions.EV_KEY) + this.button_trait = LinuxNativeTypesMap.guessButtonTrait(native_code); + else + this.button_trait = Controller.Type.UNKNOWN; + this.is_relative = is_relative; + this.descriptor = new LinuxAxisDescriptor(); + descriptor.set(native_type, native_code); + if (native_type == NativeDefinitions.EV_ABS) { + LinuxAbsInfo abs_info = new LinuxAbsInfo(); + getAbsInfo(abs_info); + this.min = abs_info.getMin(); + this.max = abs_info.getMax(); + this.flat = abs_info.getFlat(); + } else { + this.min = Integer.MIN_VALUE; + this.max = Integer.MAX_VALUE; + this.flat = 0; + } + } + + public final LinuxEventDevice getDevice() { + return device; + } + + public final void getAbsInfo(LinuxAbsInfo abs_info) throws IOException { + assert descriptor.getType() == NativeDefinitions.EV_ABS; + device.getAbsInfo(descriptor.getCode(), abs_info); + } + + public final Controller.Type getButtonTrait() { + return button_trait; + } + + public final Component.Identifier getIdentifier() { + return identifier; + } + + public final LinuxAxisDescriptor getDescriptor() { + return descriptor; + } + + public final boolean isRelative() { + return is_relative; + } + + public final boolean isAnalog() { + return identifier instanceof Component.Identifier.Axis && identifier != Component.Identifier.Axis.POV; + } + + final float convertValue(float value) { + if (identifier instanceof Component.Identifier.Axis && !is_relative) { + // Some axes have min = max = 0 + if (min == max) + return 0; + if (value > max) + value = max; + else if (value < min) + value = min; + return 2*(value - min)/(max - min) - 1; + } else { + return value; + } + } + + final float getDeadZone() { + return flat/(2f*(max - min)); + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxEventDevice.java b/plugins/linux/src/java/net/java/games/input/LinuxEventDevice.java new file mode 100644 index 0000000..f17e05d --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxEventDevice.java @@ -0,0 +1,397 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +import java.io.IOException; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + +/** + * @author elias + */ +final class LinuxEventDevice implements LinuxDevice { + private final Map component_map = new HashMap(); + private final Rumbler[] rumblers; + private final long fd; + private final String name; + private final LinuxInputID input_id; + private final List components; + private final Controller.Type type; + + /* Closed state variable that protects the validity of the file descriptor. + * Access to the closed state must be synchronized + */ + private boolean closed; + + /* Access the the key_states array could be synchronized, but + * it doesn't hurt to have multiple threads read/write from/to it + */ + private final byte[] key_states = new byte[NativeDefinitions.KEY_MAX/8 + 1]; + + public LinuxEventDevice(String filename) throws IOException { + long fd; + try { + fd = nOpen(filename, true); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to open device R/W: " + e.getMessage()); + fd = nOpen(filename, false); + } + this.fd = fd; + try { + this.name = getDeviceName(); + this.input_id = getDeviceInputID(); + this.components = getDeviceComponents(); + this.rumblers = enumerateRumblers(); + this.type = guessType(); + } catch (IOException e) { + close(); + throw e; + } + } + private final static native long nOpen(String filename, boolean rw) throws IOException; + + public final Controller.Type getType() { + return type; + } + + private final static int countComponents(List components, Class id_type, boolean relative) { + int count = 0; + for (int i = 0; i < components.size(); i++) { + LinuxEventComponent component = (LinuxEventComponent)components.get(i); + if (id_type.isInstance(component.getIdentifier()) && relative == component.isRelative()) + count++; + } + return count; + } + + private final Controller.Type guessType() throws IOException { + Controller.Type type_from_usages = guessTypeFromUsages(); + if (type_from_usages == Controller.Type.UNKNOWN) + return guessTypeFromComponents(); + else + return type_from_usages; + } + + private final Controller.Type guessTypeFromUsages() throws IOException { + byte[] usage_bits = getDeviceUsageBits(); + if (isBitSet(usage_bits, NativeDefinitions.USAGE_MOUSE)) + return Controller.Type.MOUSE; + else if (isBitSet(usage_bits, NativeDefinitions.USAGE_KEYBOARD)) + return Controller.Type.KEYBOARD; + else if (isBitSet(usage_bits, NativeDefinitions.USAGE_GAMEPAD)) + return Controller.Type.GAMEPAD; + else if (isBitSet(usage_bits, NativeDefinitions.USAGE_JOYSTICK)) + return Controller.Type.STICK; + else + return Controller.Type.UNKNOWN; + } + + private final Controller.Type guessTypeFromComponents() throws IOException { + List components = getComponents(); + if (components.size() == 0) + return Controller.Type.UNKNOWN; + int num_rel_axes = countComponents(components, Component.Identifier.Axis.class, true); + int num_abs_axes = countComponents(components, Component.Identifier.Axis.class, false); + int num_keys = countComponents(components, Component.Identifier.Key.class, false); + int mouse_traits = 0; + int keyboard_traits = 0; + int joystick_traits = 0; + int gamepad_traits = 0; + if (name.toLowerCase().indexOf("mouse") != -1) + mouse_traits++; + if (name.toLowerCase().indexOf("keyboard") != -1) + keyboard_traits++; + if (name.toLowerCase().indexOf("joystick") != -1) + joystick_traits++; + if (name.toLowerCase().indexOf("gamepad") != -1) + gamepad_traits++; + int num_keyboard_button_traits = 0; + int num_mouse_button_traits = 0; + int num_joystick_button_traits = 0; + int num_gamepad_button_traits = 0; + // count button traits + for (int i = 0; i < components.size(); i++) { + LinuxEventComponent component = (LinuxEventComponent)components.get(i); + if (component.getButtonTrait() == Controller.Type.MOUSE) + num_mouse_button_traits++; + else if (component.getButtonTrait() == Controller.Type.KEYBOARD) + num_keyboard_button_traits++; + else if (component.getButtonTrait() == Controller.Type.GAMEPAD) + num_gamepad_button_traits++; + else if (component.getButtonTrait() == Controller.Type.STICK) + num_joystick_button_traits++; + } + if ((num_mouse_button_traits >= num_keyboard_button_traits) && (num_mouse_button_traits >= num_joystick_button_traits) && (num_mouse_button_traits >= num_gamepad_button_traits)) { + mouse_traits++; + } else if ((num_keyboard_button_traits >= num_mouse_button_traits) && (num_keyboard_button_traits >= num_joystick_button_traits) && (num_keyboard_button_traits >= num_gamepad_button_traits)) { + keyboard_traits++; + } else if ((num_joystick_button_traits >= num_keyboard_button_traits) && (num_joystick_button_traits >= num_mouse_button_traits) && (num_joystick_button_traits >= num_gamepad_button_traits)) { + joystick_traits++; + } else if ((num_gamepad_button_traits >= num_keyboard_button_traits) && (num_gamepad_button_traits >= num_mouse_button_traits) && (num_gamepad_button_traits >= num_joystick_button_traits)) { + gamepad_traits++; + } + if (num_rel_axes >= 2) { + mouse_traits++; + } + if (num_abs_axes >= 2) { + joystick_traits++; + gamepad_traits++; + } + + if ((mouse_traits >= keyboard_traits) && (mouse_traits >= joystick_traits) && (mouse_traits >= gamepad_traits)) { + return Controller.Type.MOUSE; + } else if ((keyboard_traits >= mouse_traits) && (keyboard_traits >= joystick_traits) && (keyboard_traits >= gamepad_traits)) { + return Controller.Type.KEYBOARD; + } else if ((joystick_traits >= mouse_traits) && (joystick_traits >= keyboard_traits) && (joystick_traits >= gamepad_traits)) { + return Controller.Type.STICK; + } else if ((gamepad_traits >= mouse_traits) && (gamepad_traits >= keyboard_traits) && (gamepad_traits >= joystick_traits)) { + return Controller.Type.GAMEPAD; + } else + return null; + } + + private final Rumbler[] enumerateRumblers() { + List rumblers = new ArrayList(); + try { + int num_effects = getNumEffects(); + if (num_effects <= 0) + return (Rumbler[])rumblers.toArray(new Rumbler[]{}); + byte[] ff_bits = getForceFeedbackBits(); + if (isBitSet(ff_bits, NativeDefinitions.FF_RUMBLE) && num_effects > rumblers.size()) { + rumblers.add(new LinuxRumbleFF(this)); + } + } catch (IOException e) { + ControllerEnvironment.logln("Failed to enumerate rumblers: " + e.getMessage()); + } + return (Rumbler[])rumblers.toArray(new Rumbler[]{}); + } + + public final Rumbler[] getRumblers() { + return rumblers; + } + + public final synchronized int uploadRumbleEffect(int id, int trigger_button, int direction, int trigger_interval, int replay_length, int replay_delay, int strong_magnitude, int weak_magnitude) throws IOException { + checkClosed(); + return nUploadRumbleEffect(fd, id, direction, trigger_button, trigger_interval, replay_length, replay_delay, strong_magnitude, weak_magnitude); + } + private final static native int nUploadRumbleEffect(long fd, int id, int direction, int trigger_button, int trigger_interval, int replay_length, int replay_delay, int strong_magnitude, int weak_magnitude) throws IOException; + + public final synchronized int uploadConstantEffect(int id, int trigger_button, int direction, int trigger_interval, int replay_length, int replay_delay, int constant_level, int constant_env_attack_length, int constant_env_attack_level, int constant_env_fade_length, int constant_env_fade_level) throws IOException { + checkClosed(); + return nUploadConstantEffect(fd, id, direction, trigger_button, trigger_interval, replay_length, replay_delay, constant_level, constant_env_attack_length, constant_env_attack_level, constant_env_fade_length, constant_env_fade_level); + } + private final static native int nUploadConstantEffect(long fd, int id, int direction, int trigger_button, int trigger_interval, int replay_length, int replay_delay, int constant_level, int constant_env_attack_length, int constant_env_attack_level, int constant_env_fade_length, int constant_env_fade_level) throws IOException; + + final void eraseEffect(int id) throws IOException { + nEraseEffect(fd, id); + } + private final static native void nEraseEffect(long fd, int ff_id) throws IOException; + + public final synchronized void writeEvent(int type, int code, int value) throws IOException { + checkClosed(); + nWriteEvent(fd, type, code, value); + } + private final static native void nWriteEvent(long fd, int type, int code, int value) throws IOException; + + public final void registerComponent(LinuxAxisDescriptor desc, LinuxComponent component) { + component_map.put(desc, component); + } + + public final LinuxComponent mapDescriptor(LinuxAxisDescriptor desc) { + return (LinuxComponent)component_map.get(desc); + } + + public final Controller.PortType getPortType() throws IOException { + return input_id.getPortType(); + } + + public final LinuxInputID getInputID() { + return input_id; + } + + private final LinuxInputID getDeviceInputID() throws IOException { + return nGetInputID(fd); + } + private final static native LinuxInputID nGetInputID(long fd) throws IOException; + + public final int getNumEffects() throws IOException { + return nGetNumEffects(fd); + } + private final static native int nGetNumEffects(long fd) throws IOException; + + private final int getVersion() throws IOException { + return nGetVersion(fd); + } + private final static native int nGetVersion(long fd) throws IOException; + + public final synchronized boolean getNextEvent(LinuxEvent linux_event) throws IOException { + checkClosed(); + return nGetNextEvent(fd, linux_event); + } + private final static native boolean nGetNextEvent(long fd, LinuxEvent linux_event) throws IOException; + + public final synchronized void getAbsInfo(int abs_axis, LinuxAbsInfo abs_info) throws IOException { + checkClosed(); + nGetAbsInfo(fd, abs_axis, abs_info); + } + private final static native void nGetAbsInfo(long fd, int abs_axis, LinuxAbsInfo abs_info) throws IOException; + + private final void addKeys(List components) throws IOException { + byte[] bits = getKeysBits(); + for (int i = 0; i < bits.length*8; i++) { + if (isBitSet(bits, i)) { + Component.Identifier id = LinuxNativeTypesMap.getButtonID(i); + components.add(new LinuxEventComponent(this, id, false, NativeDefinitions.EV_KEY, i)); + } + } + } + + private final void addAbsoluteAxes(List components) throws IOException { + byte[] bits = getAbsoluteAxesBits(); + for (int i = 0; i < bits.length*8; i++) { + if (isBitSet(bits, i)) { + Component.Identifier id = LinuxNativeTypesMap.getAbsAxisID(i); + components.add(new LinuxEventComponent(this, id, false, NativeDefinitions.EV_ABS, i)); + } + } + } + + private final void addRelativeAxes(List components) throws IOException { + byte[] bits = getRelativeAxesBits(); + for (int i = 0; i < bits.length*8; i++) { + if (isBitSet(bits, i)) { + Component.Identifier id = LinuxNativeTypesMap.getRelAxisID(i); + components.add(new LinuxEventComponent(this, id, true, NativeDefinitions.EV_REL, i)); + } + } + } + + public final List getComponents() { + return components; + } + + private final List getDeviceComponents() throws IOException { + List components = new ArrayList(); + byte[] evtype_bits = getEventTypeBits(); + if (isBitSet(evtype_bits, NativeDefinitions.EV_KEY)) + addKeys(components); + if (isBitSet(evtype_bits, NativeDefinitions.EV_ABS)) + addAbsoluteAxes(components); + if (isBitSet(evtype_bits, NativeDefinitions.EV_REL)) + addRelativeAxes(components); + return components; + } + + private final byte[] getForceFeedbackBits() throws IOException { + byte[] bits = new byte[NativeDefinitions.FF_MAX/8 + 1]; + nGetBits(fd, NativeDefinitions.EV_FF, bits); + return bits; + } + + private final byte[] getKeysBits() throws IOException { + byte[] bits = new byte[NativeDefinitions.KEY_MAX/8 + 1]; + nGetBits(fd, NativeDefinitions.EV_KEY, bits); + return bits; + } + + private final byte[] getAbsoluteAxesBits() throws IOException { + byte[] bits = new byte[NativeDefinitions.ABS_MAX/8 + 1]; + nGetBits(fd, NativeDefinitions.EV_ABS, bits); + return bits; + } + + private final byte[] getRelativeAxesBits() throws IOException { + byte[] bits = new byte[NativeDefinitions.REL_MAX/8 + 1]; + nGetBits(fd, NativeDefinitions.EV_REL, bits); + return bits; + } + + private final byte[] getEventTypeBits() throws IOException { + byte[] bits = new byte[NativeDefinitions.EV_MAX/8 + 1]; + nGetBits(fd, 0, bits); + return bits; + } + private final static native void nGetBits(long fd, int ev_type, byte[] evtype_bits) throws IOException; + + private final byte[] getDeviceUsageBits() throws IOException { + byte[] bits = new byte[NativeDefinitions.USAGE_MAX/8 + 1]; + if (getVersion() >= 0x010001) { + nGetDeviceUsageBits(fd, bits); + } + return bits; + } + private final static native void nGetDeviceUsageBits(long fd, byte[] type_bits) throws IOException; + + public final synchronized void pollKeyStates() throws IOException { + nGetKeyStates(fd, key_states); + } + private final static native void nGetKeyStates(long fd, byte[] states) throws IOException; + + public final boolean isKeySet(int bit) { + return isBitSet(key_states, bit); + } + + public final static boolean isBitSet(byte[] bits, int bit) { + return (bits[bit/8] & (1<<(bit%8))) != 0; + } + + public final String getName() { + return name; + } + + private final String getDeviceName() throws IOException { + return nGetName(fd); + } + private final static native String nGetName(long fd) throws IOException; + + public final synchronized void close() throws IOException { + if (!closed) { + try { + if (rumblers != null) + for (int i = 0; i < rumblers.length; i++) { + rumblers[i].rumble(0); + // erasing effects seems to be unsupported on logitech devices + //rumblers[i].erase(); + } + } finally { + closed = true; + nClose(fd); + } + } + } + private final static native void nClose(long fd) throws IOException; + + private final void checkClosed() throws IOException { + if (closed) + throw new IOException("Device is closed"); + } + + protected void finalize() throws IOException { + close(); + } +} diff --git a/plugins/awt/src/net/java/games/input/AWTAxis.java b/plugins/linux/src/java/net/java/games/input/LinuxForceFeedbackEffect.java index daa2e12..2e3a0e7 100644 --- a/plugins/awt/src/net/java/games/input/AWTAxis.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxForceFeedbackEffect.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2004 Jeremy Booth ([email protected]) + * Copyright (C) 2003 Jeremy Booth ([email protected]) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,51 +25,52 @@ */ package net.java.games.input; +import java.io.IOException; + /** - * @author Jeremy - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates + * @author elias */ -public class AWTAxis extends AbstractComponent { - - private float value = 0.0f; - - /** - * @param name - * @param id - */ - protected AWTAxis(String name, Identifier id) { - super(name, id); +abstract class LinuxForceFeedbackEffect implements Rumbler { + private final LinuxEventDevice device; + private final int ff_id; + + public LinuxForceFeedbackEffect(LinuxEventDevice device) throws IOException { + this.device = device; + this.ff_id = upload(-1, 0); } - /** - * Returns the data from the last time the control has been polled. - * If this axis is a button, the value returned will be either 0.0f or 1.0f. - * If this axis is normalized, the value returned will be between -1.0f and - * 1.0f. - * @return 0.0f by default, can be overridden - */ - public float getPollData() { - return value; - } + protected abstract int upload(int id, float intensity) throws IOException; + + private final void write(int value) throws IOException { + device.writeEvent(NativeDefinitions.EV_FF, ff_id, value); + } - /* (non-Javadoc) - * @see net.java.games.input.Component#isRelative() - */ - public boolean isRelative() { - return false; - } - - /** - * Returns whether or not the axis is analog, or false if it is digital. - * @return false by default, can be overridden - */ - public boolean isAnalog() { - return true; - } + protected final LinuxEventDevice getDevice() { + return device; + } + + public final void rumble(float intensity) { + try { + if (intensity > 0) { + upload(ff_id, intensity); + write(1); + } else { + write(0); + } + } catch (IOException e) { + ControllerEnvironment.logln("Failed to rumble: " + e); + } + } - void setValue(float value) { - this.value = value; - } + public final void erase() throws IOException { + device.eraseEffect(ff_id); + } + + public final String getAxisName() { + return null; + } + + public final Component.Identifier getAxisIdentifier() { + return null; + } } diff --git a/plugins/linux/src/java/net/java/games/input/LinuxInputID.java b/plugins/linux/src/java/net/java/games/input/LinuxInputID.java new file mode 100644 index 0000000..bed8fd3 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxInputID.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +/** + * @author elias + */ +final class LinuxInputID { + private final int bustype; + private final int vendor; + private final int product; + private final int version; + + public LinuxInputID(int bustype, int vendor, int product, int version) { + this.bustype = bustype; + this.vendor = vendor; + this.product = product; + this.version = version; + } + + public final Controller.PortType getPortType() { + return LinuxNativeTypesMap.getPortType(bustype); + } + + public final String toString() { + return "LinuxInputID: bustype = 0x" + Integer.toHexString(bustype) + " | vendor = 0x" + Integer.toHexString(vendor) + + " | product = 0x" + Integer.toHexString(product) + " | version = 0x" + Integer.toHexString(version); + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxJoystickAbstractController.java b/plugins/linux/src/java/net/java/games/input/LinuxJoystickAbstractController.java new file mode 100644 index 0000000..bf5377f --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxJoystickAbstractController.java @@ -0,0 +1,70 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents a Linux controller +* @author elias +* @version 1.0 +*/ +final class LinuxJoystickAbstractController extends AbstractController { + private final LinuxJoystickDevice device; + + protected LinuxJoystickAbstractController(LinuxJoystickDevice device, Component[] components, Controller[] children, Rumbler[] rumblers) { + super(device.getName(), components, children, rumblers); + this.device = device; + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + device.setBufferSize(size); + } + + public final void pollDevice() throws IOException { + device.poll(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return false; + } + + public Type getType() { + return Controller.Type.STICK; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxJoystickAxis.java b/plugins/linux/src/java/net/java/games/input/LinuxJoystickAxis.java new file mode 100644 index 0000000..0b2621b --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxJoystickAxis.java @@ -0,0 +1,69 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents a linux Axis +* @author elias +* @version 1.0 +*/ +class LinuxJoystickAxis extends AbstractComponent { + private float value; + + public LinuxJoystickAxis(Component.Identifier.Axis axis_id) { + super(axis_id.getName(), axis_id); + } + + public final boolean isRelative() { + return false; + } + + public final boolean isAnalog() { + return true; + } + + final void setValue(float value) { + this.value = value; + } + + protected final float poll() throws IOException { + return value; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxJoystickButton.java b/plugins/linux/src/java/net/java/games/input/LinuxJoystickButton.java new file mode 100644 index 0000000..f8d47d5 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxJoystickButton.java @@ -0,0 +1,65 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents a linux button from the joystick interface +* @author elias +* @version 1.0 +*/ +final class LinuxJoystickButton extends AbstractComponent { + private float value; + + public LinuxJoystickButton(Component.Identifier.Button button_id) { + super(button_id.getName(), button_id); + } + + public final boolean isRelative() { + return false; + } + + final void setValue(float value) { + this.value = value; + } + + protected final float poll() throws IOException { + return value; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxJoystickDevice.java b/plugins/linux/src/java/net/java/games/input/LinuxJoystickDevice.java new file mode 100644 index 0000000..2d72027 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxJoystickDevice.java @@ -0,0 +1,185 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +import java.io.IOException; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + +/** + * @author elias + */ +final class LinuxJoystickDevice implements LinuxDevice { + public final static int JS_EVENT_BUTTON = 0x01; /* button pressed/released */ + public final static int JS_EVENT_AXIS = 0x02; /* joystick moved */ + public final static int JS_EVENT_INIT = 0x80; /* initial state of device */ + + public final static int AXIS_MAX_VALUE = 32767; + + private final long fd; + private final String name; + + private final LinuxJoystickEvent joystick_event = new LinuxJoystickEvent(); + private final Event event = new Event(); + private final LinuxJoystickButton[] buttons; + private final LinuxJoystickAxis[] axes; + + private EventQueue event_queue; + + /* Closed state variable that protects the validity of the file descriptor. + * Access to the closed state must be synchronized + */ + private boolean closed; + + public LinuxJoystickDevice(String filename) throws IOException { + this.fd = nOpen(filename); + try { + this.name = getDeviceName(); + setBufferSize(AbstractController.EVENT_QUEUE_DEPTH); + buttons = new LinuxJoystickButton[getNumDeviceButtons()]; + axes = new LinuxJoystickAxis[getNumDeviceAxes()]; + } catch (IOException e) { + close(); + throw e; + } + } + private final static native long nOpen(String filename) throws IOException; + + public final synchronized void setBufferSize(int size) { + event_queue = new EventQueue(size); + } + + private final void processEvent(LinuxJoystickEvent joystick_event) { + int index = joystick_event.getNumber(); + // Filter synthetic init event flag + int type = joystick_event.getType() & ~JS_EVENT_INIT; + switch (type) { + case JS_EVENT_BUTTON: + if (index < getNumButtons()) { + LinuxJoystickButton button = buttons[index]; + if (button != null) { + float value = joystick_event.getValue(); + button.setValue(value); + event.set(button, value, joystick_event.getNanos()); + break; + } + } + return; + case JS_EVENT_AXIS: + if (index < getNumAxes()) { + LinuxJoystickAxis axis = axes[index]; + if (axis != null) { + float value = (float)joystick_event.getValue()/AXIS_MAX_VALUE; + axis.setValue(value); + event.set(axis, value, joystick_event.getNanos()); + break; + } + } + return; + default: + // Unknown component type + return; + } + if (!event_queue.isFull()) { + event_queue.add(event); + } + } + + public final void registerAxis(int index, LinuxJoystickAxis axis) { + axes[index] = axis; + } + + public final void registerButton(int index, LinuxJoystickButton button) { + buttons[index] = button; + } + + public final synchronized boolean getNextEvent(Event event) throws IOException { + return event_queue.getNextEvent(event); + } + + public final synchronized void poll() throws IOException { + checkClosed(); + while (getNextDeviceEvent(joystick_event)) { + processEvent(joystick_event); + } + } + + private final boolean getNextDeviceEvent(LinuxJoystickEvent joystick_event) throws IOException { + return nGetNextEvent(fd, joystick_event); + } + private final static native boolean nGetNextEvent(long fd, LinuxJoystickEvent joystick_event) throws IOException; + + public final int getNumAxes() { + return axes.length; + } + + public final int getNumButtons() { + return buttons.length; + } + + private final int getNumDeviceButtons() throws IOException { + return nGetNumButtons(fd); + } + private final static native int nGetNumButtons(long fd) throws IOException; + + private final int getNumDeviceAxes() throws IOException { + return nGetNumAxes(fd); + } + private final static native int nGetNumAxes(long fd) throws IOException; + + private final int getVersion() throws IOException { + return nGetVersion(fd); + } + private final static native int nGetVersion(long fd) throws IOException; + + public final String getName() { + return name; + } + + private final String getDeviceName() throws IOException { + return nGetName(fd); + } + private final static native String nGetName(long fd) throws IOException; + + public final synchronized void close() throws IOException { + if (!closed) { + closed = true; + nClose(fd); + } + } + private final static native void nClose(long fd) throws IOException; + + private final void checkClosed() throws IOException { + if (closed) + throw new IOException("Device is closed"); + } + + protected void finalize() throws IOException { + close(); + } +} diff --git a/plugins/linux/src/native/joystickInterface.h b/plugins/linux/src/java/net/java/games/input/LinuxJoystickEvent.java index 01b8c58..4e14039 100644 --- a/plugins/linux/src/native/joystickInterface.h +++ b/plugins/linux/src/java/net/java/games/input/LinuxJoystickEvent.java @@ -23,15 +23,37 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE */ +package net.java.games.input; -#if !defined(joystickInterface_h) -#define joystickInterface_h +/** + * @author elias + */ +final class LinuxJoystickEvent { + private long nanos; + private int value; + private int type; + private int number; + + public final void set(long millis, int value, int type, int number) { + this.nanos = millis*1000000; + this.value = value; + this.type = type; + this.number = number; + } + + public final int getValue() { + return value; + } -#include "Device.h" + public final int getType() { + return type; + } -int jsGetJoystickInterfaceVersionNumber(); -int jsInit(); -int jsGetNumberDevices(); -void jsGetDevices(Device **deviceList); + public final int getNumber() { + return number; + } -#endif //joystickInterface_h + public final long getNanos() { + return nanos; + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxKeyboard.java b/plugins/linux/src/java/net/java/games/input/LinuxKeyboard.java index 4ea1c47..96b2d08 100644 --- a/plugins/linux/src/java/net/java/games/input/LinuxKeyboard.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxKeyboard.java @@ -1,175 +1,68 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) +/* + * %W% %E% * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ package net.java.games.input; -/** Class that represents a keyboard under linux - * @author Jeremy Booth ([email protected]) - */ -public class LinuxKeyboard extends StandardKeyboard { - - /** Values for the keys - */ - private int keyData[]; - /** Needed for the polling methods - */ - private int dummyRelAxesData[]; - /** Needed for the polling methods - */ - private int dummyAbsAxesData[]; - /** Map of native key numbers from jinput key id key indexes. - */ - private int keyMap[]; - /** List of keys this keyboard supports - */ - private int supportedKeys[]; - /** Number of keys this keyboard has - */ - private int numKeys; - /** Port type that this keyboard is connected to. - */ - private PortType portType; - /** The native device id - */ - private int nativeID; - - /** Creates a new instance of LinuxKeyboard - * @param nativeID Native device id - * @param name Name of this keybaord - * @param numButtons Number of keys - * @param numRelAxes Number of relative axes (you never know) - * @param numAbsAxes Number of absolute axes (you never know) - */ - public LinuxKeyboard(int nativeID, String name, int numButtons, int numRelAxes, int numAbsAxes) { - super(name); - - throw new RuntimeException("Error, should not get here"); - - /*children = NO_CONTROLLERS; - rumblers = NO_RUMBLERS; - - this.nativeID = nativeID; - - portType = LinuxNativeTypesMap.getPortType(getNativePortType(nativeID)); - - dummyRelAxesData = new int[numRelAxes]; - dummyAbsAxesData = new int[numAbsAxes]; - - this.numKeys = numButtons; - keyData = new int[numButtons+1]; - supportedKeys = new int[numButtons+1]; - keyMap = new int[KeyID.LAST.getKeyIndex()]; - - getSupportedButtons(supportedKeys); - supportedKeys[numKeys] = NativeDefinitions.KEY_UNKNOWN; - - setupKeyMap(); - renameKeys();*/ - } - - /** Returns whether or not the given key has been pressed since the last - * call to poll. This is called from a key's getPollData method. - * @param key The key to check - * @return the value fo the key - */ - protected boolean isKeyPressed(Key key) { - /*if(((Keyboard.KeyID) key.getIdentifier()).getKeyIndex() == StandardKeyboard.KeyID.ESCAPE.getKeyIndex()) { - System.out.println("Asked if key " + key + " was pressed"); - System.out.println("key id " + key.getIdentifier()); - System.out.println("keyIndex " + ((Keyboard.KeyID) key.getIdentifier()).getKeyIndex()); - System.out.println("keyMap for index is " + keyMap[((Keyboard.KeyID) key.getIdentifier()).getKeyIndex()]); - System.out.println("name for supportedKeys index is " + LinuxNativeTypesMap.getButtonName(supportedKeys[keyMap[((Keyboard.KeyID) key.getIdentifier()).getKeyIndex()]])); - System.out.println("id for supportedKeys index is " + LinuxNativeTypesMap.getButtonID(supportedKeys[keyMap[((Keyboard.KeyID) key.getIdentifier()).getKeyIndex()]])); - System.out.flush(); - }*/ - if(keyData[keyMap[((Component.Identifier.Key) key.getIdentifier()).getKeyIndex()]] > 0) { - return true; - } - return false; - } - - /** Polls axes for data. Returns false if the controller is no longer valid. - * Polling reflects the current state of the device when polled. - * @return False if this device is invalid. - */ - public boolean poll() { - int retval = JInputLibrary.safePoll(nativeID, keyData, dummyRelAxesData, dummyAbsAxesData); - if(retval>=0) return true; - return false; - } - - /** Goes through every key to initialise the key map - */ - private void setupKeyMap() { - for(int i=0;i<Component.Identifier.Key.LAST.getKeyIndex();i++) { - keyMap[i] = numKeys; - } - for(int i=0;i<numKeys;i++) { - int tempNativeID = supportedKeys[i]; - Component.Identifier.Key tempKeyID = Component.Identifier.Key.VOID; - try { - tempKeyID = (Component.Identifier.Key)LinuxNativeTypesMap.getButtonID(tempNativeID); - } catch (ClassCastException e) { - System.out.println("LinuxNativeTypesMap.getButtonID() returned " + LinuxNativeTypesMap.getButtonID(tempNativeID).getClass().toString()); - } - if(tempKeyID.getKeyIndex() < keyMap.length) { - keyMap[tempKeyID.getKeyIndex()] = i; - //System.out.println("keyMap[" + (tempKeyID.getKeyIndex()) + "] (" + tempKeyID + ") set to index " + i + " (" + LinuxNativeTypesMap.getButtonName(supportedKeys[i]) + ")"); - } else { - //System.out.println("Linux key " + LinuxNativeTypesMap.getButtonName(tempNativeID) + " isn't supported by jinput"); - } - } - } - - /** Renames all the keys based on what information we have about them (number/name) - */ - private void renameKeys() { - Component tempAxes[] = getComponents(); - // Do this one by hand as it's a special case - //((AbstractAxis)tempAxes[0]).setName("Unknown"); - for(int i=0;i<tempAxes.length;i++) { - Component tempAxis = tempAxes[i]; - int nativeKeyID = supportedKeys[keyMap[((Component.Identifier.Key) tempAxis.getIdentifier()).getKeyIndex()]]; - //System.out.println("key " + tempAxis + " map: " + nativeKeyID); - if(nativeKeyID != NativeDefinitions.KEY_UNKNOWN) { - String tempName = LinuxNativeTypesMap.getButtonName(nativeKeyID); - ((AbstractComponent)tempAxis).setName(tempName); +import java.io.IOException; + +/** Represents an OSX Keyboard +* @author elias +* @version 1.0 +*/ +final class LinuxKeyboard extends Keyboard { + private final PortType port; + private final LinuxEventDevice device; + + protected LinuxKeyboard(LinuxEventDevice device, Component[] components, Controller[] children, Rumbler[] rumblers) throws IOException { + super(device.getName(), components, children, rumblers); + this.device = device; + this.port = device.getPortType(); + } + + public final PortType getPortType() { + return port; + } - /*System.out.println("axis id is " + (Keyboard.KeyID) tempAxis.getIdentifier()); - System.out.println("keyMap[id] is " + keyMap[((Keyboard.KeyID) tempAxis.getIdentifier()).getKeyIndex()]); - System.out.println("nativeKeyID is: " + nativeKeyID); - System.out.println("Set name of key " + ((Keyboard.KeyID) tempAxis.getIdentifier()).getKeyIndex() + " to " + tempName);*/ - } - } - } - - /** Gets all the supported keys for this device - * @param supportedButtons The array if key types to populate - */ - private void getSupportedButtons(int supportedButtons[]) { - JInputLibrary.getSupportedButtons(nativeID, supportedButtons); - } + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return LinuxControllers.getNextDeviceEvent(event, device); + } + public final void pollDevice() throws IOException { + device.pollKeyStates(); + } } diff --git a/plugins/linux/src/java/net/java/games/input/LinuxMouse.java b/plugins/linux/src/java/net/java/games/input/LinuxMouse.java index b345b5e..17b5895 100644 --- a/plugins/linux/src/java/net/java/games/input/LinuxMouse.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxMouse.java @@ -1,168 +1,68 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) +/* + * %W% %E% * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ package net.java.games.input; -/** Class that represents a mouse under linux. - * - * @author Jeremy Booth ([email protected]) - */ -public class LinuxMouse extends Mouse { - - /** The parent linux device - */ - private LinuxDevice device; - - /** Creates a new instance of LinuxMouse - * @param device The parent device - */ - public LinuxMouse(LinuxDevice device) { - super(device.getName()); - - this.device = device; - Component[] components = device.getComponents(); - Component x = null; - Component y = null; - Component wheel = null; - Button left = null; - Button right = null; - Button middle = null; - Button side = null; - Button extra = null; - Button forward = null; - Button back = null; - - // start from the back, that way the first one is it - for(int i = (components.length -1);i>=0;i--) { - Component tempAxis = components[i]; - if(tempAxis.isRelative()) { - if(tempAxis.getIdentifier() == Component.Identifier.Axis.X) { - x = tempAxis; - } else if(tempAxis.getIdentifier() == Component.Identifier.Axis.Y) { - y = tempAxis; - } else if(tempAxis.getIdentifier() == Component.Identifier.Axis.SLIDER) { - wheel = tempAxis; - } - } else if(!(tempAxis.isAnalog())) { - if(tempAxis.getIdentifier() == Component.Identifier.Button.LEFT) { - left = new LinuxMouseButton(tempAxis); - } else if(tempAxis.getIdentifier() == Component.Identifier.Button.RIGHT) { - right = new LinuxMouseButton(tempAxis); - } else if(tempAxis.getIdentifier() == Component.Identifier.Button.MIDDLE) { - middle = new LinuxMouseButton(tempAxis); - } else if(tempAxis.getIdentifier() == Component.Identifier.Button.SIDE) { - side = new LinuxMouseButton(tempAxis); - } else if(tempAxis.getIdentifier() == Component.Identifier.Button.EXTRA) { - extra = new LinuxMouseButton(tempAxis); - } else if(tempAxis.getIdentifier() == Component.Identifier.Button.FORWARD) { - forward = new LinuxMouseButton(tempAxis); - } else if(tempAxis.getIdentifier() == Component.Identifier.Button.BACK) { - back = new LinuxMouseButton(tempAxis); - } - } - } - ball = new LinuxMouseBall(x,y,wheel); - buttons = new LinuxMouseButtons(left, right, middle, side, extra, forward, back); - - } - - /** Polls axes for data. Returns false if the controller is no longer valid. - * Polling reflects the current state of the device when polled. - * @return Returns false if the controller is no longer valid. - */ - public boolean poll() { - return device.poll(); - } - - /** Mouse ball under linux - */ - private class LinuxMouseBall extends Ball { - /** Constructs the new mouse ball - * @param x The x axis - * @param y The y axis - * @param wheel The mouse wheel axis - */ - public LinuxMouseBall(Component x, Component y, Component wheel) { - super(LinuxMouse.this.getName() + " ball"); - this.x = x; - this.y = y; - this.wheel = wheel; - } - } - - /** Mouse buttons under linux - */ - private class LinuxMouseButtons extends Buttons { - /** Creates the new mouse's buttons - * @param left Left mouse button - * @param right Right mouse button - * @param middle Middle mouse button - * @param side Side mouse button - * @param extra Extra mouse button - * @param forward Forward mouse button - * @param back Back mouse button - */ - public LinuxMouseButtons(Button left, Button right, Button middle, Button side, Button extra, Button forward, Button back) { - super(LinuxMouse.this.getName() + " buttons"); - this.left = left; - this.right = right; - this.middle = middle; - this.side = side; - this.extra = extra; - this.forward = forward; - this.back = back; - } - } - - /** Linux specific mouse buttons - */ - private class LinuxMouseButton extends Mouse.Button { - /** The real Axis - */ - private Component realAxis; - - /** Construct a linux mouse button fro mthe given axis - * @param axis The axis that holds the data - */ - public LinuxMouseButton(Component axis) { - super(axis.getName(), (Component.Identifier.Button)axis.getIdentifier()); - this.realAxis = axis; - } - - /** Returns true f this axis is relative - * @return Always returns false for a mouse button - */ - public boolean isRelative() { - return false; - } - - /** Returns the data for this mouse button - * @return Retursn this mouse buttons value - */ - public float getPollData(){ - return realAxis.getPollData(); - } - } +import java.io.IOException; + +/** Represents an OSX Mouse +* @author elias +* @version 1.0 +*/ +final class LinuxMouse extends Mouse { + private final PortType port; + private final LinuxEventDevice device; + + protected LinuxMouse(LinuxEventDevice device, Component[] components, Controller[] children, Rumbler[] rumblers) throws IOException { + super(device.getName(), components, children, rumblers); + this.device = device; + this.port = device.getPortType(); + } + + public final PortType getPortType() { + return port; + } + + public final void pollDevice() throws IOException { + device.pollKeyStates(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return LinuxControllers.getNextDeviceEvent(event, device); + } } diff --git a/plugins/linux/src/java/net/java/games/input/LinuxNativeTypesMap.java b/plugins/linux/src/java/net/java/games/input/LinuxNativeTypesMap.java index 5817922..a739074 100644 --- a/plugins/linux/src/java/net/java/games/input/LinuxNativeTypesMap.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxNativeTypesMap.java @@ -30,315 +30,25 @@ package net.java.games.input; * Key.Identifiers * @author Jeremy Booth ([email protected]) */ -public class LinuxNativeTypesMap { - - /** Instance of they key map - */ +class LinuxNativeTypesMap { private static LinuxNativeTypesMap INSTANCE = new LinuxNativeTypesMap(); - /** Indexed array of key names - */ - private String keyNames[]; - /** Inexed array of relative axes names - */ - private String relAxesNames[]; - /** Indexed array of absolute axis names - */ - private String absAxesNames[]; - /** Indexed array of relative axis ID's - */ - private Component.Identifier relAxesIDs[]; - /** Indexed array of absoulte axis ID's - */ - private Component.Identifier absAxesIDs[]; - /** Indexed array of button axis ID's - */ - private Component.Identifier buttonIDs[]; + private final Component.Identifier relAxesIDs[]; + private final Component.Identifier absAxesIDs[]; + private final Component.Identifier buttonIDs[]; /** create an empty, uninitialsed map */ private LinuxNativeTypesMap() { - keyNames = new String[NativeDefinitions.KEY_MAX]; + buttonIDs = new Component.Identifier[NativeDefinitions.KEY_MAX]; + relAxesIDs = new Component.Identifier[NativeDefinitions.REL_MAX]; + absAxesIDs = new Component.Identifier[NativeDefinitions.ABS_MAX]; + reInit(); } - /** Initialise the map, has to be done like this because the map references staic - * classes, as this would otherwise be done in a static class initialiser the whole - * thing blew up as the static classes this class references refer to this class - * this meant that the other classes could not be initialsed until this one was, - * but this class couldn't be loaded until the others were, all went horibly wrong - * and INSTANCE was null whilst initialising the class, ouch. - */ - public static void init() { - INSTANCE.reInit(); - } - /** Do the work. */ private void reInit() { - keyNames[NativeDefinitions.KEY_ESC] = "Escape"; - keyNames[NativeDefinitions.KEY_1] = "1"; - keyNames[NativeDefinitions.KEY_2] = "2"; - keyNames[NativeDefinitions.KEY_3] = "3"; - keyNames[NativeDefinitions.KEY_4] = "4"; - keyNames[NativeDefinitions.KEY_5] = "5"; - keyNames[NativeDefinitions.KEY_6] = "6"; - keyNames[NativeDefinitions.KEY_7] = "7"; - keyNames[NativeDefinitions.KEY_8] = "8"; - keyNames[NativeDefinitions.KEY_9] = "9"; - keyNames[NativeDefinitions.KEY_0] = "0"; - keyNames[NativeDefinitions.KEY_MINUS] = "-"; - keyNames[NativeDefinitions.KEY_EQUAL] = "="; - keyNames[NativeDefinitions.KEY_BACKSPACE] = "Backspace"; - keyNames[NativeDefinitions.KEY_TAB] = "Tab"; - keyNames[NativeDefinitions.KEY_Q] = "Q"; - keyNames[NativeDefinitions.KEY_W] = "W"; - keyNames[NativeDefinitions.KEY_E] = "E"; - keyNames[NativeDefinitions.KEY_R] = "R"; - keyNames[NativeDefinitions.KEY_T] = "T"; - keyNames[NativeDefinitions.KEY_Y] = "Y"; - keyNames[NativeDefinitions.KEY_U] = "U"; - keyNames[NativeDefinitions.KEY_I] = "I"; - keyNames[NativeDefinitions.KEY_O] = "O"; - keyNames[NativeDefinitions.KEY_P] = "P"; - keyNames[NativeDefinitions.KEY_LEFTBRACE] = "["; - keyNames[NativeDefinitions.KEY_RIGHTBRACE] = "]"; - keyNames[NativeDefinitions.KEY_ENTER] = "Enter"; - keyNames[NativeDefinitions.KEY_LEFTCTRL] = "LH Control"; - keyNames[NativeDefinitions.KEY_A] = "A"; - keyNames[NativeDefinitions.KEY_S] = "S"; - keyNames[NativeDefinitions.KEY_D] = "D"; - keyNames[NativeDefinitions.KEY_F] = "F"; - keyNames[NativeDefinitions.KEY_G] = "G"; - keyNames[NativeDefinitions.KEY_H] = "H"; - keyNames[NativeDefinitions.KEY_J] = "J"; - keyNames[NativeDefinitions.KEY_K] = "K"; - keyNames[NativeDefinitions.KEY_L] = "L"; - keyNames[NativeDefinitions.KEY_SEMICOLON] = ";"; - keyNames[NativeDefinitions.KEY_APOSTROPHE] = "'"; - keyNames[NativeDefinitions.KEY_GRAVE] = "`"; - keyNames[NativeDefinitions.KEY_LEFTSHIFT] = "LH Shift"; - keyNames[NativeDefinitions.KEY_BACKSLASH] = "\\"; - keyNames[NativeDefinitions.KEY_Z] = "Z"; - keyNames[NativeDefinitions.KEY_X] = "X"; - keyNames[NativeDefinitions.KEY_C] = "C"; - keyNames[NativeDefinitions.KEY_V] = "V"; - keyNames[NativeDefinitions.KEY_B] = "B"; - keyNames[NativeDefinitions.KEY_N] = "N"; - keyNames[NativeDefinitions.KEY_M] = "M"; - keyNames[NativeDefinitions.KEY_COMMA] = ","; - keyNames[NativeDefinitions.KEY_DOT] = "."; - keyNames[NativeDefinitions.KEY_SLASH] = "/"; - keyNames[NativeDefinitions.KEY_RIGHTSHIFT] = "RH Shift"; - keyNames[NativeDefinitions.KEY_KPASTERISK] = "*"; - keyNames[NativeDefinitions.KEY_LEFTALT] = "LH Alt"; - keyNames[NativeDefinitions.KEY_SPACE] = "Space"; - keyNames[NativeDefinitions.KEY_CAPSLOCK] = "CapsLock"; - keyNames[NativeDefinitions.KEY_F1] = "F1"; - keyNames[NativeDefinitions.KEY_F2] = "F2"; - keyNames[NativeDefinitions.KEY_F3] = "F3"; - keyNames[NativeDefinitions.KEY_F4] = "F4"; - keyNames[NativeDefinitions.KEY_F5] = "F5"; - keyNames[NativeDefinitions.KEY_F6] = "F6"; - keyNames[NativeDefinitions.KEY_F7] = "F7"; - keyNames[NativeDefinitions.KEY_F8] = "F8"; - keyNames[NativeDefinitions.KEY_F9] = "F9"; - keyNames[NativeDefinitions.KEY_F10] = "F10"; - keyNames[NativeDefinitions.KEY_NUMLOCK] = "NumLock"; - keyNames[NativeDefinitions.KEY_SCROLLLOCK] = "ScrollLock"; - keyNames[NativeDefinitions.KEY_KP7] = "KeyPad 7"; - keyNames[NativeDefinitions.KEY_KP8] = "KeyPad 8"; - keyNames[NativeDefinitions.KEY_KP9] = "Keypad 9"; - keyNames[NativeDefinitions.KEY_KPMINUS] = "KeyPad Minus"; - keyNames[NativeDefinitions.KEY_KP4] = "KeyPad 4"; - keyNames[NativeDefinitions.KEY_KP5] = "KeyPad 5"; - keyNames[NativeDefinitions.KEY_KP6] = "KeyPad 6"; - keyNames[NativeDefinitions.KEY_KPPLUS] = "KeyPad Plus"; - keyNames[NativeDefinitions.KEY_KP1] = "KeyPad 1"; - keyNames[NativeDefinitions.KEY_KP2] = "KeyPad 2"; - keyNames[NativeDefinitions.KEY_KP3] = "KeyPad 3"; - keyNames[NativeDefinitions.KEY_KP0] = "KeyPad 0"; - keyNames[NativeDefinitions.KEY_KPDOT] = "KeyPad decimal point"; - keyNames[NativeDefinitions.KEY_103RD] = "Huh?"; - keyNames[NativeDefinitions.KEY_F13] = "F13"; - keyNames[NativeDefinitions.KEY_102ND] = "Beats me..."; - keyNames[NativeDefinitions.KEY_F11] = "F11"; - keyNames[NativeDefinitions.KEY_F12] = "F12"; - keyNames[NativeDefinitions.KEY_F14] = "F14"; - keyNames[NativeDefinitions.KEY_F15] = "F15"; - keyNames[NativeDefinitions.KEY_F16] = "F16"; - keyNames[NativeDefinitions.KEY_F17] = "F17"; - keyNames[NativeDefinitions.KEY_F18] = "F18"; - keyNames[NativeDefinitions.KEY_F19] = "F19"; - keyNames[NativeDefinitions.KEY_F20] = "F20"; - keyNames[NativeDefinitions.KEY_KPENTER] = "Keypad Enter"; - keyNames[NativeDefinitions.KEY_RIGHTCTRL] = "RH Control"; - keyNames[NativeDefinitions.KEY_KPSLASH] = "KeyPad Forward Slash"; - keyNames[NativeDefinitions.KEY_SYSRQ] = "System Request"; - keyNames[NativeDefinitions.KEY_RIGHTALT] = "RH Alternate"; - keyNames[NativeDefinitions.KEY_LINEFEED] = "Line Feed"; - keyNames[NativeDefinitions.KEY_HOME] = "Home"; - keyNames[NativeDefinitions.KEY_UP] = "Up"; - keyNames[NativeDefinitions.KEY_PAGEUP] = "Page Up"; - keyNames[NativeDefinitions.KEY_LEFT] = "Left"; - keyNames[NativeDefinitions.KEY_RIGHT] = "Right"; - keyNames[NativeDefinitions.KEY_END] = "End"; - keyNames[NativeDefinitions.KEY_DOWN] = "Down"; - keyNames[NativeDefinitions.KEY_PAGEDOWN] = "Page Down"; - keyNames[NativeDefinitions.KEY_INSERT] = "Insert"; - keyNames[NativeDefinitions.KEY_DELETE] = "Delete"; - keyNames[NativeDefinitions.KEY_MACRO] = "Macro"; - keyNames[NativeDefinitions.KEY_MUTE] = "Mute"; - keyNames[NativeDefinitions.KEY_VOLUMEDOWN] = "Volume Down"; - keyNames[NativeDefinitions.KEY_VOLUMEUP] = "Volume Up"; - keyNames[NativeDefinitions.KEY_POWER] = "Power"; - keyNames[NativeDefinitions.KEY_KPEQUAL] = "KeyPad Equal"; - keyNames[NativeDefinitions.KEY_KPPLUSMINUS] = "KeyPad +/-"; - keyNames[NativeDefinitions.KEY_PAUSE] = "Pause"; - keyNames[NativeDefinitions.KEY_F21] = "F21"; - keyNames[NativeDefinitions.KEY_F22] = "F22"; - keyNames[NativeDefinitions.KEY_F23] = "F23"; - keyNames[NativeDefinitions.KEY_F24] = "F24"; - keyNames[NativeDefinitions.KEY_KPCOMMA] = "KeyPad comma"; - keyNames[NativeDefinitions.KEY_LEFTMETA] = "LH Meta"; - keyNames[NativeDefinitions.KEY_RIGHTMETA] = "RH Meta"; - keyNames[NativeDefinitions.KEY_COMPOSE] = "Compose"; - keyNames[NativeDefinitions.KEY_STOP] = "Stop"; - keyNames[NativeDefinitions.KEY_AGAIN] = "Again"; - keyNames[NativeDefinitions.KEY_PROPS] = "Properties"; - keyNames[NativeDefinitions.KEY_UNDO] = "Undo"; - keyNames[NativeDefinitions.KEY_FRONT] = "Front"; - keyNames[NativeDefinitions.KEY_COPY] = "Copy"; - keyNames[NativeDefinitions.KEY_OPEN] = "Open"; - keyNames[NativeDefinitions.KEY_PASTE] = "Paste"; - keyNames[NativeDefinitions.KEY_FIND] = "Find"; - keyNames[NativeDefinitions.KEY_CUT] = "Cut"; - keyNames[NativeDefinitions.KEY_HELP] = "Help"; - keyNames[NativeDefinitions.KEY_MENU] = "Menu"; - keyNames[NativeDefinitions.KEY_CALC] = "Calculator"; - keyNames[NativeDefinitions.KEY_SETUP] = "Setup"; - keyNames[NativeDefinitions.KEY_SLEEP] = "Sleep"; - keyNames[NativeDefinitions.KEY_WAKEUP] = "Wakeup"; - keyNames[NativeDefinitions.KEY_FILE] = "File"; - keyNames[NativeDefinitions.KEY_SENDFILE] = "Send File"; - keyNames[NativeDefinitions.KEY_DELETEFILE] = "Delete File"; - keyNames[NativeDefinitions.KEY_XFER] = "Transfer"; - keyNames[NativeDefinitions.KEY_PROG1] = "Program 1"; - keyNames[NativeDefinitions.KEY_PROG2] = "Program 2"; - keyNames[NativeDefinitions.KEY_WWW] = "Web Browser"; - keyNames[NativeDefinitions.KEY_MSDOS] = "DOS mode"; - keyNames[NativeDefinitions.KEY_COFFEE] = "Coffee"; - keyNames[NativeDefinitions.KEY_DIRECTION] = "Direction"; - keyNames[NativeDefinitions.KEY_CYCLEWINDOWS] = "Window cycle"; - keyNames[NativeDefinitions.KEY_MAIL] = "Mail"; - keyNames[NativeDefinitions.KEY_BOOKMARKS] = "Book Marks"; - keyNames[NativeDefinitions.KEY_COMPUTER] = "Computer"; - keyNames[NativeDefinitions.KEY_BACK] = "Back"; - keyNames[NativeDefinitions.KEY_FORWARD] = "Forward"; - keyNames[NativeDefinitions.KEY_CLOSECD] = "Close CD"; - keyNames[NativeDefinitions.KEY_EJECTCD] = "Eject CD"; - keyNames[NativeDefinitions.KEY_EJECTCLOSECD] = "Eject / Close CD"; - keyNames[NativeDefinitions.KEY_NEXTSONG] = "Next Song"; - keyNames[NativeDefinitions.KEY_PLAYPAUSE] = "Play and Pause"; - keyNames[NativeDefinitions.KEY_PREVIOUSSONG] = "Previous Song"; - keyNames[NativeDefinitions.KEY_STOPCD] = "Stop CD"; - keyNames[NativeDefinitions.KEY_RECORD] = "Record"; - keyNames[NativeDefinitions.KEY_REWIND] = "Rewind"; - keyNames[NativeDefinitions.KEY_PHONE] = "Phone"; - keyNames[NativeDefinitions.KEY_ISO] = "ISO"; - keyNames[NativeDefinitions.KEY_CONFIG] = "Config"; - keyNames[NativeDefinitions.KEY_HOMEPAGE] = "Home"; - keyNames[NativeDefinitions.KEY_REFRESH] = "Refresh"; - keyNames[NativeDefinitions.KEY_EXIT] = "Exit"; - keyNames[NativeDefinitions.KEY_MOVE] = "Move"; - keyNames[NativeDefinitions.KEY_EDIT] = "Edit"; - keyNames[NativeDefinitions.KEY_SCROLLUP] = "Scroll Up"; - keyNames[NativeDefinitions.KEY_SCROLLDOWN] = "Scroll Down"; - keyNames[NativeDefinitions.KEY_KPLEFTPAREN] = "KeyPad LH parenthesis"; - keyNames[NativeDefinitions.KEY_KPRIGHTPAREN] = "KeyPad RH parenthesis"; - keyNames[NativeDefinitions.KEY_INTL1] = "Intl 1"; - keyNames[NativeDefinitions.KEY_INTL2] = "Intl 2"; - keyNames[NativeDefinitions.KEY_INTL3] = "Intl 3"; - keyNames[NativeDefinitions.KEY_INTL4] = "Intl 4"; - keyNames[NativeDefinitions.KEY_INTL5] = "Intl 5"; - keyNames[NativeDefinitions.KEY_INTL6] = "Intl 6"; - keyNames[NativeDefinitions.KEY_INTL7] = "Intl 7"; - keyNames[NativeDefinitions.KEY_INTL8] = "Intl 8"; - keyNames[NativeDefinitions.KEY_INTL9] = "Intl 9"; - keyNames[NativeDefinitions.KEY_LANG1] = "Language 1"; - keyNames[NativeDefinitions.KEY_LANG2] = "Language 2"; - keyNames[NativeDefinitions.KEY_LANG3] = "Language 3"; - keyNames[NativeDefinitions.KEY_LANG4] = "Language 4"; - keyNames[NativeDefinitions.KEY_LANG5] = "Language 5"; - keyNames[NativeDefinitions.KEY_LANG6] = "Language 6"; - keyNames[NativeDefinitions.KEY_LANG7] = "Language 7"; - keyNames[NativeDefinitions.KEY_LANG8] = "Language 8"; - keyNames[NativeDefinitions.KEY_LANG9] = "Language 9"; - keyNames[NativeDefinitions.KEY_PLAYCD] = "Play CD"; - keyNames[NativeDefinitions.KEY_PAUSECD] = "Pause CD"; - keyNames[NativeDefinitions.KEY_PROG3] = "Program 3"; - keyNames[NativeDefinitions.KEY_PROG4] = "Program 4"; - keyNames[NativeDefinitions.KEY_SUSPEND] = "Suspend"; - keyNames[NativeDefinitions.KEY_CLOSE] = "Close"; - keyNames[NativeDefinitions.KEY_UNKNOWN] = "Specifically unknown"; - keyNames[NativeDefinitions.KEY_BRIGHTNESSDOWN] = "Brightness Down"; - keyNames[NativeDefinitions.KEY_BRIGHTNESSUP] = "Brightness Up"; - keyNames[NativeDefinitions.BTN_0] = "Button 0"; - keyNames[NativeDefinitions.BTN_1] = "Button 1"; - keyNames[NativeDefinitions.BTN_2] = "Button 2"; - keyNames[NativeDefinitions.BTN_3] = "Button 3"; - keyNames[NativeDefinitions.BTN_4] = "Button 4"; - keyNames[NativeDefinitions.BTN_5] = "Button 5"; - keyNames[NativeDefinitions.BTN_6] = "Button 6"; - keyNames[NativeDefinitions.BTN_7] = "Button 7"; - keyNames[NativeDefinitions.BTN_8] = "Button 8"; - keyNames[NativeDefinitions.BTN_9] = "Button 9"; - keyNames[NativeDefinitions.BTN_LEFT] = "Left Button"; - keyNames[NativeDefinitions.BTN_RIGHT] = "Right Button"; - keyNames[NativeDefinitions.BTN_MIDDLE] = "Middle Button"; - keyNames[NativeDefinitions.BTN_SIDE] = "Side Button"; - keyNames[NativeDefinitions.BTN_EXTRA] = "Extra Button"; - keyNames[NativeDefinitions.BTN_FORWARD] = "Forward Button"; - keyNames[NativeDefinitions.BTN_BACK] = "Back Button"; - keyNames[NativeDefinitions.BTN_TRIGGER] = "Trigger Button"; - keyNames[NativeDefinitions.BTN_THUMB] = "Thumb Button"; - keyNames[NativeDefinitions.BTN_THUMB2] = "Second Thumb Button"; - keyNames[NativeDefinitions.BTN_TOP] = "Top Button"; - keyNames[NativeDefinitions.BTN_TOP2] = "Second Top Button"; - keyNames[NativeDefinitions.BTN_PINKIE] = "Pinkie Button"; - keyNames[NativeDefinitions.BTN_BASE] = "Base Button"; - keyNames[NativeDefinitions.BTN_BASE2] = "Second Base Button"; - keyNames[NativeDefinitions.BTN_BASE3] = "Third Base Button"; - keyNames[NativeDefinitions.BTN_BASE4] = "Fourth Base Button"; - keyNames[NativeDefinitions.BTN_BASE5] = "Fifth Base Button"; - keyNames[NativeDefinitions.BTN_BASE6] = "Sixth Base Button"; - keyNames[NativeDefinitions.BTN_DEAD] = "Dead Button"; - keyNames[NativeDefinitions.BTN_A] = "Button A"; - keyNames[NativeDefinitions.BTN_B] = "Button B"; - keyNames[NativeDefinitions.BTN_C] = "Button C"; - keyNames[NativeDefinitions.BTN_X] = "Button X"; - keyNames[NativeDefinitions.BTN_Y] = "Button Y"; - keyNames[NativeDefinitions.BTN_Z] = "Button Z"; - keyNames[NativeDefinitions.BTN_TL] = "Thumb Left Button"; - keyNames[NativeDefinitions.BTN_TR] = "Thumb Right Button "; - keyNames[NativeDefinitions.BTN_TL2] = "Second Thumb Left Button"; - keyNames[NativeDefinitions.BTN_TR2] = "Second Thumb Right Button "; - keyNames[NativeDefinitions.BTN_SELECT] = "Select Button"; - keyNames[NativeDefinitions.BTN_MODE] = "Mode Button"; - keyNames[NativeDefinitions.BTN_THUMBL] = "Another Left Thumb Button "; - keyNames[NativeDefinitions.BTN_THUMBR] = "Another Right Thumb Button "; - keyNames[NativeDefinitions.BTN_TOOL_PEN] = "Digitiser Pen Tool"; - keyNames[NativeDefinitions.BTN_TOOL_RUBBER] = "Digitiser Rubber Tool"; - keyNames[NativeDefinitions.BTN_TOOL_BRUSH] = "Digitiser Brush Tool"; - keyNames[NativeDefinitions.BTN_TOOL_PENCIL] = "Digitiser Pencil Tool"; - keyNames[NativeDefinitions.BTN_TOOL_AIRBRUSH] = "Digitiser Airbrush Tool"; - keyNames[NativeDefinitions.BTN_TOOL_FINGER] = "Digitiser Finger Tool"; - keyNames[NativeDefinitions.BTN_TOOL_MOUSE] = "Digitiser Mouse Tool"; - keyNames[NativeDefinitions.BTN_TOOL_LENS] = "Digitiser Lens Tool"; - keyNames[NativeDefinitions.BTN_TOUCH] = "Digitiser Touch Button "; - keyNames[NativeDefinitions.BTN_STYLUS] = "Digitiser Stylus Button "; - keyNames[NativeDefinitions.BTN_STYLUS2] = "Second Digitiser Stylus Button "; - - buttonIDs = new Component.Identifier[NativeDefinitions.KEY_MAX]; buttonIDs[NativeDefinitions.KEY_ESC] = Component.Identifier.Key.ESCAPE; buttonIDs[NativeDefinitions.KEY_1] = Component.Identifier.Key._1; buttonIDs[NativeDefinitions.KEY_2] = Component.Identifier.Key._2; @@ -422,7 +132,7 @@ public class LinuxNativeTypesMap { buttonIDs[NativeDefinitions.KEY_KP3] = Component.Identifier.Key.NUMPAD3; buttonIDs[NativeDefinitions.KEY_KP0] = Component.Identifier.Key.NUMPAD0; buttonIDs[NativeDefinitions.KEY_KPDOT] = Component.Identifier.Key.DECIMAL; - buttonIDs[NativeDefinitions.KEY_103RD] = null; +// buttonIDs[NativeDefinitions.KEY_103RD] = null; buttonIDs[NativeDefinitions.KEY_F13] = Component.Identifier.Key.F13; buttonIDs[NativeDefinitions.KEY_102ND] = null; buttonIDs[NativeDefinitions.KEY_F11] = Component.Identifier.Key.F11; @@ -547,7 +257,7 @@ public class LinuxNativeTypesMap { /*buttonIDs[NativeDefinitions.KEY_BRIGHTNESSDOWN] = "Brightness Down"; buttonIDs[NativeDefinitions.KEY_BRIGHTNESSUP] = "Brightness Up";*/ - //Msic keys + //Misc keys buttonIDs[NativeDefinitions.BTN_0] = Component.Identifier.Button._0; buttonIDs[NativeDefinitions.BTN_1] = Component.Identifier.Button._1; buttonIDs[NativeDefinitions.BTN_2] = Component.Identifier.Button._2; @@ -612,53 +322,15 @@ public class LinuxNativeTypesMap { buttonIDs[NativeDefinitions.BTN_STYLUS] = Component.Identifier.Button.STYLUS; buttonIDs[NativeDefinitions.BTN_STYLUS2] = Component.Identifier.Button.STYLUS2; - relAxesNames = new String[NativeDefinitions.REL_MAX]; - relAxesNames[NativeDefinitions.REL_X] = "X axis"; - relAxesNames[NativeDefinitions.REL_Y] = "Y axis"; - relAxesNames[NativeDefinitions.REL_Z] = "Z axis"; - relAxesNames[NativeDefinitions.REL_HWHEEL] ="Horizontal wheel"; - relAxesNames[NativeDefinitions.REL_DIAL] = "Dial"; - relAxesNames[NativeDefinitions.REL_WHEEL] = "Vertical wheel"; - relAxesNames[NativeDefinitions.REL_MISC] = "Miscellaneous"; - - relAxesIDs = new Component.Identifier[NativeDefinitions.REL_MAX]; relAxesIDs[NativeDefinitions.REL_X] = Component.Identifier.Axis.X; relAxesIDs[NativeDefinitions.REL_Y] = Component.Identifier.Axis.Y; relAxesIDs[NativeDefinitions.REL_Z] = Component.Identifier.Axis.Z; - relAxesIDs[NativeDefinitions.REL_WHEEL] = Component.Identifier.Axis.SLIDER; + relAxesIDs[NativeDefinitions.REL_WHEEL] = Component.Identifier.Axis.Z; // There are guesses as I have no idea what they would be used for relAxesIDs[NativeDefinitions.REL_HWHEEL] = Component.Identifier.Axis.SLIDER; relAxesIDs[NativeDefinitions.REL_DIAL] = Component.Identifier.Axis.SLIDER; relAxesIDs[NativeDefinitions.REL_MISC] = Component.Identifier.Axis.SLIDER; - absAxesNames = new String[NativeDefinitions.ABS_MAX]; - absAxesNames[NativeDefinitions.ABS_X] = "X axis"; - absAxesNames[NativeDefinitions.ABS_Y] = "Y axis"; - absAxesNames[NativeDefinitions.ABS_Z] = "Z axis"; - absAxesNames[NativeDefinitions.ABS_RX] = "X rate axis"; - absAxesNames[NativeDefinitions.ABS_RY] = "Y rate axis"; - absAxesNames[NativeDefinitions.ABS_RZ] = "Z rate axis"; - absAxesNames[NativeDefinitions.ABS_THROTTLE] = "Throttle"; - absAxesNames[NativeDefinitions.ABS_RUDDER] = "Rudder"; - absAxesNames[NativeDefinitions.ABS_WHEEL] = "Wheel"; - absAxesNames[NativeDefinitions.ABS_GAS] = "Accelerator"; - absAxesNames[NativeDefinitions.ABS_BRAKE] = "Brake"; - // Hats are done this way as they are mapped from two axis down to one - absAxesNames[NativeDefinitions.ABS_HAT0X] = "Hat 1"; - absAxesNames[NativeDefinitions.ABS_HAT0Y] = "Hat 1"; - absAxesNames[NativeDefinitions.ABS_HAT1X] = "Hat 2"; - absAxesNames[NativeDefinitions.ABS_HAT1Y] = "Hat 2"; - absAxesNames[NativeDefinitions.ABS_HAT2X] = "Hat 3"; - absAxesNames[NativeDefinitions.ABS_HAT2Y] = "Hat 3"; - absAxesNames[NativeDefinitions.ABS_HAT3X] = "Hat 4"; - absAxesNames[NativeDefinitions.ABS_HAT3Y] = "Hat 4"; - absAxesNames[NativeDefinitions.ABS_PRESSURE] = "Pressure"; - absAxesNames[NativeDefinitions.ABS_DISTANCE] = "Distance"; - absAxesNames[NativeDefinitions.ABS_TILT_X] = "X axis tilt"; - absAxesNames[NativeDefinitions.ABS_TILT_Y] = "Y axis tilt"; - absAxesNames[NativeDefinitions.ABS_MISC] = "Miscellaneous"; - - absAxesIDs = new Component.Identifier[NativeDefinitions.ABS_MAX]; absAxesIDs[NativeDefinitions.ABS_X] = Component.Identifier.Axis.X; absAxesIDs[NativeDefinitions.ABS_Y] = Component.Identifier.Axis.Y; absAxesIDs[NativeDefinitions.ABS_Z] = Component.Identifier.Axis.Z; @@ -685,9 +357,373 @@ public class LinuxNativeTypesMap { absAxesIDs[NativeDefinitions.ABS_TILT_X] = null; absAxesIDs[NativeDefinitions.ABS_TILT_Y] = null; absAxesIDs[NativeDefinitions.ABS_MISC] = null; - } - + + public final static Controller.Type guessButtonTrait(int button_code) { + switch (button_code) { + case NativeDefinitions.BTN_TRIGGER : + case NativeDefinitions.BTN_THUMB : + case NativeDefinitions.BTN_THUMB2 : + case NativeDefinitions.BTN_TOP : + case NativeDefinitions.BTN_TOP2 : + case NativeDefinitions.BTN_PINKIE : + case NativeDefinitions.BTN_BASE : + case NativeDefinitions.BTN_BASE2 : + case NativeDefinitions.BTN_BASE3 : + case NativeDefinitions.BTN_BASE4 : + case NativeDefinitions.BTN_BASE5 : + case NativeDefinitions.BTN_BASE6 : + case NativeDefinitions.BTN_DEAD : + return Controller.Type.STICK; + case NativeDefinitions.BTN_A : + case NativeDefinitions.BTN_B : + case NativeDefinitions.BTN_C : + case NativeDefinitions.BTN_X : + case NativeDefinitions.BTN_Y : + case NativeDefinitions.BTN_Z : + case NativeDefinitions.BTN_TL : + case NativeDefinitions.BTN_TR : + case NativeDefinitions.BTN_TL2 : + case NativeDefinitions.BTN_TR2 : + case NativeDefinitions.BTN_SELECT : + case NativeDefinitions.BTN_MODE : + case NativeDefinitions.BTN_THUMBL : + case NativeDefinitions.BTN_THUMBR : + return Controller.Type.GAMEPAD; + case NativeDefinitions.BTN_0 : + case NativeDefinitions.BTN_1 : + case NativeDefinitions.BTN_2 : + case NativeDefinitions.BTN_3 : + case NativeDefinitions.BTN_4 : + case NativeDefinitions.BTN_5 : + case NativeDefinitions.BTN_6 : + case NativeDefinitions.BTN_7 : + case NativeDefinitions.BTN_8 : + case NativeDefinitions.BTN_9 : + return Controller.Type.UNKNOWN; + case NativeDefinitions.BTN_LEFT : + case NativeDefinitions.BTN_RIGHT : + case NativeDefinitions.BTN_MIDDLE : + case NativeDefinitions.BTN_SIDE : + case NativeDefinitions.BTN_EXTRA : + return Controller.Type.MOUSE; + // case NativeDefinitions.KEY_RESERVED: + case NativeDefinitions.KEY_ESC: + case NativeDefinitions.KEY_1: + case NativeDefinitions.KEY_2: + case NativeDefinitions.KEY_3: + case NativeDefinitions.KEY_4: + case NativeDefinitions.KEY_5: + case NativeDefinitions.KEY_6: + case NativeDefinitions.KEY_7: + case NativeDefinitions.KEY_8: + case NativeDefinitions.KEY_9: + case NativeDefinitions.KEY_0: + case NativeDefinitions.KEY_MINUS: + case NativeDefinitions.KEY_EQUAL: + case NativeDefinitions.KEY_BACKSPACE: + case NativeDefinitions.KEY_TAB: + case NativeDefinitions.KEY_Q: + case NativeDefinitions.KEY_W: + case NativeDefinitions.KEY_E: + case NativeDefinitions.KEY_R: + case NativeDefinitions.KEY_T: + case NativeDefinitions.KEY_Y: + case NativeDefinitions.KEY_U: + case NativeDefinitions.KEY_I: + case NativeDefinitions.KEY_O: + case NativeDefinitions.KEY_P: + case NativeDefinitions.KEY_LEFTBRACE: + case NativeDefinitions.KEY_RIGHTBRACE: + case NativeDefinitions.KEY_ENTER: + case NativeDefinitions.KEY_LEFTCTRL: + case NativeDefinitions.KEY_A: + case NativeDefinitions.KEY_S: + case NativeDefinitions.KEY_D: + case NativeDefinitions.KEY_F: + case NativeDefinitions.KEY_G: + case NativeDefinitions.KEY_H: + case NativeDefinitions.KEY_J: + case NativeDefinitions.KEY_K: + case NativeDefinitions.KEY_L: + case NativeDefinitions.KEY_SEMICOLON: + case NativeDefinitions.KEY_APOSTROPHE: + case NativeDefinitions.KEY_GRAVE: + case NativeDefinitions.KEY_LEFTSHIFT: + case NativeDefinitions.KEY_BACKSLASH: + case NativeDefinitions.KEY_Z: + case NativeDefinitions.KEY_X: + case NativeDefinitions.KEY_C: + case NativeDefinitions.KEY_V: + case NativeDefinitions.KEY_B: + case NativeDefinitions.KEY_N: + case NativeDefinitions.KEY_M: + case NativeDefinitions.KEY_COMMA: + case NativeDefinitions.KEY_DOT: + case NativeDefinitions.KEY_SLASH: + case NativeDefinitions.KEY_RIGHTSHIFT: + case NativeDefinitions.KEY_KPASTERISK: + case NativeDefinitions.KEY_LEFTALT: + case NativeDefinitions.KEY_SPACE: + case NativeDefinitions.KEY_CAPSLOCK: + case NativeDefinitions.KEY_F1: + case NativeDefinitions.KEY_F2: + case NativeDefinitions.KEY_F3: + case NativeDefinitions.KEY_F4: + case NativeDefinitions.KEY_F5: + case NativeDefinitions.KEY_F6: + case NativeDefinitions.KEY_F7: + case NativeDefinitions.KEY_F8: + case NativeDefinitions.KEY_F9: + case NativeDefinitions.KEY_F10: + case NativeDefinitions.KEY_NUMLOCK: + case NativeDefinitions.KEY_SCROLLLOCK: + case NativeDefinitions.KEY_KP7: + case NativeDefinitions.KEY_KP8: + case NativeDefinitions.KEY_KP9: + case NativeDefinitions.KEY_KPMINUS: + case NativeDefinitions.KEY_KP4: + case NativeDefinitions.KEY_KP5: + case NativeDefinitions.KEY_KP6: + case NativeDefinitions.KEY_KPPLUS: + case NativeDefinitions.KEY_KP1: + case NativeDefinitions.KEY_KP2: + case NativeDefinitions.KEY_KP3: + case NativeDefinitions.KEY_KP0: + case NativeDefinitions.KEY_KPDOT: + case NativeDefinitions.KEY_ZENKAKUHANKAKU: + case NativeDefinitions.KEY_102ND: + case NativeDefinitions.KEY_F11: + case NativeDefinitions.KEY_F12: + case NativeDefinitions.KEY_RO: + case NativeDefinitions.KEY_KATAKANA: + case NativeDefinitions.KEY_HIRAGANA: + case NativeDefinitions.KEY_HENKAN: + case NativeDefinitions.KEY_KATAKANAHIRAGANA: + case NativeDefinitions.KEY_MUHENKAN: + case NativeDefinitions.KEY_KPJPCOMMA: + case NativeDefinitions.KEY_KPENTER: + case NativeDefinitions.KEY_RIGHTCTRL: + case NativeDefinitions.KEY_KPSLASH: + case NativeDefinitions.KEY_SYSRQ: + case NativeDefinitions.KEY_RIGHTALT: + case NativeDefinitions.KEY_LINEFEED: + case NativeDefinitions.KEY_HOME: + case NativeDefinitions.KEY_UP: + case NativeDefinitions.KEY_PAGEUP: + case NativeDefinitions.KEY_LEFT: + case NativeDefinitions.KEY_RIGHT: + case NativeDefinitions.KEY_END: + case NativeDefinitions.KEY_DOWN: + case NativeDefinitions.KEY_PAGEDOWN: + case NativeDefinitions.KEY_INSERT: + case NativeDefinitions.KEY_DELETE: + case NativeDefinitions.KEY_MACRO: + case NativeDefinitions.KEY_MUTE: + case NativeDefinitions.KEY_VOLUMEDOWN: + case NativeDefinitions.KEY_VOLUMEUP: + case NativeDefinitions.KEY_POWER: + case NativeDefinitions.KEY_KPEQUAL: + case NativeDefinitions.KEY_KPPLUSMINUS: + case NativeDefinitions.KEY_PAUSE: + case NativeDefinitions.KEY_KPCOMMA: + case NativeDefinitions.KEY_HANGUEL: + case NativeDefinitions.KEY_HANJA: + case NativeDefinitions.KEY_YEN: + case NativeDefinitions.KEY_LEFTMETA: + case NativeDefinitions.KEY_RIGHTMETA: + case NativeDefinitions.KEY_COMPOSE: + case NativeDefinitions.KEY_STOP: + case NativeDefinitions.KEY_AGAIN: + case NativeDefinitions.KEY_PROPS: + case NativeDefinitions.KEY_UNDO: + case NativeDefinitions.KEY_FRONT: + case NativeDefinitions.KEY_COPY: + case NativeDefinitions.KEY_OPEN: + case NativeDefinitions.KEY_PASTE: + case NativeDefinitions.KEY_FIND: + case NativeDefinitions.KEY_CUT: + case NativeDefinitions.KEY_HELP: + case NativeDefinitions.KEY_MENU: + case NativeDefinitions.KEY_CALC: + case NativeDefinitions.KEY_SETUP: + case NativeDefinitions.KEY_SLEEP: + case NativeDefinitions.KEY_WAKEUP: + case NativeDefinitions.KEY_FILE: + case NativeDefinitions.KEY_SENDFILE: + case NativeDefinitions.KEY_DELETEFILE: + case NativeDefinitions.KEY_XFER: + case NativeDefinitions.KEY_PROG1: + case NativeDefinitions.KEY_PROG2: + case NativeDefinitions.KEY_WWW: + case NativeDefinitions.KEY_MSDOS: + case NativeDefinitions.KEY_COFFEE: + case NativeDefinitions.KEY_DIRECTION: + case NativeDefinitions.KEY_CYCLEWINDOWS: + case NativeDefinitions.KEY_MAIL: + case NativeDefinitions.KEY_BOOKMARKS: + case NativeDefinitions.KEY_COMPUTER: + case NativeDefinitions.KEY_BACK: + case NativeDefinitions.KEY_FORWARD: + case NativeDefinitions.KEY_CLOSECD: + case NativeDefinitions.KEY_EJECTCD: + case NativeDefinitions.KEY_EJECTCLOSECD: + case NativeDefinitions.KEY_NEXTSONG: + case NativeDefinitions.KEY_PLAYPAUSE: + case NativeDefinitions.KEY_PREVIOUSSONG: + case NativeDefinitions.KEY_STOPCD: + case NativeDefinitions.KEY_RECORD: + case NativeDefinitions.KEY_REWIND: + case NativeDefinitions.KEY_PHONE: + case NativeDefinitions.KEY_ISO: + case NativeDefinitions.KEY_CONFIG: + case NativeDefinitions.KEY_HOMEPAGE: + case NativeDefinitions.KEY_REFRESH: + case NativeDefinitions.KEY_EXIT: + case NativeDefinitions.KEY_MOVE: + case NativeDefinitions.KEY_EDIT: + case NativeDefinitions.KEY_SCROLLUP: + case NativeDefinitions.KEY_SCROLLDOWN: + case NativeDefinitions.KEY_KPLEFTPAREN: + case NativeDefinitions.KEY_KPRIGHTPAREN: + case NativeDefinitions.KEY_F13: + case NativeDefinitions.KEY_F14: + case NativeDefinitions.KEY_F15: + case NativeDefinitions.KEY_F16: + case NativeDefinitions.KEY_F17: + case NativeDefinitions.KEY_F18: + case NativeDefinitions.KEY_F19: + case NativeDefinitions.KEY_F20: + case NativeDefinitions.KEY_F21: + case NativeDefinitions.KEY_F22: + case NativeDefinitions.KEY_F23: + case NativeDefinitions.KEY_F24: + case NativeDefinitions.KEY_PLAYCD: + case NativeDefinitions.KEY_PAUSECD: + case NativeDefinitions.KEY_PROG3: + case NativeDefinitions.KEY_PROG4: + case NativeDefinitions.KEY_SUSPEND: + case NativeDefinitions.KEY_CLOSE: + case NativeDefinitions.KEY_PLAY: + case NativeDefinitions.KEY_FASTFORWARD: + case NativeDefinitions.KEY_BASSBOOST: + case NativeDefinitions.KEY_PRINT: + case NativeDefinitions.KEY_HP: + case NativeDefinitions.KEY_CAMERA: + case NativeDefinitions.KEY_SOUND: + case NativeDefinitions.KEY_QUESTION: + case NativeDefinitions.KEY_EMAIL: + case NativeDefinitions.KEY_CHAT: + case NativeDefinitions.KEY_SEARCH: + case NativeDefinitions.KEY_CONNECT: + case NativeDefinitions.KEY_FINANCE: + case NativeDefinitions.KEY_SPORT: + case NativeDefinitions.KEY_SHOP: + case NativeDefinitions.KEY_ALTERASE: + case NativeDefinitions.KEY_CANCEL: + case NativeDefinitions.KEY_BRIGHTNESSDOWN: + case NativeDefinitions.KEY_BRIGHTNESSUP: + case NativeDefinitions.KEY_MEDIA: + case NativeDefinitions.KEY_SWITCHVIDEOMODE: + case NativeDefinitions.KEY_KBDILLUMTOGGLE: + case NativeDefinitions.KEY_KBDILLUMDOWN: + case NativeDefinitions.KEY_KBDILLUMUP: + // case NativeDefinitions.KEY_UNKNOWN: + case NativeDefinitions.KEY_OK: + case NativeDefinitions.KEY_SELECT: + case NativeDefinitions.KEY_GOTO: + case NativeDefinitions.KEY_CLEAR: + case NativeDefinitions.KEY_POWER2: + case NativeDefinitions.KEY_OPTION: + case NativeDefinitions.KEY_INFO: + case NativeDefinitions.KEY_TIME: + case NativeDefinitions.KEY_VENDOR: + case NativeDefinitions.KEY_ARCHIVE: + case NativeDefinitions.KEY_PROGRAM: + case NativeDefinitions.KEY_CHANNEL: + case NativeDefinitions.KEY_FAVORITES: + case NativeDefinitions.KEY_EPG: + case NativeDefinitions.KEY_PVR: + case NativeDefinitions.KEY_MHP: + case NativeDefinitions.KEY_LANGUAGE: + case NativeDefinitions.KEY_TITLE: + case NativeDefinitions.KEY_SUBTITLE: + case NativeDefinitions.KEY_ANGLE: + case NativeDefinitions.KEY_ZOOM: + case NativeDefinitions.KEY_MODE: + case NativeDefinitions.KEY_KEYBOARD: + case NativeDefinitions.KEY_SCREEN: + case NativeDefinitions.KEY_PC: + case NativeDefinitions.KEY_TV: + case NativeDefinitions.KEY_TV2: + case NativeDefinitions.KEY_VCR: + case NativeDefinitions.KEY_VCR2: + case NativeDefinitions.KEY_SAT: + case NativeDefinitions.KEY_SAT2: + case NativeDefinitions.KEY_CD: + case NativeDefinitions.KEY_TAPE: + case NativeDefinitions.KEY_RADIO: + case NativeDefinitions.KEY_TUNER: + case NativeDefinitions.KEY_PLAYER: + case NativeDefinitions.KEY_TEXT: + case NativeDefinitions.KEY_DVD: + case NativeDefinitions.KEY_AUX: + case NativeDefinitions.KEY_MP3: + case NativeDefinitions.KEY_AUDIO: + case NativeDefinitions.KEY_VIDEO: + case NativeDefinitions.KEY_DIRECTORY: + case NativeDefinitions.KEY_LIST: + case NativeDefinitions.KEY_MEMO: + case NativeDefinitions.KEY_CALENDAR: + case NativeDefinitions.KEY_RED: + case NativeDefinitions.KEY_GREEN: + case NativeDefinitions.KEY_YELLOW: + case NativeDefinitions.KEY_BLUE: + case NativeDefinitions.KEY_CHANNELUP: + case NativeDefinitions.KEY_CHANNELDOWN: + case NativeDefinitions.KEY_FIRST: + case NativeDefinitions.KEY_LAST: + case NativeDefinitions.KEY_AB: + case NativeDefinitions.KEY_NEXT: + case NativeDefinitions.KEY_RESTART: + case NativeDefinitions.KEY_SLOW: + case NativeDefinitions.KEY_SHUFFLE: + case NativeDefinitions.KEY_BREAK: + case NativeDefinitions.KEY_PREVIOUS: + case NativeDefinitions.KEY_DIGITS: + case NativeDefinitions.KEY_TEEN: + case NativeDefinitions.KEY_TWEN: + case NativeDefinitions.KEY_DEL_EOL: + case NativeDefinitions.KEY_DEL_EOS: + case NativeDefinitions.KEY_INS_LINE: + case NativeDefinitions.KEY_DEL_LINE: + case NativeDefinitions.KEY_FN: + case NativeDefinitions.KEY_FN_ESC: + case NativeDefinitions.KEY_FN_F1: + case NativeDefinitions.KEY_FN_F2: + case NativeDefinitions.KEY_FN_F3: + case NativeDefinitions.KEY_FN_F4: + case NativeDefinitions.KEY_FN_F5: + case NativeDefinitions.KEY_FN_F6: + case NativeDefinitions.KEY_FN_F7: + case NativeDefinitions.KEY_FN_F8: + case NativeDefinitions.KEY_FN_F9: + case NativeDefinitions.KEY_FN_F10: + case NativeDefinitions.KEY_FN_F11: + case NativeDefinitions.KEY_FN_F12: + case NativeDefinitions.KEY_FN_1: + case NativeDefinitions.KEY_FN_2: + case NativeDefinitions.KEY_FN_D: + case NativeDefinitions.KEY_FN_E: + case NativeDefinitions.KEY_FN_F: + case NativeDefinitions.KEY_FN_S: + case NativeDefinitions.KEY_FN_B: + return Controller.Type.KEYBOARD; + default: + return Controller.Type.UNKNOWN; + } + } + /** Return port type from a native port type int id * @param nativeid The native port type * @return The jinput port type @@ -710,45 +746,6 @@ public class LinuxNativeTypesMap { } } - /** Returns the name of a native button - * @param nativeID The native button type id - * @return The button name - */ - public static String getButtonName(int nativeID) { - String retval = INSTANCE.keyNames[nativeID]; - //if(retval == null){ - // retval = "Unknown button id"; - // INSTANCE.keyNames[nativeID] = retval; - //} - return retval; - } - - /** Retursn the name of the native relative axis - * @param nativeID The axis type ID - * @return The axis name - */ - public static String getRelAxisName(int nativeID) { - String retval = INSTANCE.relAxesNames[nativeID]; - if(retval == null) { - retval = "Unknown relative axis id"; - INSTANCE.relAxesNames[nativeID] = retval; - } - return retval; - } - - /** Retursn the name of the native absolute axis - * @param nativeID The native axis type ID - * @return The name of the axis - */ - public static String getAbsAxisName(int nativeID) { - String retval = INSTANCE.absAxesNames[nativeID]; - if(retval == null) { - retval = "Unknown absolute axis id " + nativeID; - INSTANCE.absAxesNames[nativeID] = retval; - } - return retval; - } - /** Gets the identifier for a relative axis * @param nativeID The axis type ID * @return The jinput id @@ -793,5 +790,4 @@ public class LinuxNativeTypesMap { } return retval; } - } diff --git a/plugins/linux/src/java/net/java/games/input/LinuxPOV.java b/plugins/linux/src/java/net/java/games/input/LinuxPOV.java new file mode 100644 index 0000000..7e62501 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxPOV.java @@ -0,0 +1,95 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Represents a linux button +* @author elias +* @version 1.0 +*/ +final class LinuxPOV extends LinuxComponent { + private final LinuxEventComponent component_x; + private final LinuxEventComponent component_y; + + private float last_x; + private float last_y; + + public LinuxPOV(LinuxEventComponent component_x, LinuxEventComponent component_y) { + super(component_x); + this.component_x = component_x; + this.component_y = component_y; + } + + protected final float poll() throws IOException { + last_x = LinuxControllers.poll(component_x); + last_y = LinuxControllers.poll(component_y); + return convertValue(0f, null); + } + + public float convertValue(float value, LinuxAxisDescriptor descriptor) { + if (descriptor == component_x.getDescriptor()) + last_x = value; + if (descriptor == component_y.getDescriptor()) + last_y = value; + + if (last_x == -1 && last_y == -1) + return Component.POV.UP_LEFT; + else if (last_x == -1 && last_y == 0) + return Component.POV.LEFT; + else if (last_x == -1 && last_y == 1) + return Component.POV.DOWN_LEFT; + else if (last_x == 0 && last_y == -1) + return Component.POV.UP; + else if (last_x == 0 && last_y == 0) + return Component.POV.OFF; + else if (last_x == 0 && last_y == 1) + return Component.POV.DOWN; + else if (last_x == 1 && last_y == -1) + return Component.POV.UP_RIGHT; + else if (last_x == 1 && last_y == 0) + return Component.POV.RIGHT; + else if (last_x == 1 && last_y == 1) + return Component.POV.DOWN_RIGHT; + else { + ControllerEnvironment.logln("Unknown values x = " + last_x + " | y = " + last_y); + return Component.POV.OFF; + } + } +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxRumbleFF.java b/plugins/linux/src/java/net/java/games/input/LinuxRumbleFF.java new file mode 100644 index 0000000..e76bd31 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxRumbleFF.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 Jeremy Booth ([email protected]) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * The name of the author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + */ +package net.java.games.input; + +import java.io.IOException; + +/** + * @author elias + */ +final class LinuxRumbleFF extends LinuxForceFeedbackEffect { + public LinuxRumbleFF(LinuxEventDevice device) throws IOException { + super(device); + } + + protected final int upload(int id, float intensity) throws IOException { + int weak_magnitude; + int strong_magnitude; + if (intensity > 0.666666f) { + strong_magnitude = (int)(0x8000*intensity); + weak_magnitude = (int)(0xc000*intensity); + } else if (intensity > 0.3333333f) { + strong_magnitude = (int)(0x8000*intensity); + weak_magnitude = (int)(0xc000*0); + } else { + strong_magnitude = (int)(0x8000*0); + weak_magnitude = (int)(0xc000*intensity); + } + + return getDevice().uploadRumbleEffect(id, 0, 0, 0, 0, 0, strong_magnitude, weak_magnitude); + } +} diff --git a/plugins/linux/src/java/net/java/games/input/NativeDefinitions.java b/plugins/linux/src/java/net/java/games/input/NativeDefinitions.java index b7a17ff..efb644a 100644 --- a/plugins/linux/src/java/net/java/games/input/NativeDefinitions.java +++ b/plugins/linux/src/java/net/java/games/input/NativeDefinitions.java @@ -4,7 +4,20 @@ package net.java.games.input; /** * This file is generated from /usr/include/linux/input.h please do not edit */ -public class NativeDefinitions { +class NativeDefinitions { + public static final int EV_VERSION = 0x010001; + public static final int EV_SYN = 0x00; + public static final int EV_KEY = 0x01; + public static final int EV_REL = 0x02; + public static final int EV_ABS = 0x03; + public static final int EV_MSC = 0x04; + public static final int EV_LED = 0x11; + public static final int EV_SND = 0x12; + public static final int EV_REP = 0x14; + public static final int EV_FF = 0x15; + public static final int EV_PWR = 0x16; + public static final int EV_FF_STATUS = 0x17; + public static final int EV_MAX = 0x1f; public static final int KEY_RESERVED = 0; public static final int KEY_ESC = 1; public static final int KEY_1 = 2; @@ -89,18 +102,17 @@ public class NativeDefinitions { public static final int KEY_KP3 = 81; public static final int KEY_KP0 = 82; public static final int KEY_KPDOT = 83; - public static final int KEY_103RD = 84; - public static final int KEY_F13 = 85; + public static final int KEY_ZENKAKUHANKAKU = 85; public static final int KEY_102ND = 86; public static final int KEY_F11 = 87; public static final int KEY_F12 = 88; - public static final int KEY_F14 = 89; - public static final int KEY_F15 = 90; - public static final int KEY_F16 = 91; - public static final int KEY_F17 = 92; - public static final int KEY_F18 = 93; - public static final int KEY_F19 = 94; - public static final int KEY_F20 = 95; + public static final int KEY_RO = 89; + public static final int KEY_KATAKANA = 90; + public static final int KEY_HIRAGANA = 91; + public static final int KEY_HENKAN = 92; + public static final int KEY_KATAKANAHIRAGANA = 93; + public static final int KEY_MUHENKAN = 94; + public static final int KEY_KPJPCOMMA = 95; public static final int KEY_KPENTER = 96; public static final int KEY_RIGHTCTRL = 97; public static final int KEY_KPSLASH = 98; @@ -125,11 +137,10 @@ public class NativeDefinitions { public static final int KEY_KPEQUAL = 117; public static final int KEY_KPPLUSMINUS = 118; public static final int KEY_PAUSE = 119; - public static final int KEY_F21 = 120; - public static final int KEY_F22 = 121; - public static final int KEY_F23 = 122; - public static final int KEY_F24 = 123; - public static final int KEY_KPCOMMA = 124; + public static final int KEY_KPCOMMA = 121; + public static final int KEY_HANGUEL = 122; + public static final int KEY_HANJA = 123; + public static final int KEY_YEN = 124; public static final int KEY_LEFTMETA = 125; public static final int KEY_RIGHTMETA = 126; public static final int KEY_COMPOSE = 127; @@ -186,24 +197,18 @@ public class NativeDefinitions { public static final int KEY_SCROLLDOWN = 178; public static final int KEY_KPLEFTPAREN = 179; public static final int KEY_KPRIGHTPAREN = 180; - public static final int KEY_INTL1 = 181; - public static final int KEY_INTL2 = 182; - public static final int KEY_INTL3 = 183; - public static final int KEY_INTL4 = 184; - public static final int KEY_INTL5 = 185; - public static final int KEY_INTL6 = 186; - public static final int KEY_INTL7 = 187; - public static final int KEY_INTL8 = 188; - public static final int KEY_INTL9 = 189; - public static final int KEY_LANG1 = 190; - public static final int KEY_LANG2 = 191; - public static final int KEY_LANG3 = 192; - public static final int KEY_LANG4 = 193; - public static final int KEY_LANG5 = 194; - public static final int KEY_LANG6 = 195; - public static final int KEY_LANG7 = 196; - public static final int KEY_LANG8 = 197; - public static final int KEY_LANG9 = 198; + public static final int KEY_F13 = 183; + public static final int KEY_F14 = 184; + public static final int KEY_F15 = 185; + public static final int KEY_F16 = 186; + public static final int KEY_F17 = 187; + public static final int KEY_F18 = 188; + public static final int KEY_F19 = 189; + public static final int KEY_F20 = 190; + public static final int KEY_F21 = 191; + public static final int KEY_F22 = 192; + public static final int KEY_F23 = 193; + public static final int KEY_F24 = 194; public static final int KEY_PLAYCD = 200; public static final int KEY_PAUSECD = 201; public static final int KEY_PROG3 = 202; @@ -230,6 +235,10 @@ public class NativeDefinitions { public static final int KEY_BRIGHTNESSDOWN = 224; public static final int KEY_BRIGHTNESSUP = 225; public static final int KEY_MEDIA = 226; + public static final int KEY_SWITCHVIDEOMODE = 227; + public static final int KEY_KBDILLUMTOGGLE = 228; + public static final int KEY_KBDILLUMDOWN = 229; + public static final int KEY_KBDILLUMUP = 230; public static final int KEY_UNKNOWN = 240; public static final int BTN_MISC = 0x100; public static final int BTN_0 = 0x100; @@ -366,10 +375,34 @@ public class NativeDefinitions { public static final int KEY_DEL_EOS = 0x1c1; public static final int KEY_INS_LINE = 0x1c2; public static final int KEY_DEL_LINE = 0x1c3; + public static final int KEY_FN = 0x1d0; + public static final int KEY_FN_ESC = 0x1d1; + public static final int KEY_FN_F1 = 0x1d2; + public static final int KEY_FN_F2 = 0x1d3; + public static final int KEY_FN_F3 = 0x1d4; + public static final int KEY_FN_F4 = 0x1d5; + public static final int KEY_FN_F5 = 0x1d6; + public static final int KEY_FN_F6 = 0x1d7; + public static final int KEY_FN_F7 = 0x1d8; + public static final int KEY_FN_F8 = 0x1d9; + public static final int KEY_FN_F9 = 0x1da; + public static final int KEY_FN_F10 = 0x1db; + public static final int KEY_FN_F11 = 0x1dc; + public static final int KEY_FN_F12 = 0x1dd; + public static final int KEY_FN_1 = 0x1de; + public static final int KEY_FN_2 = 0x1df; + public static final int KEY_FN_D = 0x1e0; + public static final int KEY_FN_E = 0x1e1; + public static final int KEY_FN_F = 0x1e2; + public static final int KEY_FN_S = 0x1e3; + public static final int KEY_FN_B = 0x1e4; public static final int KEY_MAX = 0x1ff; public static final int REL_X = 0x00; public static final int REL_Y = 0x01; public static final int REL_Z = 0x02; + public static final int REL_RX = 0x03; + public static final int REL_RY = 0x04; + public static final int REL_RZ = 0x05; public static final int REL_HWHEEL = 0x06; public static final int REL_DIAL = 0x07; public static final int REL_WHEEL = 0x08; @@ -402,10 +435,16 @@ public class NativeDefinitions { public static final int ABS_VOLUME = 0x20; public static final int ABS_MISC = 0x28; public static final int ABS_MAX = 0x3f; + public static final int USAGE_MOUSE = 0x00; + public static final int USAGE_JOYSTICK = 0x01; + public static final int USAGE_GAMEPAD = 0x02; + public static final int USAGE_KEYBOARD = 0x03; + public static final int USAGE_MAX = 0x0f; public static final int BUS_PCI = 0x01; public static final int BUS_ISAPNP = 0x02; public static final int BUS_USB = 0x03; public static final int BUS_HIL = 0x04; + public static final int BUS_BLUETOOTH = 0x05; public static final int BUS_ISA = 0x10; public static final int BUS_I8042 = 0x11; public static final int BUS_XTKBD = 0x12; @@ -416,4 +455,24 @@ public class NativeDefinitions { public static final int BUS_ADB = 0x17; public static final int BUS_I2C = 0x18; public static final int BUS_HOST = 0x19; + public static final int FF_STATUS_STOPPED = 0x00; + public static final int FF_STATUS_PLAYING = 0x01; + public static final int FF_STATUS_MAX = 0x01; + public static final int FF_RUMBLE = 0x50; + public static final int FF_PERIODIC = 0x51; + public static final int FF_CONSTANT = 0x52; + public static final int FF_SPRING = 0x53; + public static final int FF_FRICTION = 0x54; + public static final int FF_DAMPER = 0x55; + public static final int FF_INERTIA = 0x56; + public static final int FF_RAMP = 0x57; + public static final int FF_SQUARE = 0x58; + public static final int FF_TRIANGLE = 0x59; + public static final int FF_SINE = 0x5a; + public static final int FF_SAW_UP = 0x5b; + public static final int FF_SAW_DOWN = 0x5c; + public static final int FF_CUSTOM = 0x5d; + public static final int FF_GAIN = 0x60; + public static final int FF_AUTOCENTER = 0x61; + public static final int FF_MAX = 0x7f; } diff --git a/plugins/linux/src/native/Device.h b/plugins/linux/src/native/Device.h deleted file mode 100644 index 61fe621..0000000 --- a/plugins/linux/src/native/Device.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#if !defined(eventInterface_Device_h) -#define eventInterface_Device_h - -/** - * Simple abstract device class - * - * @author Jeremy Booth ([email protected]) - */ -class Device { - - private: - - public: - /** Maximum name length for a device */ - const static int MAX_NAME_LENGTH = 256; - /** Return the number of relative axes for this device */ - virtual int getNumberRelAxes() = 0; - /** Return the number ofr absolute axes for this device */ - virtual int getNumberAbsAxes() = 0; - /** Return the number of buttons for this device */ - virtual int getNumberButtons() = 0; - /** Get the name of this device */ - virtual const char *getName() = 0; - /** get teh bus type */ - virtual int getBusType() = 0; - virtual int getVendorID() = 0; - virtual int getProductID() = 0; - virtual int getVersion() = 0; - /** Get the supported axes/button maps */ - virtual void getSupportedRelAxes(int supportedAxis[]) = 0; - virtual void getSupportedAbsAxes(int supportedAxis[]) = 0; - virtual void getSupportedButtons(int supportedButtons[]) = 0; - /** poll it */ - virtual int poll() = 0; - /** get the data */ - virtual void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]) = 0; - /** Get axis details */ - virtual int getAbsAxisMinimum(int axisNumber) = 0; - virtual int getAbsAxisMaximum(int axisNumber) = 0; - virtual int getAbsAxisFuzz(int axisNumber) = 0; - virtual bool getFFEnabled() = 0; - virtual void rumble(float force) = 0; - virtual void cleanup() = 0; -}; - -#endif //eventInterface_Device_h diff --git a/plugins/linux/src/native/EventDevice.cpp b/plugins/linux/src/native/EventDevice.cpp deleted file mode 100644 index b77f2b7..0000000 --- a/plugins/linux/src/native/EventDevice.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#include "eventInterfaceTypes.h" -#include "EventDevice.h" -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <linux/input.h> -#include <malloc.h> -#include <errno.h> - -#include "logger.h" - -EventDevice::EventDevice(char *deviceFileName) { - char tempName[Device::MAX_NAME_LENGTH-1] = "Unknown"; - int i; - - fd = open(deviceFileName, O_RDWR | O_NONBLOCK); - if(fd<0) { - - char errorMessage[512]; - sprintf(errorMessage, "Error opening device %s read/write, Force Feedback disabled for this device\n", deviceFileName); - perror(errorMessage); - - fd = open(deviceFileName, O_RDONLY | O_NONBLOCK); - if(fd<0) { - /*char errorMessage[512]; - sprintf(errorMessage, "Error opening device %s\n", deviceFileName); - perror(errorMessage);*/ - inited = 0; - return; - } - } else { - if(ioctl(fd, EVIOCGBIT(EV_FF, sizeof(uint8_t) * 16), ff_bitmask) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - if(getBit(FF_RUMBLE, ff_bitmask)==1) { - ffSupported = 1; - //LOG_TRACE("Force feedback supported for %s\n", deviceFileName); - int n_effects = 0; - if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) { - char errorMessage[512]; - sprintf(errorMessage, "Failed to get number of effects for device %s\n", deviceFileName); - perror(errorMessage); - } - LOG_TRACE("Device %s supports %d simultanious effects\n", deviceFileName, n_effects); - - effect_playing = false; - effect.type=FF_RUMBLE; - effect.id=-1; - effect.u.rumble.strong_magnitude = (int)(0x8000); - effect.u.rumble.weak_magnitude = (int)(0xc000); - effect.replay.length = 5000; - effect.replay.delay = 0; - LOG_TRACE("Uploading effect %d\n", effect.id); - if (ioctl(fd, EVIOCSFF, &effect) == -1) { - perror("Upload effect"); - } - LOG_TRACE("Uploaded effect %d\n", effect.id); - - - } else { - ffSupported = 0; - LOG_TRACE("Force feedback not supported for %s %d\n", deviceFileName, getBit(FF_RUMBLE, ff_bitmask)); - } - } - - if(ioctl(fd, EVIOCGNAME(sizeof(tempName)), tempName) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - - int namelength=strlen(tempName); - name = (char *)malloc(namelength+1); - strncpy(name,tempName, namelength+1); - - LOG_TRACE("Device name for device file %s is %s\n", deviceFileName, name); - - uint8_t evtype_bitmask[EV_MAX/8 + 1]; - memset(evtype_bitmask, 0, sizeof(evtype_bitmask)); - - if(ioctl(fd, EVIOCGBIT(0, EV_MAX), evtype_bitmask) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - - struct input_devinfo deviceInfo; - if(ioctl(fd, EVIOCGID, &deviceInfo) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - - bustype = deviceInfo.bustype; - vendor = deviceInfo.vendor; - product = deviceInfo.product; - version = deviceInfo.version; - - numButtons = -1; - numAbsAxes = -1; - numRelAxes = -1; - - if(!(getBit(EV_KEY, evtype_bitmask))) { - numButtons = 0; - } - if(!(getBit(EV_REL, evtype_bitmask))) { - numRelAxes = 0; - } - - if(!(getBit(EV_ABS, evtype_bitmask))) { - numAbsAxes = 0; - } - - if(!getBit(EV_FF, evtype_bitmask)) { - ffSupported = 0; - } - - if(numButtons < 0) { - // This device supports keys, deal with it. - if(ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - for(i=0;i<KEY_MAX;i++) { - buttonLookup[i]=-1; - } - short tempSupportedButtons[KEY_MAX]; - numButtons = 0; - for(i=0;i<KEY_MAX;i++) { - if(getBit(i,key_bitmask)) { - tempSupportedButtons[numButtons] = i; - numButtons++; - } - } - supportedButtons = (short *)malloc(numButtons * sizeof(short)); - buttonData = (uint8_t *)malloc(numButtons * sizeof(uint8_t)); - for(i=0;i<numButtons;i++) { - buttonData[i] = 0; - supportedButtons[i] = tempSupportedButtons[i]; - buttonLookup[supportedButtons[i]] = i; - } - } - - if(numRelAxes < 0) { - // This device supports axes, deal with it. - if(ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - for(i=0;i<REL_MAX;i++) { - relAxisLookup[i]=-1; - } - short tempSupportedAxes[REL_MAX]; - numRelAxes=0; - for(i=0;i<REL_MAX;i++) { - if(getBit(i,rel_bitmask)) { - tempSupportedAxes[numRelAxes] = i; - numRelAxes++; - } - } - relAxesData = (int *)malloc(numRelAxes * sizeof(int)); - supportedRelAxes = (short *)malloc(numRelAxes * sizeof(short)); - for(i=0;i<numRelAxes;i++) { - relAxesData[i]=0; - supportedRelAxes[i] = tempSupportedAxes[i]; - relAxisLookup[supportedRelAxes[i]] = i; - } - } - - - if(numAbsAxes < 0) { - if(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - for(i=0;i<ABS_MAX;i++) { - absAxisLookup[i] = -1; - } - short tempSupportedAxes[ABS_MAX]; - numAbsAxes=0; - for(i=0;i<ABS_MAX;i++) { - if(getBit(i,abs_bitmask)) { - tempSupportedAxes[numAbsAxes] = i; - numAbsAxes++; - } - } - - absAxesData = (int *)malloc(numAbsAxes * sizeof(int)); - supportedAbsAxes = (short *)malloc(numAbsAxes * sizeof(short)); - for(i=0;i<numAbsAxes;i++) { - supportedAbsAxes[i] = tempSupportedAxes[i]; - absAxisLookup[supportedAbsAxes[i]] = i; - } - - abs_features = (struct input_absinfo *)malloc(numAbsAxes * sizeof(struct input_absinfo)); - for(i=0;i<numAbsAxes;i++) { - if(ioctl(fd, EVIOCGABS(supportedAbsAxes[i]), &(abs_features[i]))) { - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - absAxesData[i] = abs_features[i].value; - } - } - - inited = 1; -} - -int EventDevice::isValidDevice() { - return inited; -} - -int EventDevice::getNumberRelAxes(){ - if(inited!=1) return -1; - return numRelAxes; -} - -int EventDevice::getNumberAbsAxes(){ - if(inited!=1) return -1; - return numAbsAxes; -} - -int EventDevice::getNumberButtons(){ - if(inited!=1) return -1; - return numButtons; -} - -const char *EventDevice::getName(){ - LOG_TRACE("EventDevice::getName()\n"); - return name; -} - -int EventDevice::getBusType(){ - if(inited!=1) return -1; - return bustype; -} - -int EventDevice::getVendorID(){ - if(inited!=1) return -1; - return vendor; -} - -int EventDevice::getProductID(){ - if(inited!=1) return -1; - return product; -} - -int EventDevice::getVersion(){ - if(inited!=1) return -1; - return version; -} - -void EventDevice::getSupportedRelAxes(int supportedAxis[]){ - int i; - - if(inited!=1) return; - for(i=0;i<numRelAxes; i++) { - (supportedAxis)[i] = supportedRelAxes[i]; - } -} - -void EventDevice::getSupportedAbsAxes(int supportedAxis[]){ - int i; - - if(inited!=1) return; - for(i=0;i<numAbsAxes; i++) { - (supportedAxis)[i] = supportedAbsAxes[i]; - } -} - -void EventDevice::getSupportedButtons(int supportedButtons[]){ - int i; - - if(inited!=1) return; - for(i=0;i<numButtons; i++) { - (supportedButtons)[i] = this->supportedButtons[i]; - } -} - -/** - * A return value of -1 means error, 0 means ok, but no change - * a return of >0 means the data for this device has changed - */ -int EventDevice::poll(){ - size_t read_bytes; - struct input_event events[64]; - int dataChanged=0; - - if(inited!=1) return -1; - - // first thing to do is reset all relative axis as mice never seem to do it - int i; - for(i=0;i<numRelAxes;i++){ - if(relAxesData[i]!=0) { - dataChanged=1; - relAxesData[i]=0; - } - } - - read_bytes = read(fd, events, sizeof(struct input_event) * 64); - - if(read_bytes == 0) { - // no sweat, just return; - return 0; - } - - if(read_bytes == -1) { - if(errno == EAGAIN) { - // No worries, we are in non blocking and noting is ready - return 0; - } else { - perror("Error reading events: "); - return -1; - } - } - - if (read_bytes < (int) sizeof(struct input_event)) { - perror("Error reading events: "); - return -1; - } - - int numEventsRead = (int) (read_bytes / sizeof(struct input_event)); - for(i=0;i<numEventsRead;i++) { - switch(events[i].type) { - case EV_SYN: - case EV_MSC: - // not sure what to do with it, ignore for now -- JPK - break; - case EV_KEY: { - dataChanged = 1; - int buttonIndex = buttonLookup[events[i].code]; - buttonData[buttonIndex] = events[i].value; - //printf("button %d translates to button %d on this device\n", events[i].code, buttonIndex); - break; - } - case EV_REL: { - dataChanged = 1; - int axisIndex = relAxisLookup[events[i].code]; - relAxesData[axisIndex] += events[i].value; - //printf("rel axis %d translates to rel axis %d on this device\n", events[i].code, axisIndex); - break; - } - case EV_ABS: { - dataChanged = 1; - int axisIndex = absAxisLookup[events[i].code]; - absAxesData[axisIndex] = events[i].value; - //printf("abs axis %d translates to abs axis %d on this device\n", events[i].code, axisIndex); - break; - } - case EV_LED: - // reveiced for things like numlock led change - break; - default: - fprintf(stderr, "Received event of type 0x%02X from %s, which I wasn't expecting, please report it to jinput forum at www.javagaming.org\n", events[i].type, name); - } - } - return dataChanged; -} - -void EventDevice::getPolledData(int relAxesData[], int absAxesData[], int buttonData[]){ - int i; - - if(inited!=1) return; - for(i=0;i<numRelAxes;i++) { - (relAxesData)[i] = this->relAxesData[i]; - } - for(i=0;i<numAbsAxes;i++) { - (absAxesData)[i] = this->absAxesData[i]; - } - for(i=0;i<numButtons;i++) { - (buttonData)[i] = this->buttonData[i]; - } -} - -int EventDevice::getAbsAxisMinimum(int axisNumber) { - return abs_features[axisNumber].minimum; -} - -int EventDevice::getAbsAxisMaximum(int axisNumber) { - return abs_features[axisNumber].maximum; -} - -int EventDevice::getAbsAxisFuzz(int axisNumber) { - return abs_features[axisNumber].fuzz; -} - -bool EventDevice::getFFEnabled() { - if(ffSupported==1) { - //LOG_TRACE("FF is supported for %s\n", getName()); - return true; - } - //LOG_TRACE("FF is not supported for %s\n", getName()); - return false; -} - -void EventDevice::rumble(float force) { - if(force>1) force=1; - if(force<-1) force=-1; - //LOG_TRACE("Rumbling at %d%%, (shh, pretend)\n", (int)(force*100)); - - if(effect_playing==true) { - stop.type=EV_FF; - stop.code = effect.id; - stop.value=0; - LOG_TRACE("Stopping effect %d\n", stop.code); - if (write(fd, (const void*) &stop, sizeof(stop)) == -1) { - perror("Failed to stop effect"); - } else { - effect_playing=false; - } - } - - if(force>0.666666) { - effect.u.rumble.strong_magnitude = (int)(0x8000*force); - effect.u.rumble.weak_magnitude = (int)(0xc000*force); - } else if(force>0.3333333) { - effect.u.rumble.strong_magnitude = (int)(0x8000*force); - effect.u.rumble.weak_magnitude = (int)(0xc000*0); - } else { - effect.u.rumble.strong_magnitude = (int)(0x8000*0); - effect.u.rumble.weak_magnitude = (int)(0xc000*force); - } - - LOG_TRACE("Uploading effect %d\n", effect.id); - if (ioctl(fd, EVIOCSFF, &effect) == -1) { - perror("Upload effect"); - } - LOG_TRACE("Uploaded effect %d\n", effect.id); - - if(effect_playing==false && force!=0) { - play.type = EV_FF; - play.code=effect.id; - play.value=1; - - LOG_TRACE("Playing effect %d\n", play.code); - if (write(fd, (const void*) &play, sizeof(play)) == -1) { - perror("Failed to play effect"); - } else { - effect_playing=true; - } - } -} - -void EventDevice::cleanup() { - char message[512]; - sprintf(message, "Closing device %s\n", name); - LOG_TRACE(message); - close(fd); -} diff --git a/plugins/linux/src/native/EventDevice.h b/plugins/linux/src/native/EventDevice.h deleted file mode 100644 index 1a79493..0000000 --- a/plugins/linux/src/native/EventDevice.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#if !defined(eventInterface_eventDevice_h) -#define eventInterface_eventDevice_h - -#include <stdint.h> -#include <linux/input.h> -#include "eventInterfaceTypes.h" -#include "Device.h" - -class EventDevice : public Device { - - private: - int fd; - int inited; - char *name; - int numButtons; - uint16_t bustype; - uint16_t vendor; - uint16_t product; - uint16_t version; - short *supportedRelAxes; - short *supportedAbsAxes; - short *supportedButtons; - int *relAxesData; - int *absAxesData; - uint8_t *buttonData; - int ffSupported; - int numRelAxes; - int numAbsAxes; - uint8_t evtype_bitmask[EV_MAX/8 + 1]; - uint8_t key_bitmask[KEY_MAX/8 + 1]; - uint8_t rel_bitmask[REL_MAX/8 + 1]; - uint8_t abs_bitmask[ABS_MAX/8 + 1]; - uint8_t ff_bitmask[16]; - struct input_absinfo *abs_features; - int absAxisLookup[ABS_MAX]; - int relAxisLookup[REL_MAX]; - int buttonLookup[KEY_MAX]; - struct ff_effect effect; - struct input_event play, stop; - bool effect_playing; - - public: - EventDevice(char *deviceFilename); - int getNumberRelAxes(); - int getNumberAbsAxes(); - int getNumberButtons(); - const char *getName(); - int getBusType(); - int getVendorID(); - int getProductID(); - int getVersion(); - void getSupportedRelAxes(int supportedAxis[]); - void getSupportedAbsAxes(int supportedAxis[]); - void getSupportedButtons(int supportedButtons[]); - int poll(); - void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]); - int getAbsAxisMinimum(int axisNumber); - int getAbsAxisMaximum(int axisNumber); - int getAbsAxisFuzz(int axisNumber); - int isValidDevice(); - bool getFFEnabled(); - void rumble(float force); - void cleanup(); -}; - -#endif //eventInterface_eventDevice_h diff --git a/plugins/linux/src/native/JoystickDevice.cpp b/plugins/linux/src/native/JoystickDevice.cpp deleted file mode 100644 index 20be098..0000000 --- a/plugins/linux/src/native/JoystickDevice.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#include "eventInterfaceTypes.h" -#include "JoystickDevice.h" -#include <stdio.h> -#include <linux/input.h> -#include <linux/joystick.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <malloc.h> -#include <errno.h> - -#include "logger.h" - -JoystickDevice::JoystickDevice(char *deviceFileName) { - char tempName[Device::MAX_NAME_LENGTH-1] = "Unknown"; - int i; - - LOG_TRACE("Trying to open %s\n", deviceFileName); - fd = open(deviceFileName, O_RDONLY | O_NONBLOCK); - /*if(fd<0) { - char errorMessage[512]; - sprintf(errorMessage, "Error opening device %s\n", deviceFileName); - perror(errorMessage); - }*/ - - if(fd>0){ - LOG_TRACE("Opened %s, trying to get device name\n", deviceFileName); - if(ioctl(fd, JSIOCGNAME(sizeof(tempName)), tempName) < 0) { - LOG_TRACE("Failed to get device name for %s\n", deviceFileName); - char errorMessage[512]; - sprintf(errorMessage, "Error reading device %s\n", deviceFileName); - perror(errorMessage); - } - - int namelength=strlen(tempName); - name = (char *)malloc(namelength+1); - strncpy(name,tempName, namelength+1); - - char tempNumButtons; - char tempNumAxes; - LOG_TRACE("Getting button and axes information for %s\n", deviceFileName); - ioctl (fd, JSIOCGBUTTONS, &tempNumButtons); - ioctl (fd, JSIOCGAXES, &tempNumAxes); - - numButtons = tempNumButtons; - numAbsAxes = tempNumAxes; - - //fprintf(stderr, "Got joystick %s with %d buttons and %d axes\n", tempName, numButtons, numAbsAxes); - - //buttonData = (uint8_t *)malloc(numButtons * sizeof(uint8_t)); - buttonData = new uint8_t[numButtons]; - //absAxesData = (int *)malloc(numAbsAxes * sizeof(int)); - absAxesData = new int[numAbsAxes]; - - LOG_TRACE("Initialisation of %s completed\n", deviceFileName); - inited = 1; - } else { - LOG_TRACE("Failed to open device %s\n", deviceFileName); - inited = 0; - } -} - -int JoystickDevice::isValidDevice() { - return inited; -} - -int JoystickDevice::getNumberRelAxes(){ - if(inited!=1) return -1; - return 0; -} - -int JoystickDevice::getNumberAbsAxes(){ - if(inited!=1) return -1; - return numAbsAxes; -} - -int JoystickDevice::getNumberButtons(){ - if(inited!=1) return -1; - return numButtons; -} - -const char *JoystickDevice::getName(){ - return name; -} - -int JoystickDevice::getBusType(){ - if(inited!=1) return -1; - return 0; -} - -int JoystickDevice::getVendorID(){ - if(inited!=1) return -1; - return 0; -} - -int JoystickDevice::getProductID(){ - if(inited!=1) return -1; - return 0; -} - -int JoystickDevice::getVersion(){ - if(inited!=1) return -1; - return 0; -} - -void JoystickDevice::getSupportedRelAxes(int supportedAxis[]){ -} - -void JoystickDevice::getSupportedAbsAxes(int supportedAxis[]){ -} - -void JoystickDevice::getSupportedButtons(int supportedButtons[]){ -} - -/** - * A return value of -1 means error, 0 means ok, but no change - * a return of >0 means the data for this device has changed - */ -int JoystickDevice::poll(){ - struct js_event event; - int numEvents = 0; - while(read(fd, &event, sizeof event) > 0) { - numEvents++; - event.type &= ~JS_EVENT_INIT; - if(event.type == JS_EVENT_BUTTON) { - buttonData[event.number] = event.value; - } else if(event.type == JS_EVENT_AXIS) { - absAxesData[event.number] = event.value; - } - - } - // EAGAIN is returned when the queue is empty - if(errno != EAGAIN) { - printf("Something went wrong getting an event\n"); - } - - return numEvents; -} - -void JoystickDevice::getPolledData(int relAxesData[], int absAxesData[], int buttonData[]){ - int i; - - if(inited!=1) return; - for(i=0;i<numAbsAxes;i++) { - (absAxesData)[i] = this->absAxesData[i]; - } - for(i=0;i<numButtons;i++) { - (buttonData)[i] = this->buttonData[i]; - } -} - -int JoystickDevice::getAbsAxisMinimum(int axisNumber) { - return -32767; -} - -int JoystickDevice::getAbsAxisMaximum(int axisNumber) { - return 32767; -} - -int JoystickDevice::getAbsAxisFuzz(int axisNumber) { - return 0; -} - -bool JoystickDevice::getFFEnabled() { - return false; -} - -void JoystickDevice::rumble(float force) { - return; -} - -void JoystickDevice::cleanup() { - close(fd); -} diff --git a/plugins/linux/src/native/MixedDevice.cpp b/plugins/linux/src/native/MixedDevice.cpp deleted file mode 100644 index aff795e..0000000 --- a/plugins/linux/src/native/MixedDevice.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#include "eventInterfaceTypes.h" -#include "JoystickDevice.h" -#include "MixedDevice.h" -#include <stdio.h> -#include <linux/input.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <malloc.h> -#include <errno.h> - -MixedDevice::MixedDevice(JoystickDevice *jsDevice, EventDevice *evDevice) { - - joystickDevice = jsDevice; - eventDevice = evDevice; -} - -int MixedDevice::getNumberRelAxes(){ - eventDevice->getNumberRelAxes(); -} - -int MixedDevice::getNumberAbsAxes(){ - return eventDevice->getNumberAbsAxes(); -} - -int MixedDevice::getNumberButtons(){ - return eventDevice->getNumberButtons(); -} - -const char *MixedDevice::getName(){ - return eventDevice->getName(); -} - -int MixedDevice::getBusType(){ - return eventDevice->getBusType(); -} - -int MixedDevice::getVendorID(){ - return eventDevice->getVendorID(); -} - -int MixedDevice::getProductID(){ - return eventDevice->getProductID(); -} - -int MixedDevice::getVersion(){ - return eventDevice->getVersion(); -} - -void MixedDevice::getSupportedRelAxes(int supportedAxis[]){ - return eventDevice->getSupportedRelAxes(supportedAxis); -} - -void MixedDevice::getSupportedAbsAxes(int supportedAxis[]){ - return eventDevice->getSupportedAbsAxes(supportedAxis); -} - -void MixedDevice::getSupportedButtons(int supportedButtons[]){ - return eventDevice->getSupportedButtons(supportedButtons); -} - -/** - * A return value of -1 means error, 0 means ok, but no change - * a return of >0 means the data for this device has changed - */ -int MixedDevice::poll(){ - eventDevice->poll(); - return joystickDevice->poll(); -} - -void MixedDevice::getPolledData(int relAxesData[], int absAxesData[], int buttonData[]){ - int i; - - joystickDevice->getPolledData(new int[joystickDevice->getNumberRelAxes()], absAxesData, new int[joystickDevice->getNumberButtons()]); - eventDevice->getPolledData(relAxesData, new int[eventDevice->getNumberAbsAxes()], buttonData); - -} - -int MixedDevice::getAbsAxisMinimum(int axisNumber) { - return joystickDevice->getAbsAxisMinimum(axisNumber); -} - -int MixedDevice::getAbsAxisMaximum(int axisNumber) { - return joystickDevice->getAbsAxisMaximum(axisNumber); -} - -int MixedDevice::getAbsAxisFuzz(int axisNumber) { - return joystickDevice->getAbsAxisFuzz(axisNumber); -} - -bool MixedDevice::getFFEnabled() { - return eventDevice->getFFEnabled(); -} - -void MixedDevice::rumble(float force) { - eventDevice->rumble(force); -} - -void MixedDevice::cleanup() { - if(joystickDevice!=0 && eventDevice!=0) { - joystickDevice->cleanup(); - eventDevice->cleanup(); - free(joystickDevice); - free(eventDevice); - joystickDevice=0; - eventDevice=0; - } -} diff --git a/plugins/linux/src/native/MixedDevice.h b/plugins/linux/src/native/MixedDevice.h deleted file mode 100644 index 3239ed4..0000000 --- a/plugins/linux/src/native/MixedDevice.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#ifndef MixedDevice_h -#define MixedDevice_h - -#include <stdint.h> -#include <linux/input.h> -#include "eventInterfaceTypes.h" -#include "Device.h" -#include "EventDevice.h" -#include "JoystickDevice.h" -#include "MixedDevice.h" - -class MixedDevice : public Device { - - private: - JoystickDevice *joystickDevice; - EventDevice *eventDevice; - - public: - MixedDevice(JoystickDevice *joystickDevice, EventDevice *eventDevice); - int getNumberRelAxes(); - int getNumberAbsAxes(); - int getNumberButtons(); - const char *getName(); - int getBusType(); - int getVendorID(); - int getProductID(); - int getVersion(); - void getSupportedRelAxes(int supportedAxis[]); - void getSupportedAbsAxes(int supportedAxis[]); - void getSupportedButtons(int supportedButtons[]); - void getSupportedRelAxes(short supportedAxis[]); - void getSupportedAbsAxes(short supportedAxis[]); - void getSupportedButtons(short supportedButtons[]); - int poll(); - void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]); - int getAbsAxisMinimum(int axisNumber); - int getAbsAxisMaximum(int axisNumber); - int getAbsAxisFuzz(int axisNumber); - bool getFFEnabled(); - void rumble(float force); - void cleanup(); -}; - -#endif //eventInterface_eventDevice_h diff --git a/plugins/linux/src/native/build.xml b/plugins/linux/src/native/build.xml index f055249..c323163 100644 --- a/plugins/linux/src/native/build.xml +++ b/plugins/linux/src/native/build.xml @@ -6,50 +6,43 @@ <!-- The idea is that both Ant and NetBeans have to know what the package root is --> <!-- for the classes in your application. --> <project name="JInput Linux port, Native code" basedir="." default="compileNativeJinputLib"> - - <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! --> - <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. --> - + <property name="libname" value="libjinput-linux.so"/> + <target name="init"> - <!-- You can set up any variables you want used throughout the script here. --> - <!-- property name="hello" value="world"/--> - <!-- To use e.g. Jikes, uncomment this line. --> - <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) --> - <!-- <property name="build.compiler" value="jikes"/> --> - <!-- You might like to set up some overridable paths, etc.: --> - <!-- <property name="mylib" value="../lib/mylib.jar"/> --> - <mkdir dir="build"/> - <mkdir dir="apidoc"/> - </target> - - <target name="createNativeDefinitions.java" depends="init"> - <exec dir="." executable="./getDefinitions" os="Linux" output="../java/net/java/games/input/NativeDefinitions.java"> - <arg line="/usr/include/linux/input.h"/> - </exec> - </target> + </target> - <target name="createJNIHeaders" depends="init"> - <javah> - <classpath> - <pathelement path="."/> - <pathelement location="jinput.jar"/> - </classpath> - <class name="net.java.games.input.LinuxDevice"/> - <class name="net.java.games.input.LinuxEnvironmentPlugin"/> - <class name="net.java.games.input.LinuxKeyboard"/> - </javah> - </target> - - <target name="compileNativeEventLib" depends="init"> - <exec dir="." executable="g++" os="Linux"> - <arg line="--shared -DLOGTRACE -o libeventInterface.so eventInterface.cpp EventDevice.cpp"/> - </exec> - </target> + <target depends="init" name="createNativeDefinitions.java"> + <exec dir="." executable="gawk" os="Linux" output="../java/net/java/games/input/NativeDefinitions.java"> + <arg line="-f"/> + <arg line="getDefinitions"/> + <arg line="/usr/include/linux/input.h"/> + </exec> + </target> + <target name="clean"> + <delete> + <fileset dir="." includes="*.o"/> + <fileset file="${libname}"/> + </delete> + </target> + <target name="compileNativeJinputLib" depends="init"> - <exec dir="." executable="g++" os="Linux"> - <arg line="-I${java.home}/include -I${java.home}/include/linux -I${java.home}/../include -I${java.home}/../include/linux --shared -DLOGTRACE -o libjinput-linux.so jinput.cpp eventInterface.cpp EventDevice.cpp joystickInterface.cpp JoystickDevice.cpp MixedDevice.cpp"/> - </exec> + <apply dir="." executable="cc" os="Linux" dest="." skipemptyfilesets="true" failonerror="true"> + <arg line="-O2 -Wall -c -fPIC"/> + <arg value="-I${java.home}/include"/> + <arg value="-I${java.home}/include/linux"/> + <arg value="-I../../../common/src/native"/> + <mapper type="glob" from="*.c" to="*.o"/> + <fileset dir="." includes="*.c"/> + <fileset dir="../../../common/src/native" includes="*.c"/> + </apply> + <apply dir="." parallel="true" executable="cc" os="Linux" failonerror="true"> + <arg line="-shared -O2 -Wall -o ${libname}"/> + <fileset dir="." includes="*.o"/> + </apply> + <apply dir="." parallel="true" executable="strip" os="Linux" failonerror="true"> + <fileset file="${libname}"/> + </apply> </target> </project> diff --git a/plugins/linux/src/native/eventInterface.cpp b/plugins/linux/src/native/eventInterface.cpp deleted file mode 100644 index 346965b..0000000 --- a/plugins/linux/src/native/eventInterface.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#include <sys/dir.h> -#include <stdio.h> -#include <dirent.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <linux/input.h> -#include <string.h> -#include <malloc.h> -#include <unistd.h> -#include "Device.h" -#include "EventDevice.h" - -#include "logger.h" - -int evNumDevices; -int eventInterfaceVersion; -Device **evDeviceList; -int evInited = 0; - -int evFileFilter(const struct direct *entry) { - if (strncmp(entry->d_name, "event", 5) == 0) { - return 1; - } - return 0; - } - -int evGetDeviceFiles(char ***filenames) { - struct direct **files; - int num_files, i; - char dirName[] = {"/dev/input"}; - - num_files = scandir(dirName, &files, &evFileFilter, alphasort); - - *filenames = (char **)malloc(num_files * sizeof(char *)); - - for(i=0;i<num_files;i++) { - char *filename = files[i]->d_name; - char *fullFileName; - - fullFileName = (char *)malloc((strlen(dirName) + 1 + strlen(filename) + 1)); - sprintf(fullFileName, "%s/%s", dirName, filename); - (*filenames)[i] = fullFileName; - } - - return num_files; -} - -int evInit() { - int fd=-1; - int i; - char **deviceFileNames; - int numDeviceFiles; - - numDeviceFiles = evGetDeviceFiles(&deviceFileNames); - if(numDeviceFiles<0) { - return -1; - } - - if ((fd = open(deviceFileNames[0], O_RDONLY)) <0) { - evNumDevices=0; - evInited=1; - return 0; - } - - if (ioctl(fd, EVIOCGVERSION, &eventInterfaceVersion)) { - close(fd); - evNumDevices=0; - evInited=1; - return 0; - } - - if(fd>=0) {close(fd);} - - Device *tempDeviceList[numDeviceFiles]; - - evNumDevices = 0; - for(i=0;i<numDeviceFiles;i++) { - EventDevice *tempDevice = new EventDevice(deviceFileNames[i]); - if(tempDevice->isValidDevice()==1) { - tempDeviceList[i] = tempDevice; - evNumDevices++; - } else { - tempDeviceList[i] = NULL; - } - } - - int highDeviceCountNumber = i; - int evTempDeviceCount = 0; - // Now we know for certain which devices are open, we can take notes - evDeviceList = (Device **)malloc(evNumDevices * sizeof(Device *)); - for(i=0;i<evNumDevices;i++) { - while(tempDeviceList[evTempDeviceCount] == NULL) { - evTempDeviceCount++; - } - evDeviceList[i] = tempDeviceList[evTempDeviceCount]; - LOG_TRACE("Copied temp event device %d to event device %d\n", evTempDeviceCount, i); - evTempDeviceCount++; - } - - evInited=1; - - return 0; -} - -int evGetEventInterfaceVersionNumber() { - return eventInterfaceVersion; -} - -int evGetNumberDevices() { - if(evInited) { - return evNumDevices; - } - return -1; -} - -void evGetDevices(Device **theirDeviceList) { - int i; - for(i=0;i<evNumDevices;i++) { - theirDeviceList[i] = evDeviceList[i]; - } -} diff --git a/plugins/linux/src/native/eventInterfaceTypes.h b/plugins/linux/src/native/eventInterfaceTypes.h deleted file mode 100644 index c8ffd6e..0000000 --- a/plugins/linux/src/native/eventInterfaceTypes.h +++ /dev/null @@ -1,27 +0,0 @@ -#if !defined(eventInterfaceTypes_h) -#define eventInterfaceTypes_h - -#include <linux/input.h> -#include <stdint.h> - -#define getBit(bit, bitField) (bitField[bit/8] & (1 << (bit%8))) - -struct input_devinfo { - uint16_t bustype; - uint16_t vendor; - uint16_t product; - uint16_t version; -}; - - -/** removed for compatability with input.h --JPK -struct input_absinfo { - int value; - int minimum; - int maximum; - int fuzz; - int flat; -}; -*/ - -#endif //eventInterfaceTypes_h diff --git a/plugins/linux/src/native/getDefinitions b/plugins/linux/src/native/getDefinitions index 1a15fbe..e5d127d 100644 --- a/plugins/linux/src/native/getDefinitions +++ b/plugins/linux/src/native/getDefinitions @@ -29,7 +29,7 @@ NR == 1 { printf("package net.java.games.input;\n\n") printf("\n"); printf("/**\n * This file is generated from %s please do not edit\n */\n", FILENAME); - printf("public class NativeDefinitions {\n") + printf("class NativeDefinitions {\n") } /#define ABS_/ { printf(" public static final int %s = %s;\n", $2, $3) @@ -46,6 +46,15 @@ NR == 1 { /#define BUS_/ { printf(" public static final int %s = %s;\n", $2, $3) } +/#define EV_/ { + printf(" public static final int %s = %s;\n", $2, $3) +} +/#define FF_/ { + printf(" public static final int %s = %s;\n", $2, $3) +} +/#define USAGE_/ { + printf(" public static final int %s = %s;\n", $2, $3) +} END { printf("}\n"); } diff --git a/plugins/linux/src/native/jinput.cpp b/plugins/linux/src/native/jinput.cpp deleted file mode 100644 index 40f0d29..0000000 --- a/plugins/linux/src/native/jinput.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#include <stdio.h> -#include <stdlib.h> -#include <malloc.h> -#include <string.h> - -#include "net_java_games_input_JInputLibrary.h" - -#include "Device.h" -#include "EventDevice.h" -#include "JoystickDevice.h" -#include "MixedDevice.h" -#include "eventInterface.h" -#include "joystickInterface.h" -#include "logger.h" - -Device **jinputDeviceList; -int jinputNumDevices; - -/* - * Class: net_java_games_input_JInputLibrary - * Method: nativeInit - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_nativeInit - (JNIEnv *, jclass) { - - LOG_TRACE("Initing event interface\n"); - if(evInit()!=0) { - fprintf(stderr, "Could not find any working event devices\n"); -// return -1; - } - LOG_TRACE("Initing joystick interface\n"); - if(jsInit()!=0) { - fprintf(stderr, "Could not find any working joystick devices\n"); -// return -1; - } - - LOG_TRACE("Getting the number of event devices\n"); - int numEventDevices = evGetNumberDevices(); - EventDevice *eventDevices[numEventDevices]; - - LOG_TRACE("Getting %d event devices\n", numEventDevices); - evGetDevices((Device **)eventDevices); - - LOG_TRACE("Getting the number of joystick devices\n"); - int numJoysticks = jsGetNumberDevices(); - JoystickDevice *jsDevices[numJoysticks]; - LOG_TRACE("Getting %d joystick devices\n", numJoysticks); - jsGetDevices((Device **)jsDevices); - - - int i; - int j; - int joystickPtr = 0; - jinputDeviceList = (Device **)malloc((numEventDevices + numJoysticks) * sizeof(Device *)); - for(i=0;i<numEventDevices;i++) { - EventDevice *eventDevice = eventDevices[i]; - int deviceCountCache = jinputNumDevices; - - for(j=joystickPtr;j<numJoysticks;j++) { - JoystickDevice *jsDevice = jsDevices[j]; - LOG_TRACE("Getting device information for event device %d and joystick %d\n", i, j); - if((jsDevice->getNumberButtons() == eventDevice->getNumberButtons()) && (jsDevice->getNumberAbsAxes() == (eventDevice->getNumberAbsAxes() + eventDevice->getNumberRelAxes()))) { - const char *jsName = jsDevice->getName(); - const char *eventDeviceName = eventDevice->getName(); - - if(strcmp(jsName, eventDeviceName) == 0) { - // The current event device is the curre joystick device too - LOG_TRACE("Creating a mixed device with id %d, combining event device %d and joystick device %d\n", jinputNumDevices, i, j); - jinputDeviceList[jinputNumDevices] = new MixedDevice(jsDevice, eventDevice); - jsDevices[j] = NULL; - j++; - jinputNumDevices++; - joystickPtr = j; - j = numJoysticks; - } - } - /*if(jinputNumDevices == deviceCountCache) { - fprintf(stderr, "event device \"%s\" doesn't match js \"%s\"\n", eventDevice->getName(), jsDevice->getName()); - fprintf(stderr, "event device has %d rel axes, %d abs axis and %d buttons\n", eventDevice->getNumberRelAxes(), eventDevice->getNumberAbsAxes(), eventDevice->getNumberButtons()); - fprintf(stderr, "js device has %d axes and %d buttons\n", jsDevice->getNumberAbsAxes(), jsDevice->getNumberButtons()); - } else { - fprintf(stderr, "event device %s did match js %s\n", eventDevice->getName(), jsDevice->getName()); - }*/ - - } - - if(jinputNumDevices == deviceCountCache) { - jinputDeviceList[jinputNumDevices] = eventDevice; - jinputNumDevices++; - } - } - - for(i=0;i<numJoysticks;i++) { - if(jsDevices[i]!=NULL) { - LOG_TRACE("Copying joystick device %d to jinput device list %d\n", i, jinputNumDevices); - jinputDeviceList[jinputNumDevices] = jsDevices[i]; - jinputNumDevices++; - } - } - - return(0); - -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getDeviceName - * Signature: (I)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_net_java_games_input_JInputLibrary_getDeviceName - (JNIEnv *env, jclass, jint deviceID) { - - LOG_TRACE("Gettign device name for jinput device %d.\n", deviceID); - LOG_TRACE("jinput device %d is %d\n", deviceID, jinputDeviceList[deviceID]); - LOG_TRACE("Gettign device name for jinput device %d, (%s)\n", deviceID, jinputDeviceList[deviceID]->getName()); - return env->NewStringUTF(jinputDeviceList[deviceID]->getName()); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumAbsAxes - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumAbsAxes - (JNIEnv *env, jclass, jint deviceID) { - - LOG_TRACE("Gettign number of absolute axes for jinput device %d (%d)\n", deviceID, jinputDeviceList[deviceID]->getNumberAbsAxes()); - return jinputDeviceList[deviceID]->getNumberAbsAxes(); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumRelAxes - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumRelAxes - (JNIEnv *env, jclass, jint deviceID) { - - LOG_TRACE("Gettign number of relative axes for jinput device %d (%d)\n", deviceID, jinputDeviceList[deviceID]->getNumberRelAxes()); - return jinputDeviceList[deviceID]->getNumberRelAxes(); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumButtons - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumButtons - (JNIEnv *, jclass, jint deviceID) { - - LOG_TRACE("Gettign number of buttons for jinput device %d (%d)\n", deviceID, jinputDeviceList[deviceID]->getNumberButtons()); - return jinputDeviceList[deviceID]->getNumberButtons(); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumberOfDevices - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumberOfDevices - (JNIEnv *, jclass) { - - return jinputNumDevices; -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getSupportedAbsAxes - * Signature: (I[I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedAbsAxes - (JNIEnv *env, jclass, jint deviceID, jintArray axesData) { - - jint *axisReturns = env->GetIntArrayElements(axesData, 0); - - LOG_TRACE("Getting suported absolute axes for jinput device %d\n", deviceID); - jinputDeviceList[deviceID]->getSupportedAbsAxes(axisReturns); - - env->ReleaseIntArrayElements(axesData, axisReturns, 0); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getSupportedRelAxes - * Signature: (I[I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedRelAxes - (JNIEnv *env, jclass, jint deviceID, jintArray axesData) { - - jint *axisReturns = env->GetIntArrayElements(axesData, 0); - - LOG_TRACE("Getting suported relative axes for jinput device %d\n", deviceID); - jinputDeviceList[deviceID]->getSupportedRelAxes(axisReturns); - - env->ReleaseIntArrayElements(axesData, axisReturns, 0); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getSupportedButtons - * Signature: (I[I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedButtons - (JNIEnv *env, jclass, jint deviceID, jintArray buttonData) { - - jint *buttonDataElements = env->GetIntArrayElements(buttonData, 0); - - LOG_TRACE("Getting supported buttons for jinput device %d\n", deviceID); - jinputDeviceList[deviceID]->getSupportedButtons(buttonDataElements); - - env->ReleaseIntArrayElements(buttonData, buttonDataElements, 0); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: poll - * Signature: (I[I[I[I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_poll - (JNIEnv *env, jclass, jint deviceID, jintArray buttons, jintArray relAxes, jintArray absAxes) { - - jint *buttonElements = env->GetIntArrayElements(buttons, 0); - jint *relAxesElements = env->GetIntArrayElements(relAxes, 0); - jint *absAxesElements = env->GetIntArrayElements(absAxes, 0); - - LOG_POLL_TRACE("Polling jinput device %d\n", deviceID); - int retval = jinputDeviceList[deviceID]->poll(); - LOG_POLL_TRACE("Getting polled data for device %d\n", deviceID); - jinputDeviceList[deviceID]->getPolledData(relAxesElements, absAxesElements, buttonElements); - - env->ReleaseIntArrayElements(buttons, buttonElements, 0); - env->ReleaseIntArrayElements(relAxes, relAxesElements, 0); - env->ReleaseIntArrayElements(absAxes, absAxesElements, 0); - - return retval; -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getAbsAxisFuzz - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisFuzz - (JNIEnv *, jclass, jint deviceID, jint axisID) { - - LOG_TRACE("Getting fuzz data for axis %d on device %d\n", axisID, deviceID); - return jinputDeviceList[deviceID]->getAbsAxisFuzz(axisID); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getAbsAxisMaximum - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMaximum - (JNIEnv *, jclass, jint deviceID, jint axisID) { - - LOG_TRACE("Getting absolute axes maximum value data for axis %d on device %d\n", axisID, deviceID); - return jinputDeviceList[deviceID]->getAbsAxisMaximum(axisID); -} - - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getAbsAxisMinimum - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMinimum - (JNIEnv *, jclass, jint deviceID, jint axisID) { - - LOG_TRACE("Getting absolute axes minimum value data for axis %d on device %d\n", axisID, deviceID); - return jinputDeviceList[deviceID]->getAbsAxisMinimum(axisID); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNativePortType - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNativePortType - (JNIEnv *, jclass, jint deviceID) { - - LOG_TRACE("Getting bus type for device %d\n", deviceID); - return jinputDeviceList[deviceID]->getBusType(); -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getFFEnabled - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_net_java_games_input_JInputLibrary_getFFEnabled - (JNIEnv *, jclass, jint deviceID) { - - LOG_TRACE("Getting FFEnabled status for device %d\n", deviceID); - if(jinputDeviceList[deviceID]->getFFEnabled()) { - //LOG_TRACE("jinput lib thinks device %d is ff enabled\n", deviceID); - return JNI_TRUE; - } - //LOG_TRACE("jinput lib thinks device %d is ff disabled\n", deviceID); - return JNI_FALSE; -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: nativeRumble - * Signature: (IF)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeRumble - (JNIEnv *, jclass, jint deviceID, jfloat force) { - if(jinputDeviceList[deviceID]!=0) { - LOG_TRACE("Setting rumble on device %d to %d\n", deviceID, force); - jinputDeviceList[deviceID]->rumble(force); - } -} - -/* - * Class: net_java_games_input_JInputLibrary - * Method: nativeCleanup - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeCleanup - (JNIEnv *, jclass, jint deviceID) { - if(jinputDeviceList[deviceID]!=0) { - LOG_TRACE("Cleaning up device %d\n", deviceID); - jinputDeviceList[deviceID]->cleanup(); - free(jinputDeviceList[deviceID]); - jinputDeviceList[deviceID]=0; - } -} diff --git a/plugins/linux/src/native/joystickInterface.cpp b/plugins/linux/src/native/joystickInterface.cpp deleted file mode 100644 index da96a61..0000000 --- a/plugins/linux/src/native/joystickInterface.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Copyright (C) 2003 Jeremy Booth ([email protected]) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. Redistributions in binary - * form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * The name of the author may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - */ - -#include <sys/dir.h> -#include <stdio.h> -#include <dirent.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <linux/joystick.h> -#include <string.h> -#include <malloc.h> -#include <unistd.h> -#include "Device.h" -#include "JoystickDevice.h" - -int jsNumDevices; -int joystickInterfaceVersion; -Device **jsDeviceList; -int jsInited = 0; - -int jsFileFilter(const struct direct *entry) { - if (strncmp(entry->d_name, "js", 2) == 0) { - return 1; - } - return 0; - } - -int jsGetDeviceFiles(char ***filenames) { - struct direct **files; - int num_files, i; - char dirName[12]; - - sprintf(dirName, "/dev/input"); - - num_files = scandir(dirName, &files, &jsFileFilter, alphasort); - - if(num_files==0) { - sprintf(dirName, "/dev"); - num_files = scandir(dirName, &files, &jsFileFilter, alphasort); - } - - *filenames = (char **)malloc(num_files * sizeof(char *)); - - for(i=0;i<num_files;i++) { - char *filename = files[i]->d_name; - char *fullFileName; - - fullFileName = (char *)malloc((strlen(dirName) + 1 + strlen(filename) + 1)); - sprintf(fullFileName, "%s/%s", dirName, filename); - (*filenames)[i] = fullFileName; - } - - return num_files; -} - -int jsInit() { - int fd=-1; - int i; - char **deviceFileNames; - int numDeviceFiles; - - numDeviceFiles = jsGetDeviceFiles(&deviceFileNames); - if(numDeviceFiles<0) { - return -1; - } - - if(numDeviceFiles==0) { - jsNumDevices = 0; - jsInited=1; - return 0; - } - - if ((fd = open(deviceFileNames[0], O_RDONLY)) <0) { - jsNumDevices = 0; - jsInited=1; - return 0; - } - - if (ioctl(fd, JSIOCGVERSION, &joystickInterfaceVersion)) { - close(fd); - jsNumDevices = 0; - jsInited=1; - return 0; - } - - if(fd>=0) {close(fd);} - - Device *tempDeviceList[numDeviceFiles]; - - jsNumDevices = 0; - for(i=0;i<numDeviceFiles;i++) { - JoystickDevice *tempDevice = new JoystickDevice(deviceFileNames[i]); - // The device has a copy of the name, free the memory - free(deviceFileNames[i]); - if(tempDevice->isValidDevice()==1) { - tempDeviceList[i] = tempDevice; - jsNumDevices++; - } - } - - int jsTempDeviceCount = 0; - // Now we know for certain which devices are open, we can take notes - jsDeviceList = (Device **)malloc(jsNumDevices * sizeof(Device *)); - for(i=0;i<jsNumDevices;i++) { - while(tempDeviceList[jsTempDeviceCount] == NULL) { - jsTempDeviceCount++; - } - jsDeviceList[i] = tempDeviceList[jsTempDeviceCount]; - //printf("Copied joystick %d to %d\n", jsTempDeviceCount, i); - jsTempDeviceCount++; - } - - // Free the file names array, which should now be free anyway. - free(deviceFileNames); - - jsInited=1; - - return 0; -} - -int jsGetJoystickInterfaceVersionNumber() { - return joystickInterfaceVersion; -} - -int jsGetNumberDevices() { - if(jsInited) { - return jsNumDevices; - } - return -1; -} - -void jsGetDevices(Device **theirDeviceList) { - int i; - for(i=0;i<jsNumDevices;i++) { - theirDeviceList[i] = jsDeviceList[i]; - } -} diff --git a/plugins/linux/src/native/logger.h b/plugins/linux/src/native/logger.h deleted file mode 100644 index d832491..0000000 --- a/plugins/linux/src/native/logger.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifdef LOGTRACE -#define LOG_TRACE(args...) printf(args) -#else -#define LOG_TRACE(args...) -#endif - -#ifdef LOGPOLLTRACE -#define LOG_POLL_TRACE(args...) LOG_TRACE(args...) -#else -#define LOG_POLL_TRACE(args...) -#endif diff --git a/plugins/linux/src/native/net_java_games_input_JInputLibrary.h b/plugins/linux/src/native/net_java_games_input_JInputLibrary.h deleted file mode 100644 index b0428e8..0000000 --- a/plugins/linux/src/native/net_java_games_input_JInputLibrary.h +++ /dev/null @@ -1,156 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class net_java_games_input_JInputLibrary */ - -#ifndef _Included_net_java_games_input_JInputLibrary -#define _Included_net_java_games_input_JInputLibrary -#ifdef __cplusplus -extern "C" { -#endif -/* Inaccessible static: inited */ -/* Inaccessible static: workerThreadMonitor */ -/* Inaccessible static: shutdown */ -/* Inaccessible static: shutdownThreadMonitor */ -/* Inaccessible static: cleanupDone */ -/* Inaccessible static: rumbler */ -/* Inaccessible static: force */ -/* - * Class: net_java_games_input_JInputLibrary - * Method: getDeviceName - * Signature: (I)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_net_java_games_input_JInputLibrary_getDeviceName - (JNIEnv *, jclass, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumAbsAxes - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumAbsAxes - (JNIEnv *, jclass, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumRelAxes - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumRelAxes - (JNIEnv *, jclass, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumButtons - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumButtons - (JNIEnv *, jclass, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: nativeInit - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_nativeInit - (JNIEnv *, jclass); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNumberOfDevices - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumberOfDevices - (JNIEnv *, jclass); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getSupportedAbsAxes - * Signature: (I[I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedAbsAxes - (JNIEnv *, jclass, jint, jintArray); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getSupportedRelAxes - * Signature: (I[I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedRelAxes - (JNIEnv *, jclass, jint, jintArray); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getSupportedButtons - * Signature: (I[I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedButtons - (JNIEnv *, jclass, jint, jintArray); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: poll - * Signature: (I[I[I[I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_poll - (JNIEnv *, jclass, jint, jintArray, jintArray, jintArray); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getAbsAxisFuzz - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisFuzz - (JNIEnv *, jclass, jint, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getAbsAxisMaximum - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMaximum - (JNIEnv *, jclass, jint, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getAbsAxisMinimum - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMinimum - (JNIEnv *, jclass, jint, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getNativePortType - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNativePortType - (JNIEnv *, jclass, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: getFFEnabled - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_net_java_games_input_JInputLibrary_getFFEnabled - (JNIEnv *, jclass, jint); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: nativeRumble - * Signature: (IF)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeRumble - (JNIEnv *, jclass, jint, jfloat); - -/* - * Class: net_java_games_input_JInputLibrary - * Method: nativeCleanup - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeCleanup - (JNIEnv *, jclass, jint); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/plugins/linux/src/native/net_java_games_input_LinuxEventDevice.c b/plugins/linux/src/native/net_java_games_input_LinuxEventDevice.c new file mode 100644 index 0000000..90eff09 --- /dev/null +++ b/plugins/linux/src/native/net_java_games_input_LinuxEventDevice.c @@ -0,0 +1,257 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <linux/input.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include "util.h" +#include "net_java_games_input_LinuxEventDevice.h" + +JNIEXPORT jlong JNICALL Java_net_java_games_input_LinuxEventDevice_nOpen(JNIEnv *env, jclass unused, jstring path, jboolean rw_flag) { + const char *path_str = (*env)->GetStringUTFChars(env, path, NULL); + if (path_str == NULL) + return -1; + int flags = rw_flag == JNI_TRUE ? O_RDWR : O_RDONLY; + flags = flags | O_NONBLOCK; + int fd = open(path_str, flags); + if (fd == -1) + throwIOException(env, "Failed to open device %s (%d)\n", path_str, errno); + (*env)->ReleaseStringUTFChars(env, path, path_str); + return fd; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nClose(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + int result = close(fd); + if (result == -1) + throwIOException(env, "Failed to close device (%d)\n", errno); +} + +JNIEXPORT jstring JNICALL Java_net_java_games_input_LinuxEventDevice_nGetName(JNIEnv *env, jclass unused, jlong fd_address) { +#define BUFFER_SIZE 1024 + int fd = (int)fd_address; + char device_name[BUFFER_SIZE]; + + if (ioctl(fd, EVIOCGNAME(BUFFER_SIZE), device_name) == -1) { + throwIOException(env, "Failed to get device name (%d)\n", errno); + return NULL; + } + jstring jstr = (*env)->NewStringUTF(env, device_name); + return jstr; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetKeyStates(JNIEnv *env, jclass unused, jlong fd_address, jbyteArray bits_array) { + int fd = (int)fd_address; + jsize len = (*env)->GetArrayLength(env, bits_array); + jbyte *bits = (*env)->GetByteArrayElements(env, bits_array, NULL); + if (bits == NULL) + return; + int res = ioctl(fd, EVIOCGKEY(len), bits); + (*env)->ReleaseByteArrayElements(env, bits_array, bits, 0); + if (res == -1) + throwIOException(env, "Failed to get device key states (%d)\n", errno); +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nGetVersion(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + int version; + if (ioctl(fd, EVIOCGVERSION, &version) == -1) { + throwIOException(env, "Failed to get device version (%d)\n", errno); + return -1; + } + return version; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nGetNumEffects(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + int num_effects; + if (ioctl(fd, EVIOCGEFFECTS, &num_effects) == -1) { + throwIOException(env, "Failed to get number of device effects (%d)\n", errno); + return -1; + } + return num_effects; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetDeviceUsageBits(JNIEnv *env, jclass unused, jlong fd_address, jbyteArray usages_array) { +#if EV_VERSION >= 0x010001 + int fd = (int)fd_address; + jsize len = (*env)->GetArrayLength(env, usages_array); + jbyte *usages = (*env)->GetByteArrayElements(env, usages_array, NULL); + if (usages == NULL) + return; + int res = ioctl(fd, EVIOCGUSAGE(len), usages); + (*env)->ReleaseByteArrayElements(env, usages_array, usages, 0); + if (res == -1) + throwIOException(env, "Failed to get device usages (%d)\n", errno); +#endif +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetBits(JNIEnv *env, jclass unused, jlong fd_address, jint evtype, jbyteArray bits_array) { + int fd = (int)fd_address; + jsize len = (*env)->GetArrayLength(env, bits_array); + jbyte *bits = (*env)->GetByteArrayElements(env, bits_array, NULL); + if (bits == NULL) + return; + int res = ioctl(fd, EVIOCGBIT(evtype, len), bits); + (*env)->ReleaseByteArrayElements(env, bits_array, bits, 0); + if (res == -1) + throwIOException(env, "Failed to get device bits (%d)\n", errno); +} + +JNIEXPORT jobject JNICALL Java_net_java_games_input_LinuxEventDevice_nGetInputID(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + jclass input_id_class = (*env)->FindClass(env, "net/java/games/input/LinuxInputID"); + if (input_id_class == NULL) + return NULL; + jmethodID input_id_constructor = (*env)->GetMethodID(env, input_id_class, "<init>", "(IIII)V"); + if (input_id_constructor == NULL) + return NULL; + struct input_id id; + int result = ioctl(fd, EVIOCGID, &id); + if (result == -1) { + throwIOException(env, "Failed to get input id for device (%d)\n", errno); + return NULL; + } + return (*env)->NewObject(env, input_id_class, input_id_constructor, (jint)id.bustype, (jint)id.vendor, (jint)id.product, (jint)id.version); +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetAbsInfo(JNIEnv *env, jclass unused, jlong fd_address, jint abs_axis, jobject abs_info_return) { + int fd = (int)fd_address; + jclass abs_info_class = (*env)->GetObjectClass(env, abs_info_return); + if (abs_info_class == NULL) + return; + jmethodID abs_info_set = (*env)->GetMethodID(env, abs_info_class, "set", "(IIIII)V"); + if (abs_info_set == NULL) + return; + struct input_absinfo abs_info; + int result = ioctl(fd, EVIOCGABS(abs_axis), &abs_info); + if (result == -1) { + throwIOException(env, "Failed to get abs info for axis (%d)\n", errno); + return; + } + (*env)->CallVoidMethod(env, abs_info_return, abs_info_set, (jint)abs_info.value, (jint)abs_info.minimum, (jint)abs_info.maximum, (jint)abs_info.fuzz, (jint)abs_info.flat); +} + +JNIEXPORT jboolean JNICALL Java_net_java_games_input_LinuxEventDevice_nGetNextEvent(JNIEnv *env, jclass unused, jlong fd_address, jobject linux_event_return) { + int fd = (int)fd_address; + jclass linux_event_class = (*env)->GetObjectClass(env, linux_event_return); + if (linux_event_class == NULL) + return JNI_FALSE; + jmethodID linux_event_set = (*env)->GetMethodID(env, linux_event_class, "set", "(JJIII)V"); + if (linux_event_set == NULL) + return JNI_FALSE; + struct input_event event; + if (read(fd, &event, sizeof(struct input_event)) == -1) { + if (errno == EAGAIN) + return JNI_FALSE; + throwIOException(env, "Failed to read next device event (%d)\n", errno); + return JNI_FALSE; + } + (*env)->CallVoidMethod(env, linux_event_return, linux_event_set, (jlong)event.time.tv_sec, (jlong)event.time.tv_usec, (jint)event.type, (jint)event.code, (jint)event.value); + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nUploadRumbleEffect(JNIEnv *env, jclass unused, jlong fd_address, jint id, jint direction, jint trigger_button, jint trigger_interval, jint replay_length, jint replay_delay, jint strong_magnitude, jint weak_magnitude) { + int fd = (int)fd_address; + struct ff_effect effect; + + effect.type = FF_RUMBLE; + effect.id = id; + effect.trigger.button = trigger_button; + effect.trigger.interval = trigger_interval; + effect.replay.length = replay_length; + effect.replay.delay = replay_delay; + effect.direction = direction; + effect.u.rumble.strong_magnitude = strong_magnitude; + effect.u.rumble.weak_magnitude = weak_magnitude; + + if (ioctl(fd, EVIOCSFF, &effect) == -1) { + throwIOException(env, "Failed to upload effect (%d)\n", errno); + return -1; + } + return effect.id; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nUploadConstantEffect(JNIEnv *env, jclass unused, jlong fd_address, jint id, jint direction, jint trigger_button, jint trigger_interval, jint replay_length, jint replay_delay, jint constant_level, jint constant_env_attack_length, jint constant_env_attack_level, jint constant_env_fade_length, jint constant_env_fade_level) { + int fd = (int)fd_address; + struct ff_effect effect; + + effect.type = FF_CONSTANT; + effect.id = id; + effect.trigger.button = trigger_button; + effect.trigger.interval = trigger_interval; + effect.replay.length = replay_length; + effect.replay.delay = replay_delay; + effect.direction = direction; + effect.u.constant.level = constant_level; + effect.u.constant.envelope.attack_length = constant_env_attack_length; + effect.u.constant.envelope.attack_level = constant_env_attack_level; + effect.u.constant.envelope.fade_length = constant_env_fade_length; + effect.u.constant.envelope.fade_level = constant_env_fade_level; + + if (ioctl(fd, EVIOCSFF, &effect) == -1) { + throwIOException(env, "Failed to upload effect (%d)\n", errno); + return -1; + } + return effect.id; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nWriteEvent(JNIEnv *env, jclass unused, jlong fd_address, jint type, jint code, jint value) { + int fd = (int)fd_address; + struct input_event event; + event.type = type; + event.code = code; + event.value = value; + + if (write(fd, &event, sizeof(event)) == -1) { + throwIOException(env, "Failed to write to device (%d)\n", errno); + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nEraseEffect(JNIEnv *env, jclass unused, jlong fd_address, jint ff_id) { + int fd = (int)fd_address; + int ff_id_int = ff_id; + + if (ioctl(fd, EVIOCRMFF, &ff_id_int) == -1) + throwIOException(env, "Failed to erase effect (%d)\n", errno); +} diff --git a/plugins/linux/src/native/net_java_games_input_LinuxJoystickDevice.c b/plugins/linux/src/native/net_java_games_input_LinuxJoystickDevice.c new file mode 100644 index 0000000..f82023b --- /dev/null +++ b/plugins/linux/src/native/net_java_games_input_LinuxJoystickDevice.c @@ -0,0 +1,128 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <linux/joystick.h> +#include "util.h" +#include "net_java_games_input_LinuxJoystickDevice.h" + +JNIEXPORT jlong JNICALL Java_net_java_games_input_LinuxJoystickDevice_nOpen(JNIEnv *env, jclass unused, jstring path) { + const char *path_str = (*env)->GetStringUTFChars(env, path, NULL); + if (path_str == NULL) + return -1; + int fd = open(path_str, O_RDONLY | O_NONBLOCK); + if (fd == -1) + throwIOException(env, "Failed to open device %s (%d)\n", path_str, errno); + (*env)->ReleaseStringUTFChars(env, path, path_str); + return fd; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_LinuxJoystickDevice_nClose(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + int result = close(fd); + if (result == -1) + throwIOException(env, "Failed to close device (%d)\n", errno); +} + +JNIEXPORT jstring JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetName(JNIEnv *env, jclass unused, jlong fd_address) { +#define BUFFER_SIZE 1024 + int fd = (int)fd_address; + char device_name[BUFFER_SIZE]; + + if (ioctl(fd, JSIOCGNAME(BUFFER_SIZE), device_name) == -1) { + throwIOException(env, "Failed to get device name (%d)\n", errno); + return NULL; + } + jstring jstr = (*env)->NewStringUTF(env, device_name); + return jstr; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetVersion(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + __u32 version; + if (ioctl(fd, JSIOCGVERSION, &version) == -1) { + throwIOException(env, "Failed to get device version (%d)\n", errno); + return -1; + } + return version; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetNumButtons(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + __u8 num_buttons; + if (ioctl(fd, JSIOCGBUTTONS, &num_buttons) == -1) { + throwIOException(env, "Failed to get number of buttons (%d)\n", errno); + return -1; + } + return num_buttons; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetNumAxes(JNIEnv *env, jclass unused, jlong fd_address) { + int fd = (int)fd_address; + __u8 num_axes; + if (ioctl(fd, JSIOCGAXES, &num_axes) == -1) { + throwIOException(env, "Failed to get number of buttons (%d)\n", errno); + return -1; + } + return num_axes; +} + +JNIEXPORT jboolean JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetNextEvent(JNIEnv *env, jclass unused, jlong fd_address, jobject event_return) { + int fd = (int)fd_address; + jclass event_class = (*env)->GetObjectClass(env, event_return); + if (event_class == NULL) + return JNI_FALSE; + jmethodID event_set = (*env)->GetMethodID(env, event_class, "set", "(JIII)V"); + if (event_set == NULL) + return JNI_FALSE; + struct js_event event; + if (read(fd, &event, sizeof(event)) == -1) { + if (errno == EAGAIN) + return JNI_FALSE; + throwIOException(env, "Failed to read next device event (%d)\n", errno); + return JNI_FALSE; + } + (*env)->CallVoidMethod(env, event_return, event_set, (jlong)event.time, (jint)event.value, (jint)event.type, (jint)event.number); + return JNI_TRUE; +} diff --git a/plugins/DX8/README.txt b/plugins/windows/README.txt index 12cd468..12cd468 100644 --- a/plugins/DX8/README.txt +++ b/plugins/windows/README.txt diff --git a/plugins/windows/build.xml b/plugins/windows/build.xml new file mode 100644 index 0000000..a10d7cb --- /dev/null +++ b/plugins/windows/build.xml @@ -0,0 +1,86 @@ +<?xml version="1.0"?> +<project name="Direct Input Plugin" basedir="." default="all"> + <target name="init"> + <mkdir dir="classes"/> + <mkdir dir="bin"/> + <condition property="dx8" > + <os family="Windows" /> + </condition> + </target> + + <target name="compile" depends="init"> + <javac srcdir="src/java" destdir="classes" debug="true" deprecation="true" source="1.4" target="1.4"> + <!-- To add something to the classpath: --> + <classpath> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> + </classpath> + </javac> + </target> + + <target depends="init,compile" name="create_jniheaders"> + <javah destdir="src/native/dx8"> + <classpath> + <pathelement path="classes"/> + <pathelement location="../../coreAPI/classes"/> + </classpath> + <class name="net.java.games.input.IDirectInput"/> + <class name="net.java.games.input.IDirectInputDevice"/> + <class name="net.java.games.input.IDirectInputEffect"/> + </javah> + <javah destdir="src/native"> + <classpath> + <pathelement path="classes"/> + <pathelement location="../../coreAPI/classes"/> + </classpath> + <class name="net.java.games.input.DummyWindow"/> + </javah> + <javah destdir="src/native/raw"> + <classpath> + <pathelement path="classes"/> + <pathelement location="../../coreAPI/bin/jinput-core.jar"/> + </classpath> + <class name="net.java.games.input.RawInputEnvironmentPlugin"/> + <class name="net.java.games.input.RawInputEventQueue"/> + <class name="net.java.games.input.RawDevice"/> + </javah> + </target> + + <target name="compile_native" depends="init,create_jniheaders" if="dx8"> + <ant dir="src/native" target="compile"/> + <copy todir="bin"> + <fileset dir="src/native" includes="*.dll"/> + </copy> + </target> + + <target name="jar" depends="init,compile"> + <jar jarfile="bin/dxinput.jar" compress="true" basedir="classes"> + <include name="**/*.class"/> + </jar> + </target> + + <target name="all" depends="compile,compile_native,jar" description="Build everything."> + </target> + + <target name="javadoc" depends="init" description="Javadoc for my API."> + <mkdir dir="apidocs"/> + <javadoc packagenames="net.*" + destdir="apidocs" + additionalparam="-source 1.4"> + <sourcepath> + <pathelement location="src/java"/> + </sourcepath> + <classpath> + <pathelement location="../../bin/jinput-core.jar"/> + <pathelement location="../../lib/jutils.jar"/> + </classpath> + </javadoc> + </target> + + <target name="clean" depends="init" description="Clean all build products."> + <delete dir="classes" failonerror="no"/> + <delete dir="bin" failonerror="no"/> + <delete dir="apidocs" failonerror="no"/> + <ant inheritAll="false" antfile="src/native/build.xml" target="clean"/> + </target> +</project> diff --git a/plugins/windows/src/java/net/java/games/input/DIAbstractController.java b/plugins/windows/src/java/net/java/games/input/DIAbstractController.java new file mode 100644 index 0000000..ef75400 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIAbstractController.java @@ -0,0 +1,72 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** +* @author elias +* @version 1.0 +*/ +final class DIAbstractController extends AbstractController { + private final IDirectInputDevice device; + private final Controller.Type type; + + protected DIAbstractController(IDirectInputDevice device, Component[] components, Controller[] children, Rumbler[] rumblers, Controller.Type type) { + super(device.getProductName(), components, children, rumblers); + this.device = device; + this.type = type; + } + + public final void pollDevice() throws IOException { + device.pollAll(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return DIControllers.getNextDeviceEvent(event, device); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + device.setBufferSize(size); + } + + public final Controller.Type getType() { + return type; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIComponent.java b/plugins/windows/src/java/net/java/games/input/DIComponent.java new file mode 100644 index 0000000..715c7fb --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIComponent.java @@ -0,0 +1,74 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** +* @author elias +* @version 1.0 +*/ +final class DIComponent extends AbstractComponent { + private final DIDeviceObject object; + + public DIComponent(Component.Identifier identifier, DIDeviceObject object) { + super(object.getName(), identifier); + this.object = object; + } + + public final boolean isRelative() { + return object.isRelative(); + } + + public final boolean isAnalog() { + return object.isAnalog(); + } + + public final float getDeadZone() { + return object.getDeadzone(); + } + + public final DIDeviceObject getDeviceObject() { + return object; + } + + protected final float poll() throws IOException { + return DIControllers.poll(this, object); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIControllers.java b/plugins/windows/src/java/net/java/games/input/DIControllers.java new file mode 100644 index 0000000..0d7f01f --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIControllers.java @@ -0,0 +1,76 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** +* @author elias +* @version 1.0 +*/ +final class DIControllers { + private final static DIDeviceObjectData di_event = new DIDeviceObjectData(); + + /* synchronized to protect di_event */ + public final static synchronized boolean getNextDeviceEvent(Event event, IDirectInputDevice device) throws IOException { + if (!device.getNextEvent(di_event)) + return false; + DIDeviceObject object = device.mapEvent(di_event); + int event_value; + if (object.isRelative()) { + event_value = object.getRelativeEventValue(di_event.getData()); + } else { + event_value = di_event.getData(); + } + DIComponent component = device.mapObject(object); + event.set(component, component.getDeviceObject().convertValue(event_value), di_event.getNanos()); + return true; + } + + public final static float poll(Component component, DIDeviceObject object) throws IOException { + int poll_data = object.getDevice().getPollData(object); + float result; + if (object.isRelative()) { + result = object.getRelativePollValue(poll_data); + } else { + result = poll_data; + } + return object.convertValue(result); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIDeviceObject.java b/plugins/windows/src/java/net/java/games/input/DIDeviceObject.java new file mode 100644 index 0000000..a7c43c8 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIDeviceObject.java @@ -0,0 +1,207 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper for DIDEVICEOBJECTINSTANCE + * @author elias + * @version 1.0 + */ +final class DIDeviceObject { + //DirectInput scales wheel deltas by 120 + private final static int WHEEL_SCALE = 120; + + private final IDirectInputDevice device; + private final byte[] guid; + private final int identifier; + private final int type; + private final int instance; + private final int guid_type; + private final int flags; + private final String name; + private final Component.Identifier id; + private final int format_offset; + private final long min; + private final long max; + private final int deadzone; + + /* These are used for emulating relative axes */ + private int last_poll_value; + private int last_event_value; + + public DIDeviceObject(IDirectInputDevice device, Component.Identifier id, byte[] guid, int guid_type, int identifier, int type, int instance, int flags, String name, int format_offset) throws IOException { + this.device = device; + this.id = id; + this.guid = guid; + this.identifier = identifier; + this.type = type; + this.instance = instance; + this.guid_type = guid_type; + this.flags = flags; + this.name = name; + this.format_offset = format_offset; + if (isAxis() && !isRelative()) { + long[] range = device.getRangeProperty(identifier); + this.min = range[0]; + this.max = range[1]; + this.deadzone = device.getDeadzoneProperty(identifier); + } else { + this.min = IDirectInputDevice.DIPROPRANGE_NOMIN; + this.max = IDirectInputDevice.DIPROPRANGE_NOMAX; + this.deadzone = 0; + } + } + + public final synchronized int getRelativePollValue(int current_abs_value) { + int rel_value = current_abs_value - last_poll_value; + last_poll_value = current_abs_value; + return rel_value; + } + + public final synchronized int getRelativeEventValue(int current_abs_value) { + int rel_value = current_abs_value - last_event_value; + last_event_value = current_abs_value; + return rel_value; + } + + public final int getGUIDType() { + return guid_type; + } + + public final int getFormatOffset() { + return format_offset; + } + + public final IDirectInputDevice getDevice() { + return device; + } + + public final int getDIIdentifier() { + return identifier; + } + + public final Component.Identifier getIdentifier() { + return id; + } + + public final String getName() { + return name; + } + + public final int getInstance() { + return instance; + } + + public final int getType() { + return type; + } + + public final byte[] getGUID() { + return guid; + } + + public final int getFlags() { + return flags; + } + + public final long getMin() { + return min; + } + + public final long getMax() { + return max; + } + + public final float getDeadzone() { + return deadzone; + } + + public final boolean isButton() { + return (type & IDirectInputDevice.DIDFT_BUTTON) != 0; + } + + private final boolean isAxis() { + return (type & IDirectInputDevice.DIDFT_AXIS) != 0; + } + + public final boolean isRelative() { + return isAxis() && (type & IDirectInputDevice.DIDFT_RELAXIS) != 0; + } + + public final boolean isAnalog() { + return isAxis() && id != Component.Identifier.Axis.POV; + } + + public final float convertValue(float value) { + if (getDevice().getType() == IDirectInputDevice.DI8DEVTYPE_MOUSE && id == Component.Identifier.Axis.Z) { + return value/WHEEL_SCALE; + } else if (isButton()) { + return (((int)value) & 0x80) != 0 ? 1 : 0; + } else if (id == Component.Identifier.Axis.POV) { + int int_value = (int)value; + if ((int_value & 0xFFFF) == 0xFFFF) + return Component.POV.OFF; + // DirectInput returns POV directions in hundredths of degree clockwise from north + int slice = 360*100/16; + if (int_value >= 0 && int_value < slice) + return Component.POV.UP; + else if (int_value < 3*slice) + return Component.POV.UP_RIGHT; + else if (int_value < 5*slice) + return Component.POV.RIGHT; + else if (int_value < 7*slice) + return Component.POV.DOWN_RIGHT; + else if (int_value < 9*slice) + return Component.POV.DOWN; + else if (int_value < 11*slice) + return Component.POV.DOWN_LEFT; + else if (int_value < 13*slice) + return Component.POV.LEFT; + else if (int_value < 15*slice) + return Component.POV.UP_LEFT; + else + return Component.POV.UP; + } else if (isAxis() && !isRelative()) { + return 2*(value - min)/(float)(max - min) - 1; + } else + return value; + } + +} diff --git a/plugins/windows/src/java/net/java/games/input/DIDeviceObjectData.java b/plugins/windows/src/java/net/java/games/input/DIDeviceObjectData.java new file mode 100644 index 0000000..fa84a9d --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIDeviceObjectData.java @@ -0,0 +1,73 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +/** Java wrapper for DIDEVICEOBJECTDATA + * @author elias + * @version 1.0 + */ +final class DIDeviceObjectData { + private int format_offset; + private int data; + private int millis; + private int sequence; + + public final void set(int format_offset, int data, int millis, int sequence) { + this.format_offset = format_offset; + this.data = data; + this.millis = millis; + this.sequence = sequence; + } + + public final void set(DIDeviceObjectData other) { + set(other.format_offset, other.data, other.millis, other.sequence); + } + + public final int getData() { + return data; + } + + public final int getFormatOffset() { + return format_offset; + } + + public final long getNanos() { + return millis*1000000L; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIEffectInfo.java b/plugins/windows/src/java/net/java/games/input/DIEffectInfo.java new file mode 100644 index 0000000..5ece8a3 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIEffectInfo.java @@ -0,0 +1,83 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +/** Java wrapper for DIEFFECTINFO + * @author elias + * @version 1.0 + */ +final class DIEffectInfo { + private final IDirectInputDevice device; + private final byte[] guid; + private final int guid_id; + private final int effect_type; + private final int static_params; + private final int dynamic_params; + private final String name; + + public DIEffectInfo(IDirectInputDevice device, byte[] guid, int guid_id, int effect_type, int static_params, int dynamic_params, String name) { + this.device = device; + this.guid = guid; + this.guid_id = guid_id; + this.effect_type = effect_type; + this.static_params = static_params; + this.dynamic_params = dynamic_params; + this.name = name; + } + + public final byte[] getGUID() { + return guid; + } + + public final int getGUIDId() { + return guid_id; + } + + public final int getDynamicParams() { + return dynamic_params; + } + + public final int getEffectType() { + return effect_type; + } + + public final String getName() { + return name; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIIdentifierMap.java b/plugins/windows/src/java/net/java/games/input/DIIdentifierMap.java new file mode 100644 index 0000000..f9c06a8 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIIdentifierMap.java @@ -0,0 +1,544 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +/** + * @author elias + * @version 1.0 + */ +final class DIIdentifierMap { + public final static int DIK_ESCAPE = 0x01; + public final static int DIK_1 = 0x02; + public final static int DIK_2 = 0x03; + public final static int DIK_3 = 0x04; + public final static int DIK_4 = 0x05; + public final static int DIK_5 = 0x06; + public final static int DIK_6 = 0x07; + public final static int DIK_7 = 0x08; + public final static int DIK_8 = 0x09; + public final static int DIK_9 = 0x0A; + public final static int DIK_0 = 0x0B; + public final static int DIK_MINUS = 0x0C; /* - on main keyboard */ + public final static int DIK_EQUALS = 0x0D; + public final static int DIK_BACK = 0x0E; /* backspace */ + public final static int DIK_TAB = 0x0F; + public final static int DIK_Q = 0x10; + public final static int DIK_W = 0x11; + public final static int DIK_E = 0x12; + public final static int DIK_R = 0x13; + public final static int DIK_T = 0x14; + public final static int DIK_Y = 0x15; + public final static int DIK_U = 0x16; + public final static int DIK_I = 0x17; + public final static int DIK_O = 0x18; + public final static int DIK_P = 0x19; + public final static int DIK_LBRACKET = 0x1A; + public final static int DIK_RBRACKET = 0x1B; + public final static int DIK_RETURN = 0x1C; /* Enter on main keyboard */ + public final static int DIK_LCONTROL = 0x1D; + public final static int DIK_A = 0x1E; + public final static int DIK_S = 0x1F; + public final static int DIK_D = 0x20; + public final static int DIK_F = 0x21; + public final static int DIK_G = 0x22; + public final static int DIK_H = 0x23; + public final static int DIK_J = 0x24; + public final static int DIK_K = 0x25; + public final static int DIK_L = 0x26; + public final static int DIK_SEMICOLON = 0x27; + public final static int DIK_APOSTROPHE = 0x28; + public final static int DIK_GRAVE = 0x29; /* accent grave */ + public final static int DIK_LSHIFT = 0x2A; + public final static int DIK_BACKSLASH = 0x2B; + public final static int DIK_Z = 0x2C; + public final static int DIK_X = 0x2D; + public final static int DIK_C = 0x2E; + public final static int DIK_V = 0x2F; + public final static int DIK_B = 0x30; + public final static int DIK_N = 0x31; + public final static int DIK_M = 0x32; + public final static int DIK_COMMA = 0x33; + public final static int DIK_PERIOD = 0x34; /* . on main keyboard */ + public final static int DIK_SLASH = 0x35; /* / on main keyboard */ + public final static int DIK_RSHIFT = 0x36; + public final static int DIK_MULTIPLY = 0x37; /* * on numeric keypad */ + public final static int DIK_LMENU = 0x38; /* left Alt */ + public final static int DIK_SPACE = 0x39; + public final static int DIK_CAPITAL = 0x3A; + public final static int DIK_F1 = 0x3B; + public final static int DIK_F2 = 0x3C; + public final static int DIK_F3 = 0x3D; + public final static int DIK_F4 = 0x3E; + public final static int DIK_F5 = 0x3F; + public final static int DIK_F6 = 0x40; + public final static int DIK_F7 = 0x41; + public final static int DIK_F8 = 0x42; + public final static int DIK_F9 = 0x43; + public final static int DIK_F10 = 0x44; + public final static int DIK_NUMLOCK = 0x45; + public final static int DIK_SCROLL = 0x46; /* Scroll Lock */ + public final static int DIK_NUMPAD7 = 0x47; + public final static int DIK_NUMPAD8 = 0x48; + public final static int DIK_NUMPAD9 = 0x49; + public final static int DIK_SUBTRACT = 0x4A; /* - on numeric keypad */ + public final static int DIK_NUMPAD4 = 0x4B; + public final static int DIK_NUMPAD5 = 0x4C; + public final static int DIK_NUMPAD6 = 0x4D; + public final static int DIK_ADD = 0x4E; /* + on numeric keypad */ + public final static int DIK_NUMPAD1 = 0x4F; + public final static int DIK_NUMPAD2 = 0x50; + public final static int DIK_NUMPAD3 = 0x51; + public final static int DIK_NUMPAD0 = 0x52; + public final static int DIK_DECIMAL = 0x53; /* . on numeric keypad */ + public final static int DIK_OEM_102 = 0x56; /* <> or \| on RT 102-key keyboard (Non-U.S.) */ + public final static int DIK_F11 = 0x57; + public final static int DIK_F12 = 0x58; + public final static int DIK_F13 = 0x64; /* (NEC PC98) */ + public final static int DIK_F14 = 0x65; /* (NEC PC98) */ + public final static int DIK_F15 = 0x66; /* (NEC PC98) */ + public final static int DIK_KANA = 0x70; /* (Japanese keyboard) */ + public final static int DIK_ABNT_C1 = 0x73; /* /? on Brazilian keyboard */ + public final static int DIK_CONVERT = 0x79; /* (Japanese keyboard) */ + public final static int DIK_NOCONVERT = 0x7B; /* (Japanese keyboard) */ + public final static int DIK_YEN = 0x7D; /* (Japanese keyboard) */ + public final static int DIK_ABNT_C2 = 0x7E; /* Numpad . on Brazilian keyboard */ + public final static int DIK_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */ + public final static int DIK_PREVTRACK = 0x90; /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ + public final static int DIK_AT = 0x91; /* (NEC PC98) */ + public final static int DIK_COLON = 0x92; /* (NEC PC98) */ + public final static int DIK_UNDERLINE = 0x93; /* (NEC PC98) */ + public final static int DIK_KANJI = 0x94; /* (Japanese keyboard) */ + public final static int DIK_STOP = 0x95; /* (NEC PC98) */ + public final static int DIK_AX = 0x96; /* (Japan AX) */ + public final static int DIK_UNLABELED = 0x97; /* (J3100) */ + public final static int DIK_NEXTTRACK = 0x99; /* Next Track */ + public final static int DIK_NUMPADENTER = 0x9C; /* Enter on numeric keypad */ + public final static int DIK_RCONTROL = 0x9D; + public final static int DIK_MUTE = 0xA0; /* Mute */ + public final static int DIK_CALCULATOR = 0xA1; /* Calculator */ + public final static int DIK_PLAYPAUSE = 0xA2; /* Play / Pause */ + public final static int DIK_MEDIASTOP = 0xA4; /* Media Stop */ + public final static int DIK_VOLUMEDOWN = 0xAE; /* Volume - */ + public final static int DIK_VOLUMEUP = 0xB0; /* Volume + */ + public final static int DIK_WEBHOME = 0xB2; /* Web home */ + public final static int DIK_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */ + public final static int DIK_DIVIDE = 0xB5; /* / on numeric keypad */ + public final static int DIK_SYSRQ = 0xB7; + public final static int DIK_RMENU = 0xB8; /* right Alt */ + public final static int DIK_PAUSE = 0xC5; /* Pause */ + public final static int DIK_HOME = 0xC7; /* Home on arrow keypad */ + public final static int DIK_UP = 0xC8; /* UpArrow on arrow keypad */ + public final static int DIK_PRIOR = 0xC9; /* PgUp on arrow keypad */ + public final static int DIK_LEFT = 0xCB; /* LeftArrow on arrow keypad */ + public final static int DIK_RIGHT = 0xCD; /* RightArrow on arrow keypad */ + public final static int DIK_END = 0xCF; /* End on arrow keypad */ + public final static int DIK_DOWN = 0xD0; /* DownArrow on arrow keypad */ + public final static int DIK_NEXT = 0xD1; /* PgDn on arrow keypad */ + public final static int DIK_INSERT = 0xD2; /* Insert on arrow keypad */ + public final static int DIK_DELETE = 0xD3; /* Delete on arrow keypad */ + public final static int DIK_LWIN = 0xDB; /* Left Windows key */ + public final static int DIK_RWIN = 0xDC; /* Right Windows key */ + public final static int DIK_APPS = 0xDD; /* AppMenu key */ + public final static int DIK_POWER = 0xDE; /* System Power */ + public final static int DIK_SLEEP = 0xDF; /* System Sleep */ + public final static int DIK_WAKE = 0xE3; /* System Wake */ + public final static int DIK_WEBSEARCH = 0xE5; /* Web Search */ + public final static int DIK_WEBFAVORITES = 0xE6; /* Web Favorites */ + public final static int DIK_WEBREFRESH = 0xE7; /* Web Refresh */ + public final static int DIK_WEBSTOP = 0xE8; /* Web Stop */ + public final static int DIK_WEBFORWARD = 0xE9; /* Web Forward */ + public final static int DIK_WEBBACK = 0xEA; /* Web Back */ + public final static int DIK_MYCOMPUTER = 0xEB; /* My Computer */ + public final static int DIK_MAIL = 0xEC; /* Mail */ + public final static int DIK_MEDIASELECT = 0xED; /* Media Select */ + + public final static Component.Identifier.Key getKeyIdentifier(int key_code) { + switch (key_code) { + case DIK_ESCAPE: + return Component.Identifier.Key.ESCAPE; + case DIK_1: + return Component.Identifier.Key._1; + case DIK_2: + return Component.Identifier.Key._2; + case DIK_3: + return Component.Identifier.Key._3; + case DIK_4: + return Component.Identifier.Key._4; + case DIK_5: + return Component.Identifier.Key._5; + case DIK_6: + return Component.Identifier.Key._6; + case DIK_7: + return Component.Identifier.Key._7; + case DIK_8: + return Component.Identifier.Key._8; + case DIK_9: + return Component.Identifier.Key._9; + case DIK_0: + return Component.Identifier.Key._0; + case DIK_MINUS: + return Component.Identifier.Key.MINUS; + case DIK_EQUALS: + return Component.Identifier.Key.EQUALS; + case DIK_BACK: + return Component.Identifier.Key.BACK; + case DIK_TAB: + return Component.Identifier.Key.TAB; + case DIK_Q: + return Component.Identifier.Key.Q; + case DIK_W: + return Component.Identifier.Key.W; + case DIK_E: + return Component.Identifier.Key.E; + case DIK_R: + return Component.Identifier.Key.R; + case DIK_T: + return Component.Identifier.Key.T; + case DIK_Y: + return Component.Identifier.Key.Y; + case DIK_U: + return Component.Identifier.Key.U; + case DIK_I: + return Component.Identifier.Key.I; + case DIK_O: + return Component.Identifier.Key.O; + case DIK_P: + return Component.Identifier.Key.P; + case DIK_LBRACKET: + return Component.Identifier.Key.LBRACKET; + case DIK_RBRACKET: + return Component.Identifier.Key.RBRACKET; + case DIK_RETURN: + return Component.Identifier.Key.RETURN; + case DIK_LCONTROL: + return Component.Identifier.Key.LCONTROL; + case DIK_A: + return Component.Identifier.Key.A; + case DIK_S: + return Component.Identifier.Key.S; + case DIK_D: + return Component.Identifier.Key.D; + case DIK_F: + return Component.Identifier.Key.F; + case DIK_G: + return Component.Identifier.Key.G; + case DIK_H: + return Component.Identifier.Key.H; + case DIK_J: + return Component.Identifier.Key.J; + case DIK_K: + return Component.Identifier.Key.K; + case DIK_L: + return Component.Identifier.Key.L; + case DIK_SEMICOLON: + return Component.Identifier.Key.SEMICOLON; + case DIK_APOSTROPHE: + return Component.Identifier.Key.APOSTROPHE; + case DIK_GRAVE: + return Component.Identifier.Key.GRAVE; + case DIK_LSHIFT: + return Component.Identifier.Key.LSHIFT; + case DIK_BACKSLASH: + return Component.Identifier.Key.BACKSLASH; + case DIK_Z: + return Component.Identifier.Key.Z; + case DIK_X: + return Component.Identifier.Key.X; + case DIK_C: + return Component.Identifier.Key.C; + case DIK_V: + return Component.Identifier.Key.V; + case DIK_B: + return Component.Identifier.Key.B; + case DIK_N: + return Component.Identifier.Key.N; + case DIK_M: + return Component.Identifier.Key.M; + case DIK_COMMA: + return Component.Identifier.Key.COMMA; + case DIK_PERIOD: + return Component.Identifier.Key.PERIOD; + case DIK_SLASH: + return Component.Identifier.Key.SLASH; + case DIK_RSHIFT: + return Component.Identifier.Key.RSHIFT; + case DIK_MULTIPLY: + return Component.Identifier.Key.MULTIPLY; + case DIK_LMENU: + return Component.Identifier.Key.LALT; + case DIK_SPACE: + return Component.Identifier.Key.SPACE; + case DIK_CAPITAL: + return Component.Identifier.Key.CAPITAL; + case DIK_F1: + return Component.Identifier.Key.F1; + case DIK_F2: + return Component.Identifier.Key.F2; + case DIK_F3: + return Component.Identifier.Key.F3; + case DIK_F4: + return Component.Identifier.Key.F4; + case DIK_F5: + return Component.Identifier.Key.F5; + case DIK_F6: + return Component.Identifier.Key.F6; + case DIK_F7: + return Component.Identifier.Key.F7; + case DIK_F8: + return Component.Identifier.Key.F8; + case DIK_F9: + return Component.Identifier.Key.F9; + case DIK_F10: + return Component.Identifier.Key.F10; + case DIK_NUMLOCK: + return Component.Identifier.Key.NUMLOCK; + case DIK_SCROLL: + return Component.Identifier.Key.SCROLL; + case DIK_NUMPAD7: + return Component.Identifier.Key.NUMPAD7; + case DIK_NUMPAD8: + return Component.Identifier.Key.NUMPAD8; + case DIK_NUMPAD9: + return Component.Identifier.Key.NUMPAD9; + case DIK_SUBTRACT: + return Component.Identifier.Key.SUBTRACT; + case DIK_NUMPAD4: + return Component.Identifier.Key.NUMPAD4; + case DIK_NUMPAD5: + return Component.Identifier.Key.NUMPAD5; + case DIK_NUMPAD6: + return Component.Identifier.Key.NUMPAD6; + case DIK_ADD: + return Component.Identifier.Key.ADD; + case DIK_NUMPAD1: + return Component.Identifier.Key.NUMPAD1; + case DIK_NUMPAD2: + return Component.Identifier.Key.NUMPAD2; + case DIK_NUMPAD3: + return Component.Identifier.Key.NUMPAD3; + case DIK_NUMPAD0: + return Component.Identifier.Key.NUMPAD0; + case DIK_DECIMAL: + return Component.Identifier.Key.DECIMAL; + case DIK_F11: + return Component.Identifier.Key.F11; + case DIK_F12: + return Component.Identifier.Key.F12; + case DIK_F13: + return Component.Identifier.Key.F13; + case DIK_F14: + return Component.Identifier.Key.F14; + case DIK_F15: + return Component.Identifier.Key.F15; + case DIK_KANA: + return Component.Identifier.Key.KANA; + case DIK_CONVERT: + return Component.Identifier.Key.CONVERT; + case DIK_NOCONVERT: + return Component.Identifier.Key.NOCONVERT; + case DIK_YEN: + return Component.Identifier.Key.YEN; + case DIK_NUMPADEQUALS: + return Component.Identifier.Key.NUMPADEQUAL; + case DIK_AT: + return Component.Identifier.Key.AT; + case DIK_COLON: + return Component.Identifier.Key.COLON; + case DIK_UNDERLINE: + return Component.Identifier.Key.UNDERLINE; + case DIK_KANJI: + return Component.Identifier.Key.KANJI; + case DIK_STOP: + return Component.Identifier.Key.STOP; + case DIK_AX: + return Component.Identifier.Key.AX; + case DIK_UNLABELED: + return Component.Identifier.Key.UNLABELED; + case DIK_NUMPADENTER: + return Component.Identifier.Key.NUMPADENTER; + case DIK_RCONTROL: + return Component.Identifier.Key.RCONTROL; + case DIK_NUMPADCOMMA: + return Component.Identifier.Key.NUMPADCOMMA; + case DIK_DIVIDE: + return Component.Identifier.Key.DIVIDE; + case DIK_SYSRQ: + return Component.Identifier.Key.SYSRQ; + case DIK_RMENU: + return Component.Identifier.Key.RALT; + case DIK_PAUSE: + return Component.Identifier.Key.PAUSE; + case DIK_HOME: + return Component.Identifier.Key.HOME; + case DIK_UP: + return Component.Identifier.Key.UP; + case DIK_PRIOR: + return Component.Identifier.Key.PAGEUP; + case DIK_LEFT: + return Component.Identifier.Key.LEFT; + case DIK_RIGHT: + return Component.Identifier.Key.RIGHT; + case DIK_END: + return Component.Identifier.Key.END; + case DIK_DOWN: + return Component.Identifier.Key.DOWN; + case DIK_NEXT: + return Component.Identifier.Key.PAGEDOWN; + case DIK_INSERT: + return Component.Identifier.Key.INSERT; + case DIK_DELETE: + return Component.Identifier.Key.DELETE; + case DIK_LWIN: + return Component.Identifier.Key.LWIN; + case DIK_RWIN: + return Component.Identifier.Key.RWIN; + case DIK_APPS: + return Component.Identifier.Key.APPS; + case DIK_POWER: + return Component.Identifier.Key.POWER; + case DIK_SLEEP: + return Component.Identifier.Key.SLEEP; + /* Unassigned keys */ + case DIK_ABNT_C1: + case DIK_ABNT_C2: + case DIK_PREVTRACK: + case DIK_PLAYPAUSE: + case DIK_NEXTTRACK: + case DIK_MUTE: + case DIK_CALCULATOR: + case DIK_MEDIASTOP: + case DIK_VOLUMEDOWN: + case DIK_VOLUMEUP: + case DIK_WEBHOME: + case DIK_WAKE: + case DIK_WEBSEARCH: + case DIK_WEBFAVORITES: + case DIK_WEBREFRESH: + case DIK_WEBSTOP: + case DIK_WEBFORWARD: + case DIK_WEBBACK: + case DIK_MYCOMPUTER: + case DIK_MAIL: + case DIK_MEDIASELECT: + case DIK_OEM_102: + default: + return Component.Identifier.Key.UNKNOWN; + } + } + + public final static Component.Identifier.Button getButtonIdentifier(int id) { + switch (id) { + case 0: + return Component.Identifier.Button._0; + case 1: + return Component.Identifier.Button._1; + case 2: + return Component.Identifier.Button._2; + case 3: + return Component.Identifier.Button._3; + case 4: + return Component.Identifier.Button._4; + case 5: + return Component.Identifier.Button._5; + case 6: + return Component.Identifier.Button._6; + case 7: + return Component.Identifier.Button._7; + case 8: + return Component.Identifier.Button._8; + case 9: + return Component.Identifier.Button._9; + case 10: + return Component.Identifier.Button._10; + case 11: + return Component.Identifier.Button._11; + case 12: + return Component.Identifier.Button._12; + case 13: + return Component.Identifier.Button._13; + case 14: + return Component.Identifier.Button._14; + case 15: + return Component.Identifier.Button._15; + case 16: + return Component.Identifier.Button._16; + case 17: + return Component.Identifier.Button._17; + case 18: + return Component.Identifier.Button._18; + case 19: + return Component.Identifier.Button._19; + case 20: + return Component.Identifier.Button._20; + case 21: + return Component.Identifier.Button._21; + case 22: + return Component.Identifier.Button._23; + case 23: + return Component.Identifier.Button._24; + case 24: + return Component.Identifier.Button._25; + case 25: + return Component.Identifier.Button._26; + case 26: + return Component.Identifier.Button._27; + case 27: + return Component.Identifier.Button._28; + case 28: + return Component.Identifier.Button._29; + case 29: + return Component.Identifier.Button._30; + case 30: + return Component.Identifier.Button._31; + default: + return null; + } + } + + public final static Component.Identifier.Button mapMouseButtonIdentifier(Component.Identifier.Button button_id) { + if (button_id == Component.Identifier.Button._0) { + return Component.Identifier.Button.LEFT; + } else if (button_id == Component.Identifier.Button._1) { + return Component.Identifier.Button.RIGHT; + } else if (button_id == Component.Identifier.Button._2) { + return Component.Identifier.Button.MIDDLE; + } else + return button_id; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIKeyboard.java b/plugins/windows/src/java/net/java/games/input/DIKeyboard.java new file mode 100644 index 0000000..6eec1b7 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIKeyboard.java @@ -0,0 +1,66 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** +* @author elias +* @version 1.0 +*/ +final class DIKeyboard extends Keyboard { + private final IDirectInputDevice device; + + protected DIKeyboard(IDirectInputDevice device, Component[] components, Controller[] children, Rumbler[] rumblers) { + super(device.getProductName(), components, children, rumblers); + this.device = device; + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return DIControllers.getNextDeviceEvent(event, device); + } + + public final void pollDevice() throws IOException { + device.pollAll(); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + device.setBufferSize(size); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DIMouse.java b/plugins/windows/src/java/net/java/games/input/DIMouse.java new file mode 100644 index 0000000..e24ff77 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DIMouse.java @@ -0,0 +1,67 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** +* @author elias +* @version 1.0 +*/ +final class DIMouse extends Mouse { + private final IDirectInputDevice device; + + protected DIMouse(IDirectInputDevice device, Component[] components, Controller[] children, Rumbler[] rumblers) { + super(device.getProductName(), components, children, rumblers); + this.device = device; + } + + public final void pollDevice() throws IOException { + device.pollAll(); + } + + protected final boolean getNextDeviceEvent(Event event) throws IOException { + return DIControllers.getNextDeviceEvent(event, device); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + device.setBufferSize(size); + } + +} diff --git a/plugins/windows/src/java/net/java/games/input/DataQueue.java b/plugins/windows/src/java/net/java/games/input/DataQueue.java new file mode 100644 index 0000000..8151d3f --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DataQueue.java @@ -0,0 +1,125 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +/** + * @author elias + * @version 1.0 + */ +final class DataQueue { + private final Object[] elements; + private int position; + private int limit; + + public DataQueue(int size, Class element_type) { + this.elements= new Object[size]; + for (int i = 0; i < elements.length; i++) { + try { + elements[i] = element_type.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + clear(); + } + + public final void clear() { + position = 0; + limit = elements.length; + } + + public final int position() { + return position; + } + + public final int limit() { + return limit; + } + + public final Object get(int index) { + assert index < limit; + return elements[index]; + } + + public final Object get() { + if (!hasRemaining()) + return null; + return get(position++); + } + + public final void compact() { + int index = 0; + while (hasRemaining()) { + swap(position, index); + position++; + index++; + } + position = index; + limit = elements.length; + } + + private final void swap(int index1, int index2) { + Object temp = elements[index1]; + elements[index1] = elements[index2]; + elements[index2] = temp; + } + + public final void flip() { + limit = position; + position = 0; + } + + public final boolean hasRemaining() { + return remaining() > 0; + } + + public final int remaining() { + return limit - position; + } + + public final void position(int position) { + this.position = position; + } + + public final Object[] getElements() { + return elements; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java b/plugins/windows/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java new file mode 100644 index 0000000..46c9b7d --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java @@ -0,0 +1,186 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.List; +import java.util.ArrayList; +import java.io.IOException; + +import net.java.games.util.plugins.Plugin; + +/** DirectInput implementation of controller environment + * @author martak + * @author elias + * @version 1.0 + */ +public final class DirectInputEnvironmentPlugin extends ControllerEnvironment implements Plugin { + static { + AccessController.doPrivileged( + new PrivilegedAction() { + public final Object run() { + System.loadLibrary("jinput-dx8"); + return null; + } + }); + } + + private final Controller[] controllers; + private final List active_devices = new ArrayList(); + private final DummyWindow window; + + /** Creates new DirectInputEnvironment */ + public DirectInputEnvironmentPlugin() { + DummyWindow window = null; + Controller[] controllers = new Controller[]{}; + try { + window = new DummyWindow(); + try { + controllers = enumControllers(window); + } catch (IOException e) { + window.destroy(); + throw e; + } + } catch (IOException e) { + ControllerEnvironment.logln("Failed to enumerate devices: " + e.getMessage()); + } + 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() { + return controllers; + } + + private final Component[] createComponents(IDirectInputDevice device, boolean map_mouse_buttons) { + List device_objects = device.getObjects(); + List controller_components = new ArrayList(); + for (int i = 0; i < device_objects.size(); i++) { + DIDeviceObject device_object = (DIDeviceObject)device_objects.get(i); + Component.Identifier identifier = device_object.getIdentifier(); + if (map_mouse_buttons && identifier instanceof Component.Identifier.Button) { + identifier = DIIdentifierMap.mapMouseButtonIdentifier((Component.Identifier.Button)identifier); + } + DIComponent component = new DIComponent(identifier, device_object); + controller_components.add(component); + device.registerComponent(device_object, component); + } + Component[] components = new Component[controller_components.size()]; + controller_components.toArray(components); + return components; + } + + private final Mouse createMouseFromDevice(IDirectInputDevice device) { + Component[] components = createComponents(device, true); + Mouse mouse = new DIMouse(device, components, new Controller[]{}, device.getRumblers()); + if (mouse.getX() != null && mouse.getY() != null && mouse.getLeft() != null) + return mouse; + else + return null; + } + + private final AbstractController createControllerFromDevice(IDirectInputDevice device, Controller.Type type) { + Component[] components = createComponents(device, false); + AbstractController controller = new DIAbstractController(device, components, new Controller[]{}, device.getRumblers(), type); + return controller; + } + + private final Keyboard createKeyboardFromDevice(IDirectInputDevice device) { + Component[] components = createComponents(device, false); + return new DIKeyboard(device, components, new Controller[]{}, device.getRumblers()); + } + + private final Controller createControllerFromDevice(IDirectInputDevice device) { + switch (device.getType()) { + case IDirectInputDevice.DI8DEVTYPE_MOUSE: + return createMouseFromDevice(device); + case IDirectInputDevice.DI8DEVTYPE_KEYBOARD: + return createKeyboardFromDevice(device); + case IDirectInputDevice.DI8DEVTYPE_JOYSTICK: + return createControllerFromDevice(device, Controller.Type.STICK); + case IDirectInputDevice.DI8DEVTYPE_GAMEPAD: + return createControllerFromDevice(device, Controller.Type.GAMEPAD); + default: + return null; + } + } + + private final Controller[] enumControllers(DummyWindow window) throws IOException { + List controllers = new ArrayList(); + IDirectInput dinput = new IDirectInput(window); + try { + List devices = dinput.getDevices(); + for (int i = 0; i < devices.size(); i++) { + IDirectInputDevice device = (IDirectInputDevice)devices.get(i); + Controller controller = createControllerFromDevice(device); + if (controller != null) { + controllers.add(controller); + active_devices.add(device); + } else + device.release(); + } + } finally { + dinput.release(); + } + Controller[] controllers_array = new Controller[controllers.size()]; + controllers.toArray(controllers_array); + return controllers_array; + } + + private final class ShutdownHook extends Thread { + public final void run() { + /* Release the devices to kill off active force feedback effects */ + for (int i = 0; i < active_devices.size(); i++) { + IDirectInputDevice device = (IDirectInputDevice)active_devices.get(i); + device.release(); + } + /* We won't release the window since it is + * owned by the thread that created the environment. + */ + } + } +} // class DirectInputEnvironment diff --git a/plugins/windows/src/java/net/java/games/input/DummyWindow.java b/plugins/windows/src/java/net/java/games/input/DummyWindow.java new file mode 100644 index 0000000..5c66d9a --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DummyWindow.java @@ -0,0 +1,64 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper for a (dummy) window + * @author martak + * @author elias + * @version 1.0 + */ +final class DummyWindow { + private final long hwnd_address; + + public DummyWindow() throws IOException { + this.hwnd_address = createWindow(); + } + private final static native long createWindow() throws IOException; + + public final void destroy() throws IOException { + nDestroy(hwnd_address); + } + private final static native void nDestroy(long hwnd_address) throws IOException; + + public final long getHwnd() { + return hwnd_address; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/IDirectInput.java b/plugins/windows/src/java/net/java/games/input/IDirectInput.java new file mode 100644 index 0000000..8cef150 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/IDirectInput.java @@ -0,0 +1,95 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; + +/** Java wrapper for IDirectInput + * @author martak + * @author elias + * @version 1.0 + */ +final class IDirectInput { + private final List devices = new ArrayList(); + private final long idirectinput_address; + private final DummyWindow window; + + public IDirectInput(DummyWindow window) throws IOException { + this.window = window; + this.idirectinput_address = createIDirectInput(); + try { + enumDevices(); + } catch (IOException e) { + releaseDevices(); + release(); + throw e; + } + } + private final static native long createIDirectInput() throws IOException; + + public final List getDevices() { + return devices; + } + + private final void enumDevices() throws IOException { + nEnumDevices(idirectinput_address); + } + private final native void nEnumDevices(long addr) throws IOException; + + /* This method is called from native code in nEnumDevices + * native side will clean up in case of an exception + */ + private final void addDevice(long address, byte[] instance_guid, byte[] product_guid, int dev_type, int dev_subtype, String instance_name, String product_name) throws IOException { + devices.add(new IDirectInputDevice(window, address, instance_guid, product_guid, dev_type, dev_subtype, instance_name, product_name)); + } + + public final void releaseDevices() { + for (int i = 0; i < devices.size(); i++) { + IDirectInputDevice device = (IDirectInputDevice)devices.get(i); + device.release(); + } + } + + public final void release() { + nRelease(idirectinput_address); + } + private final static native void nRelease(long address); +} diff --git a/plugins/windows/src/java/net/java/games/input/IDirectInputDevice.java b/plugins/windows/src/java/net/java/games/input/IDirectInputDevice.java new file mode 100644 index 0000000..ef061cd --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/IDirectInputDevice.java @@ -0,0 +1,519 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Arrays; + +/** Java wrapper for IDirectInputDevice + * @author martak + * @author elias + * @version 1.0 + */ +final class IDirectInputDevice { + public final static int GUID_XAxis = 1; + public final static int GUID_YAxis = 2; + public final static int GUID_ZAxis = 3; + public final static int GUID_RxAxis = 4; + public final static int GUID_RyAxis = 5; + public final static int GUID_RzAxis = 6; + public final static int GUID_Slider = 7; + public final static int GUID_Button = 8; + public final static int GUID_Key = 9; + public final static int GUID_POV = 10; + public final static int GUID_Unknown = 11; + + public final static int GUID_ConstantForce = 12; + public final static int GUID_RampForce = 13; + public final static int GUID_Square = 14; + public final static int GUID_Sine = 15; + public final static int GUID_Triangle = 16; + public final static int GUID_SawtoothUp = 17; + public final static int GUID_SawtoothDown = 18; + public final static int GUID_Spring = 19; + public final static int GUID_Damper = 20; + public final static int GUID_Inertia = 21; + public final static int GUID_Friction = 22; + public final static int GUID_CustomForce = 23; + + public final static int DI8DEVTYPE_DEVICE = 0x11; + public final static int DI8DEVTYPE_MOUSE = 0x12; + public final static int DI8DEVTYPE_KEYBOARD = 0x13; + public final static int DI8DEVTYPE_JOYSTICK = 0x14; + public final static int DI8DEVTYPE_GAMEPAD = 0x15; + public final static int DI8DEVTYPE_DRIVING = 0x16; + public final static int DI8DEVTYPE_FLIGHT = 0x17; + public final static int DI8DEVTYPE_1STPERSON = 0x18; + public final static int DI8DEVTYPE_DEVICECTRL = 0x19; + public final static int DI8DEVTYPE_SCREENPOINTER = 0x1A; + public final static int DI8DEVTYPE_REMOTE = 0x1B; + public final static int DI8DEVTYPE_SUPPLEMENTAL = 0x1C; + + public final static int DISCL_EXCLUSIVE = 0x00000001; + public final static int DISCL_NONEXCLUSIVE = 0x00000002; + public final static int DISCL_FOREGROUND = 0x00000004; + public final static int DISCL_BACKGROUND = 0x00000008; + public final static int DISCL_NOWINKEY = 0x00000010; + + public final static int DIDFT_ALL = 0x00000000; + + public final static int DIDFT_RELAXIS = 0x00000001; + public final static int DIDFT_ABSAXIS = 0x00000002; + public final static int DIDFT_AXIS = 0x00000003; + + public final static int DIDFT_PSHBUTTON = 0x00000004; + public final static int DIDFT_TGLBUTTON = 0x00000008; + public final static int DIDFT_BUTTON = 0x0000000C; + + public final static int DIDFT_POV = 0x00000010; + public final static int DIDFT_COLLECTION = 0x00000040; + public final static int DIDFT_NODATA = 0x00000080; + + public final static int DIDFT_FFACTUATOR = 0x01000000; + public final static int DIDFT_FFEFFECTTRIGGER = 0x02000000; + public final static int DIDFT_OUTPUT = 0x10000000; + public final static int DIDFT_VENDORDEFINED = 0x04000000; + public final static int DIDFT_ALIAS = 0x08000000; + public final static int DIDFT_OPTIONAL = 0x80000000; + + public final static int DIDFT_NOCOLLECTION = 0x00FFFF00; + + public final static int DIDF_ABSAXIS = 0x00000001; + public final static int DIDF_RELAXIS = 0x00000002; + + public final static int DI_OK = 0x00000000; + public final static int DI_NOEFFECT = 0x00000001; + public final static int DI_PROPNOEFFECT = 0x00000001; + + public final static int DI_DOWNLOADSKIPPED = 0x00000003; + public final static int DI_EFFECTRESTARTED = 0x00000004; + public final static int DI_TRUNCATED = 0x00000008; + public final static int DI_SETTINGSNOTSAVED = 0x0000000B; + public final static int DI_TRUNCATEDANDRESTARTED = 0x0000000C; + + public final static int DI_BUFFEROVERFLOW = 0x00000001; + public final static int DIERR_INPUTLOST = 0x8007001E; + public final static int DIERR_NOTACQUIRED = 0x8007001C; + public final static int DIERR_OTHERAPPHASPRIO = 0x80070005; + + public final static int DIDOI_FFACTUATOR = 0x00000001; + public final static int DIDOI_FFEFFECTTRIGGER = 0x00000002; + public final static int DIDOI_POLLED = 0x00008000; + public final static int DIDOI_ASPECTPOSITION = 0x00000100; + public final static int DIDOI_ASPECTVELOCITY = 0x00000200; + public final static int DIDOI_ASPECTACCEL = 0x00000300; + public final static int DIDOI_ASPECTFORCE = 0x00000400; + public final static int DIDOI_ASPECTMASK = 0x00000F00; + public final static int DIDOI_GUIDISUSAGE = 0x00010000; + + public final static int DIEFT_ALL = 0x00000000; + + public final static int DIEFT_CONSTANTFORCE = 0x00000001; + public final static int DIEFT_RAMPFORCE = 0x00000002; + public final static int DIEFT_PERIODIC = 0x00000003; + public final static int DIEFT_CONDITION = 0x00000004; + public final static int DIEFT_CUSTOMFORCE = 0x00000005; + public final static int DIEFT_HARDWARE = 0x000000FF; + public final static int DIEFT_FFATTACK = 0x00000200; + public final static int DIEFT_FFFADE = 0x00000400; + public final static int DIEFT_SATURATION = 0x00000800; + public final static int DIEFT_POSNEGCOEFFICIENTS = 0x00001000; + public final static int DIEFT_POSNEGSATURATION = 0x00002000; + public final static int DIEFT_DEADBAND = 0x00004000; + public final static int DIEFT_STARTDELAY = 0x00008000; + + public final static int DIEFF_OBJECTIDS = 0x00000001; + public final static int DIEFF_OBJECTOFFSETS = 0x00000002; + public final static int DIEFF_CARTESIAN = 0x00000010; + public final static int DIEFF_POLAR = 0x00000020; + public final static int DIEFF_SPHERICAL = 0x00000040; + + public final static int DIEP_DURATION = 0x00000001; + public final static int DIEP_SAMPLEPERIOD = 0x00000002; + public final static int DIEP_GAIN = 0x00000004; + public final static int DIEP_TRIGGERBUTTON = 0x00000008; + public final static int DIEP_TRIGGERREPEATINTERVAL = 0x00000010; + public final static int DIEP_AXES = 0x00000020; + public final static int DIEP_DIRECTION = 0x00000040; + public final static int DIEP_ENVELOPE = 0x00000080; + public final static int DIEP_TYPESPECIFICPARAMS = 0x00000100; + public final static int DIEP_STARTDELAY = 0x00000200; + public final static int DIEP_ALLPARAMS_DX5 = 0x000001FF; + public final static int DIEP_ALLPARAMS = 0x000003FF; + public final static int DIEP_START = 0x20000000; + public final static int DIEP_NORESTART = 0x40000000; + public final static int DIEP_NODOWNLOAD = 0x80000000; + public final static int DIEB_NOTRIGGER = 0xFFFFFFFF; + + public final static int INFINITE = 0xFFFFFFFF; + + public final static int DI_DEGREES = 100; + public final static int DI_FFNOMINALMAX = 10000; + public final static int DI_SECONDS = 1000000; + + public final static int DIPROPRANGE_NOMIN = 0x80000000; + public final static int DIPROPRANGE_NOMAX = 0x7FFFFFFF; + + private final DummyWindow window; + private final long address; + private final int dev_type; + private final int dev_subtype; + private final String instance_name; + private final String product_name; + private final List objects = new ArrayList(); + private final List effects = new ArrayList(); + private final List rumblers = new ArrayList(); + private final int[] device_state; + private final Map object_to_component = new HashMap(); + private boolean released; + private DataQueue queue; + + private int button_counter; + private int current_format_offset; + + public IDirectInputDevice(DummyWindow window, long address, byte[] instance_guid, byte[] product_guid, int dev_type, int dev_subtype, String instance_name, String product_name) throws IOException { + this.window = window; + this.address = address; + this.product_name = product_name; + this.instance_name = instance_name; + this.dev_type = dev_type; + this.dev_subtype = dev_subtype; + // Assume that the caller (native side) releases the device if setup fails + enumObjects(); + try { + enumEffects(); + createRumblers(); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to create rumblers: " + e.getMessage()); + } + /* Some DirectInput lamer-designer made the device state + * axis mode be per-device not per-axis, so I'll just + * get all axes as absolute and compensate for relative axes + */ + setDataFormat(DIDF_ABSAXIS); + if (rumblers.size() > 0) { + try { + setCooperativeLevel(DISCL_BACKGROUND | DISCL_EXCLUSIVE); + } catch (IOException e) { + setCooperativeLevel(DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); + } + } else + setCooperativeLevel(DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); + setBufferSize(AbstractController.EVENT_QUEUE_DEPTH); + acquire(); + this.device_state = new int[objects.size()]; + } + + public final Rumbler[] getRumblers() { + return (Rumbler[])rumblers.toArray(new Rumbler[]{}); + } + + private final List createRumblers() throws IOException { + DIDeviceObject x_axis = lookupObjectByGUID(GUID_XAxis); + DIDeviceObject y_axis = lookupObjectByGUID(GUID_YAxis); + if(x_axis == null || y_axis == null) + return rumblers; + DIDeviceObject[] axes = {x_axis, y_axis}; + long[] directions = {0, 0}; + for (int i = 0; i < effects.size(); i++) { + DIEffectInfo info = (DIEffectInfo)effects.get(i); + if ((info.getEffectType() & 0xff) == DIEFT_PERIODIC && + (info.getDynamicParams() & DIEP_GAIN) != 0) { + rumblers.add(createPeriodicRumbler(axes, directions, info)); + } + } + return rumblers; + } + + private final Rumbler createPeriodicRumbler(DIDeviceObject[] axes, long[] directions, DIEffectInfo info) throws IOException { + int[] axis_ids = new int[axes.length]; + for (int i = 0; i < axis_ids.length; i++) { + axis_ids[i] = axes[i].getDIIdentifier(); + } + long effect_address = nCreatePeriodicEffect(address, info.getGUID(), DIEFF_CARTESIAN | DIEFF_OBJECTIDS, INFINITE, 0, 0, DIEB_NOTRIGGER, 0, axis_ids, directions, 0, 0, 0, 0, DI_FFNOMINALMAX, 0, 0, 50000, 0); + return new IDirectInputEffect(effect_address, info); + } + private final static native long nCreatePeriodicEffect(long address, byte[] effect_guid, int flags, int duration, int sample_period, int gain, int trigger_button, int trigger_repeat_interval, int[] axis_ids, long[] directions, int envelope_attack_level, int envelope_attack_time, int envelope_fade_level, int envelope_fade_time, int periodic_magnitude, int periodic_offset, int periodic_phase, int periodic_period, int start_delay) throws IOException; + + private final DIDeviceObject lookupObjectByGUID(int guid_id) { + for (int i = 0; i < objects.size(); i++) { + DIDeviceObject object = (DIDeviceObject)objects.get(i); + if (guid_id == object.getGUIDType()) + return object; + } + return null; + } + + public final int getPollData(DIDeviceObject object) { + return device_state[object.getFormatOffset()]; + } + + public final DIDeviceObject mapEvent(DIDeviceObjectData event) { + /* Raw event format offsets (dwOfs member) is in bytes, + * but we're indexing into ints so we have to compensate + * for the int size (4 bytes) + */ + int format_offset = event.getFormatOffset()/4; + return (DIDeviceObject)objects.get(format_offset); + } + + public final DIComponent mapObject(DIDeviceObject object) { + return (DIComponent)object_to_component.get(object); + } + + public final void registerComponent(DIDeviceObject object, DIComponent component) { + object_to_component.put(object, component); + } + + public final synchronized void pollAll() throws IOException { + checkReleased(); + poll(); + getDeviceState(device_state); + queue.compact(); + getDeviceData(queue); + queue.flip(); + } + + public synchronized final boolean getNextEvent(DIDeviceObjectData data) { + DIDeviceObjectData next_event = (DIDeviceObjectData)queue.get(); + if (next_event == null) + return false; + data.set(next_event); + return true; + } + + private final void poll() throws IOException { + int res = nPoll(address); + if (res != DI_OK && res != DI_NOEFFECT) { + if (res == DIERR_NOTACQUIRED) { + acquire(); + return; + } + throw new IOException("Failed to poll device (" + Integer.toHexString(res) + ")"); + } + } + private final static native int nPoll(long address) throws IOException; + + private final void acquire() throws IOException { + int res = nAcquire(address); + if (res != DI_OK && res != DIERR_OTHERAPPHASPRIO && res != DI_NOEFFECT) + throw new IOException("Failed to acquire device (" + Integer.toHexString(res) + ")"); + } + private final static native int nAcquire(long address); + + private final void unacquire() throws IOException { + int res = nUnacquire(address); + if (res != DI_OK && res != DI_NOEFFECT) + throw new IOException("Failed to unAcquire device (" + Integer.toHexString(res) + ")"); + } + private final static native int nUnacquire(long address); + + private final boolean getDeviceData(DataQueue queue) throws IOException { + int res = nGetDeviceData(address, 0, queue, queue.getElements(), queue.position(), queue.remaining()); + if (res != DI_OK && res != DI_BUFFEROVERFLOW) { + if (res == DIERR_NOTACQUIRED) { + acquire(); + return false; + } + throw new IOException("Failed to get device data (" + Integer.toHexString(res) + ")"); + } + return true; + } + private final static native int nGetDeviceData(long address, int flags, DataQueue queue, Object[] queue_elements, int position, int remaining); + + private final void getDeviceState(int[] device_state) throws IOException { + int res = nGetDeviceState(address, device_state); + if (res != DI_OK) { + if (res == DIERR_NOTACQUIRED) { + Arrays.fill(device_state, 0); + acquire(); + return; + } + throw new IOException("Failed to get device state (" + Integer.toHexString(res) + ")"); + } + } + private final static native int nGetDeviceState(long address, int[] device_state); + + /* Set a custom data format that maps each object's data into an int[] + array with the same index as in the objects List */ + private final void setDataFormat(int flags) throws IOException { + DIDeviceObject[] device_objects = new DIDeviceObject[objects.size()]; + objects.toArray(device_objects); + int res = nSetDataFormat(address, flags, device_objects); + if (res != DI_OK) + throw new IOException("Failed to set data format (" + Integer.toHexString(res) + ")"); + } + private final static native int nSetDataFormat(long address, int flags, DIDeviceObject[] device_objects); + + public final String getProductName() { + return product_name; + } + + public final int getType() { + return dev_type; + } + + public final List getObjects() { + return objects; + } + + private final void enumEffects() throws IOException { + int res = nEnumEffects(address, DIEFT_ALL); + if (res != DI_OK) + throw new IOException("Failed to enumerate effects (" + Integer.toHexString(res) + ")"); + } + private final native int nEnumEffects(long address, int flags); + + /* Called from native side from nEnumEffects */ + private final void addEffect(byte[] guid, int guid_id, int effect_type, int static_params, int dynamic_params, String name) { + effects.add(new DIEffectInfo(this, guid, guid_id, effect_type, static_params, dynamic_params, name)); + } + + private final void enumObjects() throws IOException { + int res = nEnumObjects(address, DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + if (res != DI_OK) + throw new IOException("Failed to enumerate objects (" + Integer.toHexString(res) + ")"); + } + private final native int nEnumObjects(long address, int flags); + + public final synchronized long[] getRangeProperty(int object_identifier) throws IOException { + checkReleased(); + long[] range = new long[2]; + int res = nGetRangeProperty(address, object_identifier, range); + if (res != DI_OK) + throw new IOException("Failed to get object range (" + res + ")"); + return range; + } + private final static native int nGetRangeProperty(long address, int object_id, long[] range); + + public final synchronized int getDeadzoneProperty(int object_identifier) throws IOException { + checkReleased(); + return nGetDeadzoneProperty(address, object_identifier); + } + private final static native int nGetDeadzoneProperty(long address, int object_id) throws IOException; + + /* Called from native side from nEnumObjects */ + private final void addObject(byte[] guid, int guid_type, int identifier, int type, int instance, int flags, String name) throws IOException { + Component.Identifier id = getIdentifier(guid_type, type, instance); + int format_offset = current_format_offset++; + DIDeviceObject obj = new DIDeviceObject(this, id, guid, guid_type, identifier, type, instance, flags, name, format_offset); + objects.add(obj); + } + + private final static Component.Identifier.Key getKeyIdentifier(int key_instance) { + return DIIdentifierMap.getKeyIdentifier(key_instance); + } + + private final Component.Identifier.Button getNextButtonIdentifier() { + int button_id = button_counter++; + return DIIdentifierMap.getButtonIdentifier(button_id); + } + + private final Component.Identifier getIdentifier(int guid_type, int type, int instance) { + switch (guid_type) { + case IDirectInputDevice.GUID_XAxis: + return Component.Identifier.Axis.X; + case IDirectInputDevice.GUID_YAxis: + return Component.Identifier.Axis.Y; + case IDirectInputDevice.GUID_ZAxis: + return Component.Identifier.Axis.Z; + case IDirectInputDevice.GUID_RxAxis: + return Component.Identifier.Axis.RX; + case IDirectInputDevice.GUID_RyAxis: + return Component.Identifier.Axis.RY; + case IDirectInputDevice.GUID_RzAxis: + return Component.Identifier.Axis.RZ; + case IDirectInputDevice.GUID_Slider: + return Component.Identifier.Axis.SLIDER; + case IDirectInputDevice.GUID_POV: + return Component.Identifier.Axis.POV; + case IDirectInputDevice.GUID_Key: + return getKeyIdentifier(instance); + case IDirectInputDevice.GUID_Button: + return getNextButtonIdentifier(); + default: + return null; + } + } + + public final synchronized void setBufferSize(int size) throws IOException { + checkReleased(); + unacquire(); + int res = nSetBufferSize(address, size); + if (res != DI_OK && res != DI_PROPNOEFFECT) + throw new IOException("Failed to set buffer size (" + Integer.toHexString(res) + ")"); + queue = new DataQueue(size, DIDeviceObjectData.class); + queue.position(queue.limit()); + acquire(); + } + private final static native int nSetBufferSize(long address, int size); + + public final synchronized void setCooperativeLevel(int flags) throws IOException { + checkReleased(); + int res = nSetCooperativeLevel(address, window.getHwnd(), flags); + if (res != DI_OK) + throw new IOException("Failed to set cooperative level (" + Integer.toHexString(res) + ")"); + } + private final static native int nSetCooperativeLevel(long address, long hwnd_address, int flags); + + public synchronized final void release() { + if (!released) { + released = true; + for (int i = 0; i < rumblers.size(); i++) { + IDirectInputEffect effect = (IDirectInputEffect)rumblers.get(i); + effect.release(); + } + nRelease(address); + } + } + private final static native void nRelease(long address); + + private final void checkReleased() throws IOException { + if (released) + throw new IOException("Device is released"); + } + + protected void finalize() { + release(); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/IDirectInputEffect.java b/plugins/windows/src/java/net/java/games/input/IDirectInputEffect.java new file mode 100644 index 0000000..5cb372f --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/IDirectInputEffect.java @@ -0,0 +1,121 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper for IDirectInputEffect + * @author elias + * @version 1.0 + */ +final class IDirectInputEffect implements Rumbler { + private final long address; + private final DIEffectInfo info; + private boolean released; + + public IDirectInputEffect(long address, DIEffectInfo info) { + this.address = address; + this.info = info; + } + + public final synchronized void rumble(float intensity) { + try { + checkReleased(); + if (intensity > 0) { + int int_gain = (int)Math.round(intensity*IDirectInputDevice.DI_FFNOMINALMAX); + setGain(int_gain); + start(1, 0); + } else + stop(); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to set rumbler gain: " + e.getMessage()); + } + } + + public final Component.Identifier getAxisIdentifier() { + return null; + } + + public final String getAxisName() { + return null; + } + + public final synchronized void release() { + if (!released) { + released = true; + nRelease(address); + } + } + private final static native void nRelease(long address); + + private final void checkReleased() throws IOException { + if (released) + throw new IOException(); + } + + private final void setGain(int gain) throws IOException { + int res = nSetGain(address, gain); + if (res != IDirectInputDevice.DI_DOWNLOADSKIPPED && + res != IDirectInputDevice.DI_EFFECTRESTARTED && + res != IDirectInputDevice.DI_OK && + res != IDirectInputDevice.DI_TRUNCATED && + res != IDirectInputDevice.DI_TRUNCATEDANDRESTARTED) { + throw new IOException("Failed to set effect gain (0x" + Integer.toHexString(res) + ")"); + } + } + private final static native int nSetGain(long address, int gain); + + private final void start(int iterations, int flags) throws IOException { + int res = nStart(address, iterations, flags); + if (res != IDirectInputDevice.DI_OK) + throw new IOException("Failed to start effect (0x" + Integer.toHexString(res) + ")"); + } + private final static native int nStart(long address, int iterations, int flags); + + private final void stop() throws IOException { + int res = nStop(address); + if (res != IDirectInputDevice.DI_OK) + throw new IOException("Failed to stop effect (0x" + Integer.toHexString(res) + ")"); + } + private final static native int nStop(long address); + + protected void finalize() { + release(); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawDevice.java b/plugins/windows/src/java/net/java/games/input/RawDevice.java new file mode 100644 index 0000000..4841234 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawDevice.java @@ -0,0 +1,310 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RAWDEVICELIST + * @author elias + * @version 1.0 + */ +final class RawDevice { + public final static int RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001; // Left Button changed to down. + public final static int RI_MOUSE_LEFT_BUTTON_UP = 0x0002; // Left Button changed to up. + public final static int RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004; // Right Button changed to down. + public final static int RI_MOUSE_RIGHT_BUTTON_UP = 0x0008; // Right Button changed to up. + public final static int RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010; // Middle Button changed to down. + public final static int RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020; // Middle Button changed to up. + + public final static int RI_MOUSE_BUTTON_1_DOWN = RI_MOUSE_LEFT_BUTTON_DOWN; + public final static int RI_MOUSE_BUTTON_1_UP = RI_MOUSE_LEFT_BUTTON_UP; + public final static int RI_MOUSE_BUTTON_2_DOWN = RI_MOUSE_RIGHT_BUTTON_DOWN; + public final static int RI_MOUSE_BUTTON_2_UP = RI_MOUSE_RIGHT_BUTTON_UP; + public final static int RI_MOUSE_BUTTON_3_DOWN = RI_MOUSE_MIDDLE_BUTTON_DOWN; + public final static int RI_MOUSE_BUTTON_3_UP = RI_MOUSE_MIDDLE_BUTTON_UP; + + public final static int RI_MOUSE_BUTTON_4_DOWN = 0x0040; + public final static int RI_MOUSE_BUTTON_4_UP = 0x0080; + public final static int RI_MOUSE_BUTTON_5_DOWN = 0x0100; + public final static int RI_MOUSE_BUTTON_5_UP = 0x0200; + + /* + * If usButtonFlags has RI_MOUSE_WHEEL, the wheel delta is stored in usButtonData. + * Take it as a signed value. + */ + public final static int RI_MOUSE_WHEEL = 0x0400; + + public final static int MOUSE_MOVE_RELATIVE = 0; + public final static int MOUSE_MOVE_ABSOLUTE = 1; + public final static int MOUSE_VIRTUAL_DESKTOP = 0x02; // the coordinates are mapped to the virtual desktop + public final static int MOUSE_ATTRIBUTES_CHANGED = 0x04; // requery for mouse attributes + + public final static int RIM_TYPEHID = 2; + public final static int RIM_TYPEKEYBOARD = 1; + public final static int RIM_TYPEMOUSE = 0; + + public final static int WM_KEYDOWN = 0x0100; + public final static int WM_KEYUP = 0x0101; + public final static int WM_SYSKEYDOWN = 0x0104; + public final static int WM_SYSKEYUP = 0x0105; + + private final RawInputEventQueue queue; + private final long handle; + private final int type; + + /* Events from the event queue thread end here */ + private DataQueue keyboard_events; + private DataQueue mouse_events; + + /* After processing in poll*(), the events are placed here */ + private DataQueue processed_keyboard_events; + private DataQueue processed_mouse_events; + + /* mouse state */ + private final boolean[] button_states = new boolean[5]; + private int wheel; + private int relative_x; + private int relative_y; + private int last_x; + private int last_y; + + // Last x, y for converting absolute events to relative + private int event_relative_x; + private int event_relative_y; + private int event_last_x; + private int event_last_y; + + /* keyboard state */ + private final boolean[] key_states = new boolean[0xFF]; + + public RawDevice(RawInputEventQueue queue, long handle, int type) { + this.queue = queue; + this.handle = handle; + this.type = type; + setBufferSize(AbstractController.EVENT_QUEUE_DEPTH); + } + + /* Careful, this is called from the event queue thread */ + public final synchronized void addMouseEvent(long millis, int flags, int button_flags, int button_data, long raw_buttons, long last_x, long last_y, long extra_information) { + if (mouse_events.hasRemaining()) { + RawMouseEvent event = (RawMouseEvent)mouse_events.get(); + event.set(millis, flags, button_flags, button_data, raw_buttons, last_x, last_y, extra_information); + } + } + + /* Careful, this is called from the event queue thread */ + public final synchronized void addKeyboardEvent(long millis, int make_code, int flags, int vkey, int message, long extra_information) { + if (keyboard_events.hasRemaining()) { + RawKeyboardEvent event = (RawKeyboardEvent)keyboard_events.get(); + event.set(millis, make_code, flags, vkey, message, extra_information); + } + } + + public final synchronized void pollMouse() { + relative_x = relative_y = wheel = 0; + mouse_events.flip(); + while (mouse_events.hasRemaining()) { + RawMouseEvent event = (RawMouseEvent)mouse_events.get(); + boolean has_update = processMouseEvent(event); + if (has_update && processed_mouse_events.hasRemaining()) { + RawMouseEvent processed_event = (RawMouseEvent)processed_mouse_events.get(); + processed_event.set(event); + } + } + mouse_events.compact(); + } + + public final synchronized void pollKeyboard() { + keyboard_events.flip(); + while (keyboard_events.hasRemaining()) { + RawKeyboardEvent event = (RawKeyboardEvent)keyboard_events.get(); + boolean has_update = processKeyboardEvent(event); + if (has_update && processed_keyboard_events.hasRemaining()) { + RawKeyboardEvent processed_event = (RawKeyboardEvent)processed_keyboard_events.get(); + processed_event.set(event); + } + } + keyboard_events.compact(); + } + + private final boolean updateButtonState(int button_id, int button_flags, int down_flag, int up_flag) { + if (button_id >= button_states.length) + return false; + if ((button_flags & down_flag) != 0) { + button_states[button_id] = true; + return true; + } else if ((button_flags & up_flag) != 0) { + button_states[button_id] = false; + return true; + } else + return false; + } + + private final boolean processKeyboardEvent(RawKeyboardEvent event) { + int message = event.getMessage(); + int vkey = event.getVKey(); + if (vkey >= key_states.length) + return false; + if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) { + key_states[vkey] = true; + return true; + } else if (message == WM_KEYUP || message == WM_SYSKEYUP) { + key_states[vkey] = false; + return true; + } else + return false; + } + + public final boolean isKeyDown(int vkey) { + return key_states[vkey]; + } + + private final boolean processMouseEvent(RawMouseEvent event) { + boolean has_update = false; + int button_flags = event.getButtonFlags(); + has_update = updateButtonState(0, button_flags, RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP) || has_update; + has_update = updateButtonState(1, button_flags, RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP) || has_update; + has_update = updateButtonState(2, button_flags, RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP) || has_update; + has_update = updateButtonState(3, button_flags, RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP) || has_update; + has_update = updateButtonState(4, button_flags, RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP) || has_update; + int dx; + int dy; + if ((event.getFlags() & MOUSE_MOVE_ABSOLUTE) != 0) { + dx = event.getLastX() - last_x; + dy = event.getLastY() - last_y; + last_x = event.getLastX(); + last_y = event.getLastY(); + } else { + dx = event.getLastX(); + dy = event.getLastY(); + } + int dwheel = 0; + if ((button_flags & RI_MOUSE_WHEEL) != 0) + dwheel = event.getWheelDelta(); + relative_x += dx; + relative_y += dy; + wheel += dwheel; + has_update = dx != 0 || dy != 0 || dwheel != 0 || has_update; + return has_update; + } + + public final int getWheel() { + return wheel; + } + + public final int getEventRelativeX() { + return event_relative_x; + } + + public final int getEventRelativeY() { + return event_relative_y; + } + + public final int getRelativeX() { + return relative_x; + } + + public final int getRelativeY() { + return relative_y; + } + + public final synchronized boolean getNextKeyboardEvent(RawKeyboardEvent event) { + processed_keyboard_events.flip(); + if (!processed_keyboard_events.hasRemaining()) { + processed_keyboard_events.compact(); + return false; + } + RawKeyboardEvent next_event = (RawKeyboardEvent)processed_keyboard_events.get(); + event.set(next_event); + processed_keyboard_events.compact(); + return true; + } + + public final synchronized boolean getNextMouseEvent(RawMouseEvent event) { + processed_mouse_events.flip(); + if (!processed_mouse_events.hasRemaining()) { + processed_mouse_events.compact(); + return false; + } + RawMouseEvent next_event = (RawMouseEvent)processed_mouse_events.get(); + if ((next_event.getFlags() & MOUSE_MOVE_ABSOLUTE) != 0) { + event_relative_x = next_event.getLastX() - event_last_x; + event_relative_y = next_event.getLastY() - event_last_y; + event_last_x = next_event.getLastX(); + event_last_y = next_event.getLastY(); + } else { + event_relative_x = next_event.getLastX(); + event_relative_y = next_event.getLastY(); + } + event.set(next_event); + processed_mouse_events.compact(); + return true; + } + + public final boolean getButtonState(int button_id) { + if (button_id >= button_states.length) + return false; + return button_states[button_id]; + } + + public final void setBufferSize(int size) { + keyboard_events = new DataQueue(size, RawKeyboardEvent.class); + mouse_events = new DataQueue(size, RawMouseEvent.class); + processed_keyboard_events = new DataQueue(size, RawKeyboardEvent.class); + processed_mouse_events = new DataQueue(size, RawMouseEvent.class); + } + + public final int getType() { + return type; + } + + public final long getHandle() { + return handle; + } + + public final String getName() throws IOException { + return nGetName(handle); + } + private final static native String nGetName(long handle) throws IOException; + + public final RawDeviceInfo getInfo() throws IOException { + return nGetInfo(this, handle); + } + private final static native RawDeviceInfo nGetInfo(RawDevice device, long handle) throws IOException; +} diff --git a/plugins/windows/src/java/net/java/games/input/RawDeviceInfo.java b/plugins/windows/src/java/net/java/games/input/RawDeviceInfo.java new file mode 100644 index 0000000..7e6228f --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawDeviceInfo.java @@ -0,0 +1,67 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RID_DEVICE_INFO + * @author elias + * @version 1.0 + */ +abstract class RawDeviceInfo { + public abstract Controller createControllerFromDevice(RawDevice device, SetupAPIDevice setupapi_device) throws IOException; + + public abstract int getUsage(); + + public abstract int getUsagePage(); + + public abstract long getHandle(); + + public final boolean equals(Object other) { + if (!(other instanceof RawDeviceInfo)) + return false; + RawDeviceInfo other_info = (RawDeviceInfo)other; + return other_info.getUsage() == getUsage() && + other_info.getUsagePage() == getUsagePage(); + } + + public final int hashCode() { + return getUsage() ^ getUsagePage(); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawHIDInfo.java b/plugins/windows/src/java/net/java/games/input/RawHIDInfo.java new file mode 100644 index 0000000..6465bb4 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawHIDInfo.java @@ -0,0 +1,80 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RID_DEVICE_INFO_HID + * @author elias + * @version 1.0 + */ +class RawHIDInfo extends RawDeviceInfo { + private final RawDevice device; + + private final int vendor_id; + private final int product_id; + private final int version; + private final int page; + private final int usage; + + public RawHIDInfo(RawDevice device, int vendor_id, int product_id, int version, int page, int usage) { + this.device = device; + this.vendor_id = vendor_id; + this.product_id = product_id; + this.version = version; + this.page = page; + this.usage = usage; + } + + public final int getUsage() { + return usage; + } + + public final int getUsagePage() { + return page; + } + + public final long getHandle() { + return device.getHandle(); + } + + public final Controller createControllerFromDevice(RawDevice device, SetupAPIDevice setupapi_device) throws IOException { + return null; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawIdentifierMap.java b/plugins/windows/src/java/net/java/games/input/RawIdentifierMap.java new file mode 100644 index 0000000..662a183 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawIdentifierMap.java @@ -0,0 +1,553 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +/** + * @author elias + * @version 1.0 + */ +final class RawIdentifierMap { + public final static int VK_LBUTTON = 0x01; + public final static int VK_RBUTTON = 0x02; + public final static int VK_CANCEL = 0x03; + public final static int VK_MBUTTON = 0x04; /* NOT contiguous with L & RBUTTON */ + + public final static int VK_XBUTTON1 = 0x05; /* NOT contiguous with L & RBUTTON */ + public final static int VK_XBUTTON2 = 0x06; /* NOT contiguous with L & RBUTTON */ + +/* + * 0x07 : unassigned + */ + + public final static int VK_BACK = 0x08; + public final static int VK_TAB = 0x09; + +/* + * 0x0A - 0x0B : reserved + */ + + public final static int VK_CLEAR = 0x0C; + public final static int VK_RETURN = 0x0D; + + public final static int VK_SHIFT = 0x10; + public final static int VK_CONTROL = 0x11; + public final static int VK_MENU = 0x12; + public final static int VK_PAUSE = 0x13; + public final static int VK_CAPITAL = 0x14; + + public final static int VK_KANA = 0x15; + public final static int VK_HANGEUL = 0x15; /* old name - should be here for compatibility */ + public final static int VK_HANGUL = 0x15; + public final static int VK_JUNJA = 0x17; + public final static int VK_FINAL = 0x18; + public final static int VK_HANJA = 0x19; + public final static int VK_KANJI = 0x19; + + public final static int VK_ESCAPE = 0x1B; + + public final static int VK_CONVERT = 0x1C; + public final static int VK_NONCONVERT = 0x1D; + public final static int VK_ACCEPT = 0x1E; + public final static int VK_MODECHANGE = 0x1F; + + public final static int VK_SPACE = 0x20; + public final static int VK_PRIOR = 0x21; + public final static int VK_NEXT = 0x22; + public final static int VK_END = 0x23; + public final static int VK_HOME = 0x24; + public final static int VK_LEFT = 0x25; + public final static int VK_UP = 0x26; + public final static int VK_RIGHT = 0x27; + public final static int VK_DOWN = 0x28; + public final static int VK_SELECT = 0x29; + public final static int VK_PRINT = 0x2A; + public final static int VK_EXECUTE = 0x2B; + public final static int VK_SNAPSHOT = 0x2C; + public final static int VK_INSERT = 0x2D; + public final static int VK_DELETE = 0x2E; + public final static int VK_HELP = 0x2F; +/* + * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39) + * 0x40 : unassigned + * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) + */ + public final static int VK_0 = 0x30; + public final static int VK_1 = 0x31; + public final static int VK_2 = 0x32; + public final static int VK_3 = 0x33; + public final static int VK_4 = 0x34; + public final static int VK_5 = 0x35; + public final static int VK_6 = 0x36; + public final static int VK_7 = 0x37; + public final static int VK_8 = 0x38; + public final static int VK_9 = 0x39; + + public final static int VK_A = 0x41; + public final static int VK_B = 0x42; + public final static int VK_C = 0x43; + public final static int VK_D = 0x44; + public final static int VK_E = 0x45; + public final static int VK_F = 0x46; + public final static int VK_G = 0x47; + public final static int VK_H = 0x48; + public final static int VK_I = 0x49; + public final static int VK_J = 0x4A; + public final static int VK_K = 0x4B; + public final static int VK_L = 0x4C; + public final static int VK_M = 0x4D; + public final static int VK_N = 0x4E; + public final static int VK_O = 0x4F; + public final static int VK_P = 0x50; + public final static int VK_Q = 0x51; + public final static int VK_R = 0x52; + public final static int VK_S = 0x53; + public final static int VK_T = 0x54; + public final static int VK_U = 0x55; + public final static int VK_V = 0x56; + public final static int VK_W = 0x57; + public final static int VK_X = 0x58; + public final static int VK_Y = 0x59; + public final static int VK_Z = 0x5A; + + public final static int VK_LWIN = 0x5B; + public final static int VK_RWIN = 0x5C; + public final static int VK_APPS = 0x5D; +/* + * 0x5E : reserved; + */ + + public final static int VK_SLEEP = 0x5F; + + public final static int VK_NUMPAD0 = 0x60; + public final static int VK_NUMPAD1 = 0x61; + public final static int VK_NUMPAD2 = 0x62; + public final static int VK_NUMPAD3 = 0x63; + public final static int VK_NUMPAD4 = 0x64; + public final static int VK_NUMPAD5 = 0x65; + public final static int VK_NUMPAD6 = 0x66; + public final static int VK_NUMPAD7 = 0x67; + public final static int VK_NUMPAD8 = 0x68; + public final static int VK_NUMPAD9 = 0x69; + public final static int VK_MULTIPLY = 0x6A; + public final static int VK_ADD = 0x6B; + public final static int VK_SEPARATOR = 0x6C; + public final static int VK_SUBTRACT = 0x6D; + public final static int VK_DECIMAL = 0x6E; + public final static int VK_DIVIDE = 0x6F; + public final static int VK_F1 = 0x70; + public final static int VK_F2 = 0x71; + public final static int VK_F3 = 0x72; + public final static int VK_F4 = 0x73; + public final static int VK_F5 = 0x74; + public final static int VK_F6 = 0x75; + public final static int VK_F7 = 0x76; + public final static int VK_F8 = 0x77; + public final static int VK_F9 = 0x78; + public final static int VK_F10 = 0x79; + public final static int VK_F11 = 0x7A; + public final static int VK_F12 = 0x7B; + public final static int VK_F13 = 0x7C; + public final static int VK_F14 = 0x7D; + public final static int VK_F15 = 0x7E; + public final static int VK_F16 = 0x7F; + public final static int VK_F17 = 0x80; + public final static int VK_F18 = 0x81; + public final static int VK_F19 = 0x82; + public final static int VK_F20 = 0x83; + public final static int VK_F21 = 0x84; + public final static int VK_F22 = 0x85; + public final static int VK_F23 = 0x86; + public final static int VK_F24 = 0x87; + +/* + * 0x88 - 0x8F : unassigned; + */ + + public final static int VK_NUMLOCK = 0x90; + public final static int VK_SCROLL = 0x91; + +/* + * NEC PC-9800 kbd definitions + */ + public final static int VK_OEM_NEC_EQUAL = 0x92; // '=' key on numpad +/* + * Fujitsu/OASYS kbd definitions + */ + public final static int VK_OEM_FJ_JISHO = 0x92; // 'Dictionary' key + public final static int VK_OEM_FJ_MASSHOU = 0x93; // 'Unregister word' key + public final static int VK_OEM_FJ_TOUROKU = 0x94; // 'Register word' key + public final static int VK_OEM_FJ_LOYA = 0x95; // 'Left OYAYUBI' key + public final static int VK_OEM_FJ_ROYA = 0x96; // 'Right OYAYUBI' key + +/* + * 0x97 - 0x9F : unassigned + */ + +/* + * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. + * Used only as parameters to GetAsyncKeyState() and GetKeyState(). + * No other API or message will distinguish left and right keys in this way. + */ + public final static int VK_LSHIFT = 0xA0; + public final static int VK_RSHIFT = 0xA1; + public final static int VK_LCONTROL = 0xA2; + public final static int VK_RCONTROL = 0xA3; + public final static int VK_LMENU = 0xA4; + public final static int VK_RMENU = 0xA5; + + public final static int VK_BROWSER_BACK = 0xA6; + public final static int VK_BROWSER_FORWARD = 0xA7; + public final static int VK_BROWSER_REFRESH = 0xA8; + public final static int VK_BROWSER_STOP = 0xA9; + public final static int VK_BROWSER_SEARCH = 0xAA; + public final static int VK_BROWSER_FAVORITES = 0xAB; + public final static int VK_BROWSER_HOME = 0xAC; + + public final static int VK_VOLUME_MUTE = 0xAD; + public final static int VK_VOLUME_DOWN = 0xAE; + public final static int VK_VOLUME_UP = 0xAF; + public final static int VK_MEDIA_NEXT_TRACK = 0xB0; + public final static int VK_MEDIA_PREV_TRACK = 0xB1; + public final static int VK_MEDIA_STOP = 0xB2; + public final static int VK_MEDIA_PLAY_PAUSE = 0xB3; + public final static int VK_LAUNCH_MAIL = 0xB4; + public final static int VK_LAUNCH_MEDIA_SELECT = 0xB5; + public final static int VK_LAUNCH_APP1 = 0xB6; + public final static int VK_LAUNCH_APP2 = 0xB7; + +/* + * 0xB8 - 0xB9 : reserved + */ + + public final static int VK_OEM_1 = 0xBA; // ';:' for US + public final static int VK_OEM_PLUS = 0xBB; // '+' any country + public final static int VK_OEM_COMMA = 0xBC; // ',' any country + public final static int VK_OEM_MINUS = 0xBD; // '-' any country + public final static int VK_OEM_PERIOD = 0xBE; // '.' any country + public final static int VK_OEM_2 = 0xBF; // '/?' for US + public final static int VK_OEM_3 = 0xC0; // '`~' for US + +/* + * 0xC1 - 0xD7 : reserved + */ + +/* + * 0xD8 - 0xDA : unassigned + */ + + public final static int VK_OEM_4 = 0xDB; // '[{' for US + public final static int VK_OEM_5 = 0xDC; // '\|' for US + public final static int VK_OEM_6 = 0xDD; // ']}' for US + public final static int VK_OEM_7 = 0xDE; // ''"' for US + public final static int VK_OEM_8 = 0xDF; + +/* + * 0xE0 : reserved + */ + +/* + * Various extended or enhanced keyboards + */ + public final static int VK_OEM_AX = 0xE1; // 'AX' key on Japanese AX kbd + public final static int VK_OEM_102 = 0xE2; // "<>" or "\|" on RT 102-key kbd. + public final static int VK_ICO_HELP = 0xE3; // Help key on ICO + public final static int VK_ICO_00 = 0xE4; // 00 key on ICO + + public final static int VK_PROCESSKEY = 0xE5; + + public final static int VK_ICO_CLEAR = 0xE6; + + + public final static int VK_PACKET = 0xE7; + +/* + * 0xE8 : unassigned + */ + +/* + * Nokia/Ericsson definitions + */ + public final static int VK_OEM_RESET = 0xE9; + public final static int VK_OEM_JUMP = 0xEA; + public final static int VK_OEM_PA1 = 0xEB; + public final static int VK_OEM_PA2 = 0xEC; + public final static int VK_OEM_PA3 = 0xED; + public final static int VK_OEM_WSCTRL = 0xEE; + public final static int VK_OEM_CUSEL = 0xEF; + public final static int VK_OEM_ATTN = 0xF0; + public final static int VK_OEM_FINISH = 0xF1; + public final static int VK_OEM_COPY = 0xF2; + public final static int VK_OEM_AUTO = 0xF3; + public final static int VK_OEM_ENLW = 0xF4; + public final static int VK_OEM_BACKTAB = 0xF5; + + public final static int VK_ATTN = 0xF6; + public final static int VK_CRSEL = 0xF7; + public final static int VK_EXSEL = 0xF8; + public final static int VK_EREOF = 0xF9; + public final static int VK_PLAY = 0xFA; + public final static int VK_ZOOM = 0xFB; + public final static int VK_NONAME = 0xFC; + public final static int VK_PA1 = 0xFD; + public final static int VK_OEM_CLEAR = 0xFE; + + public final static Component.Identifier.Key mapVKey(int vkey) { + switch (vkey) { + case VK_ESCAPE: + return Component.Identifier.Key.ESCAPE; + case VK_1: + return Component.Identifier.Key._1; + case VK_2: + return Component.Identifier.Key._2; + case VK_3: + return Component.Identifier.Key._3; + case VK_4: + return Component.Identifier.Key._4; + case VK_5: + return Component.Identifier.Key._5; + case VK_6: + return Component.Identifier.Key._6; + case VK_7: + return Component.Identifier.Key._7; + case VK_8: + return Component.Identifier.Key._8; + case VK_9: + return Component.Identifier.Key._9; + case VK_0: + return Component.Identifier.Key._0; + case VK_OEM_NEC_EQUAL: + return Component.Identifier.Key.NUMPADEQUAL; + case VK_BACK: + return Component.Identifier.Key.BACK; + case VK_TAB: + return Component.Identifier.Key.TAB; + case VK_Q: + return Component.Identifier.Key.Q; + case VK_W: + return Component.Identifier.Key.W; + case VK_E: + return Component.Identifier.Key.E; + case VK_R: + return Component.Identifier.Key.R; + case VK_T: + return Component.Identifier.Key.T; + case VK_Y: + return Component.Identifier.Key.Y; + case VK_U: + return Component.Identifier.Key.U; + case VK_I: + return Component.Identifier.Key.I; + case VK_O: + return Component.Identifier.Key.O; + case VK_P: + return Component.Identifier.Key.P; + case VK_OEM_4: + return Component.Identifier.Key.LBRACKET; + case VK_OEM_6: + return Component.Identifier.Key.RBRACKET; + case VK_RETURN: + return Component.Identifier.Key.RETURN; + case VK_CONTROL: + case VK_LCONTROL: + return Component.Identifier.Key.LCONTROL; + case VK_A: + return Component.Identifier.Key.A; + case VK_S: + return Component.Identifier.Key.S; + case VK_D: + return Component.Identifier.Key.D; + case VK_F: + return Component.Identifier.Key.F; + case VK_G: + return Component.Identifier.Key.G; + case VK_H: + return Component.Identifier.Key.H; + case VK_J: + return Component.Identifier.Key.J; + case VK_K: + return Component.Identifier.Key.K; + case VK_L: + return Component.Identifier.Key.L; + case VK_OEM_3: + return Component.Identifier.Key.GRAVE; + case VK_SHIFT: + case VK_LSHIFT: + return Component.Identifier.Key.LSHIFT; + case VK_Z: + return Component.Identifier.Key.Z; + case VK_X: + return Component.Identifier.Key.X; + case VK_C: + return Component.Identifier.Key.C; + case VK_V: + return Component.Identifier.Key.V; + case VK_B: + return Component.Identifier.Key.B; + case VK_N: + return Component.Identifier.Key.N; + case VK_M: + return Component.Identifier.Key.M; + case VK_OEM_COMMA: + return Component.Identifier.Key.COMMA; + case VK_OEM_PERIOD: + return Component.Identifier.Key.PERIOD; + case VK_RSHIFT: + return Component.Identifier.Key.RSHIFT; + case VK_MULTIPLY: + return Component.Identifier.Key.MULTIPLY; + case VK_MENU: + case VK_LMENU: + return Component.Identifier.Key.LALT; + case VK_SPACE: + return Component.Identifier.Key.SPACE; + case VK_CAPITAL: + return Component.Identifier.Key.CAPITAL; + case VK_F1: + return Component.Identifier.Key.F1; + case VK_F2: + return Component.Identifier.Key.F2; + case VK_F3: + return Component.Identifier.Key.F3; + case VK_F4: + return Component.Identifier.Key.F4; + case VK_F5: + return Component.Identifier.Key.F5; + case VK_F6: + return Component.Identifier.Key.F6; + case VK_F7: + return Component.Identifier.Key.F7; + case VK_F8: + return Component.Identifier.Key.F8; + case VK_F9: + return Component.Identifier.Key.F9; + case VK_F10: + return Component.Identifier.Key.F10; + case VK_NUMLOCK: + return Component.Identifier.Key.NUMLOCK; + case VK_SCROLL: + return Component.Identifier.Key.SCROLL; + case VK_NUMPAD7: + return Component.Identifier.Key.NUMPAD7; + case VK_NUMPAD8: + return Component.Identifier.Key.NUMPAD8; + case VK_NUMPAD9: + return Component.Identifier.Key.NUMPAD9; + case VK_SUBTRACT: + return Component.Identifier.Key.SUBTRACT; + case VK_NUMPAD4: + return Component.Identifier.Key.NUMPAD4; + case VK_NUMPAD5: + return Component.Identifier.Key.NUMPAD5; + case VK_NUMPAD6: + return Component.Identifier.Key.NUMPAD6; + case VK_ADD: + return Component.Identifier.Key.ADD; + case VK_NUMPAD1: + return Component.Identifier.Key.NUMPAD1; + case VK_NUMPAD2: + return Component.Identifier.Key.NUMPAD2; + case VK_NUMPAD3: + return Component.Identifier.Key.NUMPAD3; + case VK_NUMPAD0: + return Component.Identifier.Key.NUMPAD0; + case VK_DECIMAL: + return Component.Identifier.Key.DECIMAL; + case VK_F11: + return Component.Identifier.Key.F11; + case VK_F12: + return Component.Identifier.Key.F12; + case VK_F13: + return Component.Identifier.Key.F13; + case VK_F14: + return Component.Identifier.Key.F14; + case VK_F15: + return Component.Identifier.Key.F15; + case VK_KANA: + return Component.Identifier.Key.KANA; + case VK_CONVERT: + return Component.Identifier.Key.CONVERT; + case VK_KANJI: + return Component.Identifier.Key.KANJI; + case VK_OEM_AX: + return Component.Identifier.Key.AX; + case VK_RCONTROL: + return Component.Identifier.Key.RCONTROL; + case VK_SEPARATOR: + return Component.Identifier.Key.NUMPADCOMMA; + case VK_DIVIDE: + return Component.Identifier.Key.DIVIDE; + case VK_SNAPSHOT: + return Component.Identifier.Key.SYSRQ; + case VK_RMENU: + return Component.Identifier.Key.RALT; + case VK_PAUSE: + return Component.Identifier.Key.PAUSE; + case VK_HOME: + return Component.Identifier.Key.HOME; + case VK_UP: + return Component.Identifier.Key.UP; + case VK_PRIOR: + return Component.Identifier.Key.PAGEUP; + case VK_LEFT: + return Component.Identifier.Key.LEFT; + case VK_RIGHT: + return Component.Identifier.Key.RIGHT; + case VK_END: + return Component.Identifier.Key.END; + case VK_DOWN: + return Component.Identifier.Key.DOWN; + case VK_NEXT: + return Component.Identifier.Key.PAGEDOWN; + case VK_INSERT: + return Component.Identifier.Key.INSERT; + case VK_DELETE: + return Component.Identifier.Key.DELETE; + case VK_LWIN: + return Component.Identifier.Key.LWIN; + case VK_RWIN: + return Component.Identifier.Key.RWIN; + case VK_APPS: + return Component.Identifier.Key.APPS; + case VK_SLEEP: + return Component.Identifier.Key.SLEEP; + default: + return Component.Identifier.Key.UNKNOWN; + } + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawInputEnvironmentPlugin.java b/plugins/windows/src/java/net/java/games/input/RawInputEnvironmentPlugin.java new file mode 100644 index 0000000..304ff13 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawInputEnvironmentPlugin.java @@ -0,0 +1,160 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.List; +import java.util.ArrayList; +import java.io.IOException; + +import net.java.games.util.plugins.Plugin; + +/** DirectInput implementation of controller environment + * @author martak + * @author elias + * @version 1.0 + */ +public final class RawInputEnvironmentPlugin extends ControllerEnvironment implements Plugin { + static { + AccessController.doPrivileged( + new PrivilegedAction() { + public final Object run() { + System.loadLibrary("jinput-raw"); + return null; + } + }); + } + + private final Controller[] controllers; + + /** Creates new DirectInputEnvironment */ + public RawInputEnvironmentPlugin() { + RawInputEventQueue queue; + Controller[] controllers = new Controller[]{}; + try { + queue = new RawInputEventQueue(); + controllers = enumControllers(queue); + } catch (IOException e) { + ControllerEnvironment.logln("Failed to enumerate devices: " + e.getMessage()); + } + this.controllers = controllers; + } + + public final Controller[] getControllers() { + return controllers; + } + + private final static SetupAPIDevice lookupSetupAPIDevice(String device_name, List setupapi_devices) { + /* First, replace # with / in the device name, since that + * seems to be the format in raw input device name + */ + device_name = device_name.replaceAll("#", "\\\\").toUpperCase(); + for (int i = 0; i < setupapi_devices.size(); i++) { + SetupAPIDevice device = (SetupAPIDevice)setupapi_devices.get(i); + if (device_name.indexOf(device.getInstanceId().toUpperCase()) != -1) + return device; + } + return null; + } + + private final static void createControllersFromDevices(RawInputEventQueue queue, List controllers, List devices, List setupapi_devices) throws IOException { + List active_devices = new ArrayList(); + for (int i = 0; i < devices.size(); i++) { + RawDevice device = (RawDevice)devices.get(i); + SetupAPIDevice setupapi_device = lookupSetupAPIDevice(device.getName(), setupapi_devices); + if (setupapi_device == null) { + /* Either the device is an RDP or we failed to locate the + * SetupAPI device that matches + */ + continue; + } + RawDeviceInfo info = device.getInfo(); + Controller controller = info.createControllerFromDevice(device, setupapi_device); + if (controller != null) { + controllers.add(controller); + active_devices.add(device); + } + } + queue.start(active_devices); + } + + private final static native void enumerateDevices(RawInputEventQueue queue, List devices) throws IOException; + + private final Controller[] enumControllers(RawInputEventQueue queue) throws IOException { + List controllers = new ArrayList(); + List devices = new ArrayList(); + enumerateDevices(queue, devices); + List setupapi_devices = enumSetupAPIDevices(); + createControllersFromDevices(queue, controllers, devices, setupapi_devices); + Controller[] controllers_array = new Controller[controllers.size()]; + controllers.toArray(controllers_array); + return controllers_array; + } + + /* + * The raw input API, while being able to access + * multiple mice and keyboards, is a bit raw (hah) + * since it lacks some important features: + * + * 1. The list of keyboards and the list of mice + * both include useless Terminal Server + * devices (RDP_MOU and RDP_KEY) that we'd + * like to skip. + * 2. The device names returned by GetRawInputDeviceInfo() + * are not for display, but instead synthesized + * from a combination of a device instance id + * and a GUID. + * + * A solution to both problems is the SetupAPI that allows + * us to enumerate all keyboard and mouse devices and fetch their + * descriptive names and at the same time filter out the unwanted + * RDP devices. + */ + private final static List enumSetupAPIDevices() throws IOException { + List devices = new ArrayList(); + nEnumSetupAPIDevices(getKeyboardClassGUID(), devices); + nEnumSetupAPIDevices(getMouseClassGUID(), devices); + return devices; + } + private final static native void nEnumSetupAPIDevices(byte[] guid, List devices) throws IOException; + + private final static native byte[] getKeyboardClassGUID(); + private final static native byte[] getMouseClassGUID(); +} // class DirectInputEnvironment diff --git a/plugins/windows/src/java/net/java/games/input/RawInputEventQueue.java b/plugins/windows/src/java/net/java/games/input/RawInputEventQueue.java new file mode 100644 index 0000000..99f486d --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawInputEventQueue.java @@ -0,0 +1,157 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Set; +import java.util.HashSet; + +/** Java wrapper of RAWDEVICELIST + * @author elias + * @version 1.0 + */ +final class RawInputEventQueue { + private final Object monitor = new Object(); + + private List devices; + + public final void start(List devices) throws IOException { + this.devices = devices; + QueueThread queue = new QueueThread(); + synchronized (monitor) { + queue.start(); + // wait for initialization + while (!queue.isInitialized()) { + try { + monitor.wait(); + } catch (InterruptedException e) {} + } + } + if (queue.getException() != null) + throw queue.getException(); + } + + private final RawDevice lookupDevice(long handle) { + for (int i = 0; i < devices.size(); i++) { + RawDevice device = (RawDevice)devices.get(i); + if (device.getHandle() == handle) + return device; + } + return null; + } + + /* Event methods called back from native code in nPoll() */ + private final void addMouseEvent(long handle, long millis, int flags, int button_flags, int button_data, long raw_buttons, long last_x, long last_y, long extra_information) { + RawDevice device = lookupDevice(handle); + if (device == null) + return; + device.addMouseEvent(millis, flags, button_flags, button_data, raw_buttons, last_x, last_y, extra_information); + } + + private final void addKeyboardEvent(long handle, long millis, int make_code, int flags, int vkey, int message, long extra_information) { + RawDevice device = lookupDevice(handle); + if (device == null) + return; + device.addKeyboardEvent(millis, make_code, flags, vkey, message, extra_information); + } + + private final void poll(DummyWindow window) throws IOException { + nPoll(window.getHwnd()); + } + private final native void nPoll(long hwnd_handle) throws IOException; + + private final static void registerDevices(DummyWindow window, RawDeviceInfo[] devices) throws IOException { + nRegisterDevices(0, window.getHwnd(), devices); + } + private final static native void nRegisterDevices(int flags, long hwnd_addr, RawDeviceInfo[] devices) throws IOException; + + private final class QueueThread extends Thread { + private boolean initialized; + private DummyWindow window; + private IOException exception; + + public QueueThread() { + setDaemon(true); + } + + public final boolean isInitialized() { + return initialized; + } + + public final IOException getException() { + return exception; + } + + public final void run() { + // We have to create the window in the (private) queue thread + try { + window = new DummyWindow(); + } catch (IOException e) { + exception = e; + } + initialized = true; + synchronized (monitor) { + monitor.notify(); + } + if (exception != null) + return; + Set active_infos = new HashSet(); + try { + for (int i = 0; i < devices.size(); i++) { + RawDevice device = (RawDevice)devices.get(i); + active_infos.add(device.getInfo()); + } + RawDeviceInfo[] active_infos_array = new RawDeviceInfo[active_infos.size()]; + active_infos.toArray(active_infos_array); + try { + registerDevices(window, active_infos_array); + while (!isInterrupted()) { + poll(window); + } + } finally { + window.destroy(); + } + } catch (IOException e) { + exception = e; + } + } + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawKeyboard.java b/plugins/windows/src/java/net/java/games/input/RawKeyboard.java new file mode 100644 index 0000000..728284f --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawKeyboard.java @@ -0,0 +1,130 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** +* @author elias +* @version 1.0 +*/ +final class RawKeyboard extends Keyboard { + private final RawKeyboardEvent raw_event = new RawKeyboardEvent(); + private final RawDevice device; + + protected RawKeyboard(String name, RawDevice device, Controller[] children, Rumbler[] rumblers) throws IOException { + super(name, createKeyboardComponents(device), children, rumblers); + this.device = device; + } + + private final static Component[] createKeyboardComponents(RawDevice device) { + List components = new ArrayList(); + Field[] vkey_fields = RawIdentifierMap.class.getFields(); + for (int i = 0; i < vkey_fields.length; i++) { + Field vkey_field = vkey_fields[i]; + try { + if (Modifier.isStatic(vkey_field.getModifiers()) && vkey_field.getType() == int.class) { + int vkey_code = vkey_field.getInt(null); + Component.Identifier.Key key_id = RawIdentifierMap.mapVKey(vkey_code); + if (key_id != Component.Identifier.Key.UNKNOWN) + components.add(new Key(device, vkey_code, key_id)); + } + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + return (Component[])components.toArray(new Component[]{}); + } + + protected final synchronized boolean getNextDeviceEvent(Event event) throws IOException { + while (true) { + if (!device.getNextKeyboardEvent(raw_event)) + return false; + int vkey = raw_event.getVKey(); + Component.Identifier.Key key_id = RawIdentifierMap.mapVKey(vkey); + Component key = getComponent(key_id); + if (key == null) + continue; + int message = raw_event.getMessage(); + if (message == RawDevice.WM_KEYDOWN || message == RawDevice.WM_SYSKEYDOWN) { + event.set(key, 1, raw_event.getNanos()); + return true; + } else if (message == RawDevice.WM_KEYUP || message == RawDevice.WM_SYSKEYUP) { + event.set(key, 0, raw_event.getNanos()); + return true; + } + } + } + + public final void pollDevice() throws IOException { + device.pollKeyboard(); + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + device.setBufferSize(size); + } + + final static class Key extends AbstractComponent { + private final RawDevice device; + private final int vkey_code; + + public Key(RawDevice device, int vkey_code, Component.Identifier.Key key_id) { + super(key_id.getName(), key_id); + this.device = device; + this.vkey_code = vkey_code; + } + + protected final float poll() throws IOException { + return device.isKeyDown(vkey_code) ? 1f : 0f; + } + + public final boolean isAnalog() { + return false; + } + + public final boolean isRelative() { + return false; + } + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawKeyboardEvent.java b/plugins/windows/src/java/net/java/games/input/RawKeyboardEvent.java new file mode 100644 index 0000000..753baa9 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawKeyboardEvent.java @@ -0,0 +1,79 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RAWKEYBOARD + * @author elias + * @version 1.0 + */ +final class RawKeyboardEvent { + private long millis; + private int make_code; + private int flags; + private int vkey; + private int message; + private long extra_information; + + public final void set(long millis, int make_code, int flags, int vkey, int message, long extra_information) { + this.millis = millis; + this.make_code = make_code; + this.flags = flags; + this.vkey = vkey; + this.message = message; + this.extra_information = extra_information; + } + + public final void set(RawKeyboardEvent event) { + set(event.millis, event.make_code, event.flags, event.vkey, event.message, event.extra_information); + } + + public final int getVKey() { + return vkey; + } + + public final int getMessage() { + return message; + } + + public final long getNanos() { + return millis*1000000L; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawKeyboardInfo.java b/plugins/windows/src/java/net/java/games/input/RawKeyboardInfo.java new file mode 100644 index 0000000..3b4add3 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawKeyboardInfo.java @@ -0,0 +1,81 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RID_DEVICE_INFO_KEYBOARD + * @author elias + * @version 1.0 + */ +class RawKeyboardInfo extends RawDeviceInfo { + private final RawDevice device; + private final int type; + private final int sub_type; + private final int keyboard_mode; + private final int num_function_keys; + private final int num_indicators; + private final int num_keys_total; + + public RawKeyboardInfo(RawDevice device, int type, int sub_type, int keyboard_mode, int num_function_keys, int num_indicators, int num_keys_total) { + this.device = device; + this.type = type; + this.sub_type = sub_type; + this.keyboard_mode = keyboard_mode; + this.num_function_keys = num_function_keys; + this.num_indicators = num_indicators; + this.num_keys_total = num_keys_total; + } + + public final int getUsage() { + return 6; + } + + public final int getUsagePage() { + return 1; + } + + public final long getHandle() { + return device.getHandle(); + } + + public final Controller createControllerFromDevice(RawDevice device, SetupAPIDevice setupapi_device) throws IOException { + return new RawKeyboard(setupapi_device.getName(), device, new Controller[]{}, new Rumbler[]{}); + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawMouse.java b/plugins/windows/src/java/net/java/games/input/RawMouse.java new file mode 100644 index 0000000..597085f --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawMouse.java @@ -0,0 +1,214 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** +* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistribution of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* - Redistribution in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materails provided with the distribution. +* +* Neither the name Sun Microsystems, Inc. or the names of the contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* This software is provided "AS IS," without a warranty of any kind. +* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING +* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR +* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND +* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS +* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS +* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST +* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, +* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY +* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, +* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* +* You acknowledge that this software is not designed or intended for us in +* the design, construction, operation or maintenance of any nuclear facility +* +*****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** +* @author elias +* @version 1.0 +*/ +final class RawMouse extends Mouse { + /* Because one raw event can contain multiple + * changes, we'll make a simple state machine + * to keep track of which change to report next + */ + + // Another event should be read + private final static int EVENT_DONE = 1; + // The X axis should be reported next + private final static int EVENT_X = 2; + // The Y axis should be reported next + private final static int EVENT_Y = 3; + // The Z axis should be reported next + private final static int EVENT_Z = 4; + // Button 0 should be reported next + private final static int EVENT_BUTTON_0 = 5; + // Button 1 should be reported next + private final static int EVENT_BUTTON_1 = 6; + // Button 2 should be reported next + private final static int EVENT_BUTTON_2 = 7; + // Button 3 should be reported next + private final static int EVENT_BUTTON_3 = 8; + // Button 4 should be reported next + private final static int EVENT_BUTTON_4 = 9; + + private final RawDevice device; + + private final RawMouseEvent current_event = new RawMouseEvent(); + private int event_state = EVENT_DONE; + + protected RawMouse(String name, RawDevice device, Component[] components, Controller[] children, Rumbler[] rumblers) throws IOException { + super(name, components, children, rumblers); + this.device = device; + } + + public final void pollDevice() throws IOException { + device.pollMouse(); + } + + private final static boolean makeButtonEvent(RawMouseEvent mouse_event, Event event, Component button_component, int down_flag, int up_flag) { + if ((mouse_event.getButtonFlags() & down_flag) != 0) { + event.set(button_component, 1, mouse_event.getNanos()); + return true; + } else if ((mouse_event.getButtonFlags() & up_flag) != 0) { + event.set(button_component, 0, mouse_event.getNanos()); + return true; + } else + return false; + } + + protected final synchronized boolean getNextDeviceEvent(Event event) throws IOException { + while (true) { + switch (event_state) { + case EVENT_DONE: + if (!device.getNextMouseEvent(current_event)) + return false; + event_state = EVENT_X; + break; + case EVENT_X: + int rel_x = device.getEventRelativeX(); + event_state = EVENT_Y; + if (rel_x != 0) { + event.set(getX(), rel_x, current_event.getNanos()); + return true; + } + break; + case EVENT_Y: + int rel_y = device.getEventRelativeY(); + event_state = EVENT_Z; + if (rel_y != 0) { + event.set(getY(), rel_y, current_event.getNanos()); + return true; + } + break; + case EVENT_Z: + int wheel = current_event.getWheelDelta(); + event_state = EVENT_BUTTON_0; + if (wheel != 0) { + event.set(getWheel(), wheel, current_event.getNanos()); + return true; + } + break; + case EVENT_BUTTON_0: + event_state = EVENT_BUTTON_1; + if (makeButtonEvent(current_event, event, getLeft(), RawDevice.RI_MOUSE_BUTTON_1_DOWN, RawDevice.RI_MOUSE_BUTTON_1_UP)) + return true; + break; + case EVENT_BUTTON_1: + event_state = EVENT_BUTTON_2; + if (makeButtonEvent(current_event, event, getLeft(), RawDevice.RI_MOUSE_BUTTON_2_DOWN, RawDevice.RI_MOUSE_BUTTON_2_UP)) + return true; + break; + case EVENT_BUTTON_2: + event_state = EVENT_BUTTON_3; + if (makeButtonEvent(current_event, event, getLeft(), RawDevice.RI_MOUSE_BUTTON_3_DOWN, RawDevice.RI_MOUSE_BUTTON_3_UP)) + return true; + break; + case EVENT_BUTTON_3: + event_state = EVENT_BUTTON_4; + if (makeButtonEvent(current_event, event, getLeft(), RawDevice.RI_MOUSE_BUTTON_4_DOWN, RawDevice.RI_MOUSE_BUTTON_4_UP)) + return true; + break; + case EVENT_BUTTON_4: + event_state = EVENT_DONE; + if (makeButtonEvent(current_event, event, getLeft(), RawDevice.RI_MOUSE_BUTTON_5_DOWN, RawDevice.RI_MOUSE_BUTTON_5_UP)) + return true; + break; + default: + throw new RuntimeException("Unknown event state: " + event_state); + } + } + } + + protected final void setDeviceEventQueueSize(int size) throws IOException { + device.setBufferSize(size); + } + + final static class Axis extends AbstractComponent { + private final RawDevice device; + + public Axis(RawDevice device, Component.Identifier.Axis axis) { + super(axis.getName(), axis); + this.device = device; + } + + public final boolean isRelative() { + return true; + } + + public final boolean isAnalog() { + return true; + } + + protected final float poll() throws IOException { + if (getIdentifier() == Component.Identifier.Axis.X) { + return device.getRelativeX(); + } else if (getIdentifier() == Component.Identifier.Axis.Y) { + return device.getRelativeY(); + } else if (getIdentifier() == Component.Identifier.Axis.Z) { + return device.getWheel(); + } else + throw new RuntimeException("Unknown raw axis: " + getIdentifier()); + } + } + + final static class Button extends AbstractComponent { + private final RawDevice device; + private final int button_id; + + public Button(RawDevice device, Component.Identifier.Button id, int button_id) { + super(id.getName(), id); + this.device = device; + this.button_id = button_id; + } + + protected final float poll() throws IOException { + return device.getButtonState(button_id) ? 1 : 0; + } + + public final boolean isAnalog() { + return false; + } + + public final boolean isRelative() { + return false; + } + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawMouseEvent.java b/plugins/windows/src/java/net/java/games/input/RawMouseEvent.java new file mode 100644 index 0000000..1cc8fce --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawMouseEvent.java @@ -0,0 +1,108 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RAWMOUSE + * @author elias + * @version 1.0 + */ +final class RawMouseEvent { + /* It seems that raw input scales wheel + * the same way as direcinput + */ + private final static int WHEEL_SCALE = 120; + + private long millis; + private int flags; + private int button_flags; + private int button_data; + private long raw_buttons; + private long last_x; + private long last_y; + private long extra_information; + + public final void set(long millis, int flags, int button_flags, int button_data, long raw_buttons, long last_x, long last_y, long extra_information) { + this.millis = millis; + this.flags = flags; + this.button_flags = button_flags; + this.button_data = button_data; + this.raw_buttons = raw_buttons; + this.last_x = last_x; + this.last_y = last_y; + this.extra_information = extra_information; + } + + public final void set(RawMouseEvent event) { + set(event.millis, event.flags, event.button_flags, event.button_data, event.raw_buttons, event.last_x, event.last_y, event.extra_information); + } + + public final int getWheelDelta() { + return button_data/WHEEL_SCALE; + } + + private final int getButtonData() { + return button_data; + } + + public final int getFlags() { + return flags; + } + + public final int getButtonFlags() { + return button_flags; + } + + public final int getLastX() { + return (int)last_x; + } + + public final int getLastY() { + return (int)last_y; + } + + public final long getRawButtons() { + return raw_buttons; + } + + public final long getNanos() { + return millis*1000000L; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/RawMouseInfo.java b/plugins/windows/src/java/net/java/games/input/RawMouseInfo.java new file mode 100644 index 0000000..aa89e94 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/RawMouseInfo.java @@ -0,0 +1,88 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of RID_DEVICE_INFO_MOUSE + * @author elias + * @version 1.0 + */ +class RawMouseInfo extends RawDeviceInfo { + private final RawDevice device; + private final int id; + private final int num_buttons; + private final int sample_rate; + + public RawMouseInfo(RawDevice device, int id, int num_buttons, int sample_rate) { + this.device = device; + this.id = id; + this.num_buttons = num_buttons; + this.sample_rate = sample_rate; + } + + public final int getUsage() { + return 2; + } + + public final int getUsagePage() { + return 1; + } + + public final long getHandle() { + return device.getHandle(); + } + + public final Controller createControllerFromDevice(RawDevice device, SetupAPIDevice setupapi_device) throws IOException { + if (num_buttons == 0) + return null; + // A raw mouse contains the x and y and z axis and the buttons + Component[] components = new Component[3 + num_buttons]; + int index = 0; + components[index++] = new RawMouse.Axis(device, Component.Identifier.Axis.X); + components[index++] = new RawMouse.Axis(device, Component.Identifier.Axis.Y); + components[index++] = new RawMouse.Axis(device, Component.Identifier.Axis.Z); + for (int i = 0; i < num_buttons; i++) { + Component.Identifier.Button id = DIIdentifierMap.mapMouseButtonIdentifier(DIIdentifierMap.getButtonIdentifier(i)); + components[index++] = new RawMouse.Button(device, id, i); + } + Controller mouse = new RawMouse(setupapi_device.getName(), device, components, new Controller[]{}, new Rumbler[]{}); + return mouse; + } +} diff --git a/plugins/windows/src/java/net/java/games/input/SetupAPIDevice.java b/plugins/windows/src/java/net/java/games/input/SetupAPIDevice.java new file mode 100644 index 0000000..1c84545 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/SetupAPIDevice.java @@ -0,0 +1,63 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +/***************************************************************************** + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materails provided with the distribution. + * + * Neither the name Sun Microsystems, Inc. or the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND + * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS + * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY + * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for us in + * the design, construction, operation or maintenance of any nuclear facility + * + *****************************************************************************/ +package net.java.games.input; + +import java.io.IOException; + +/** Java wrapper of a SetupAPI device + * @author elias + * @version 1.0 + */ +final class SetupAPIDevice { + private final String device_instance_id; + private final String device_name; + + public SetupAPIDevice(String device_instance_id, String device_name) { + this.device_instance_id = device_instance_id; + this.device_name = device_name; + } + + public final String getName() { + return device_name; + } + + public final String getInstanceId() { + return device_instance_id; + } +} diff --git a/plugins/windows/src/native/build.xml b/plugins/windows/src/native/build.xml new file mode 100644 index 0000000..02225a7 --- /dev/null +++ b/plugins/windows/src/native/build.xml @@ -0,0 +1,87 @@ +<?xml version="1.0"?> + +<project name="JInput dx8 port, Native code" basedir="." default="compile"> + <target name="init"> + </target> + + <target name="compile_dir" depends="init"> + <echo message="${compiledir}"/> + <apply dir="${compiledir}" failonerror="true" executable="cl" dest="${compiledir}" skipemptyfilesets="true"> + <arg line="/Ox /Wp64 /W2 /nologo /c"/> + <arg value="/I${toolkithome}\include"/> + <arg value="/I${sdkhome}\include"/> + <arg value="/I${dxhome}\include"/> + <arg value="/I${java.home}\..\include"/> + <arg value="/I${java.home}\..\include\win32"/> + <arg value="/I${commonhome}/src/native"/> + <arg value="/I.."/> + <srcfile/> + <fileset dir="${compiledir}" includes="*.c"/> + <mapper type="glob" from="*.c" to="*.obj"/> + </apply> + </target> + + <!-- <target name="link" unless="nolink">--> + <target name="link"> + <apply dir="." parallel="true" executable="cl" failonerror="true"> + <arg line="/LD /nologo"/> + <srcfile/> + <arg line="/Fe${dllname} /link"/> + <arg value="/LIBPATH:${java.home}\lib"/> + <arg value="/LIBPATH:${dxhome}\lib\x86"/> + <arg value="/LIBPATH:${sdkhome}\lib"/> + <arg value="/LIBPATH:${toolkithome}\lib"/> + <arg line="/DLL ${libs}"/> + <fileset dir="${commonhome}/src/native" includes="*.obj"/> + <fileset dir="." includes="*.obj"/> + <fileset dir="${objdir}" includes="*.obj"/> + </apply> + </target> + + <target name="clean"> + <delete> + <fileset dir="." includes="*.obj"/> + <fileset dir="raw" includes="*.obj"/> + <fileset dir="dx8" includes="*.obj"/> + <fileset dir="." includes="*.dll"/> + </delete> + </target> + + <target name="compile" depends="init"> + <property name="program_files" location="c:\Program Files"/> + <property name="dxhome" location="${program_files}\Microsoft DirectX SDK (February 2006)"/> + <property name="toolkithome" location="${program_files}\Microsoft Visual C++ Toolkit 2003"/> + <property name="rawlibs" value="Kernel32.lib User32.lib Setupapi.lib"/> + <property name="dx8libs" value="Kernel32.lib dinput8.lib dxguid.lib User32.lib"/> + <property name="sdkhome" location="${program_files}\Microsoft Platform SDK"/> + <property name="commonhome" location="../../../common"/> + <property name="dx8dllname" value="jinput-dx8.dll"/> + <property name="rawdllname" value="jinput-raw.dll"/> + <antcall target="compile_dir"> + <param name="compiledir" location="${commonhome}/src/native"/> + </antcall> + <antcall target="compile_dir"> + <param name="compiledir" location="."/> + </antcall> + <antcall target="compile_dir"> + <param name="compiledir" location="raw"/> + </antcall> + <antcall target="compile_dir"> + <param name="compiledir" location="dx8"/> + </antcall> + <!-- <uptodate property="nolink" targetfile="${dllname}"> + <srcfiles dir="." includes="*.obj"/> + </uptodate>--> + <antcall target="link"> + <param name="dllname" value="${dx8dllname}"/> + <param name="libs" value="${dx8libs}"/> + <param name="objdir" location="dx8"/> + </antcall> + <antcall target="link"> + <param name="dllname" value="${rawdllname}"/> + <param name="libs" value="${rawlibs}"/> + <param name="objdir" location="raw"/> + </antcall> + </target> +</project> + diff --git a/plugins/windows/src/native/dx8/dxversion.h b/plugins/windows/src/native/dx8/dxversion.h new file mode 100644 index 0000000..396c7f7 --- /dev/null +++ b/plugins/windows/src/native/dx8/dxversion.h @@ -0,0 +1,13 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef DXVERSION_H +#define DXVERSION_H + +#define DIRECTINPUT_VERSION 0x0800 + +#endif diff --git a/plugins/windows/src/native/dx8/net_java_games_input_IDirectInput.c b/plugins/windows/src/native/dx8/net_java_games_input_IDirectInput.c new file mode 100644 index 0000000..ae7b0ca --- /dev/null +++ b/plugins/windows/src/native/dx8/net_java_games_input_IDirectInput.c @@ -0,0 +1,103 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include <windows.h> +#include <jni.h> +#include "dxversion.h" +#include <dinput.h> +#include "net_java_games_input_IDirectInput.h" +#include "util.h" +#include "winutil.h" + +typedef struct { + LPDIRECTINPUT8 lpDirectInput; + JNIEnv *env; + jobject obj; +} enum_context_t; + +JNIEXPORT jlong JNICALL Java_net_java_games_input_IDirectInput_createIDirectInput(JNIEnv *env, jclass unused) { + LPDIRECTINPUT8 lpDirectInput; + HRESULT res = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, + &IID_IDirectInput8,(VOID **)&lpDirectInput, NULL); + if (FAILED(res)) { + throwIOException(env, "Failed to create IDirectInput8 (%d)\n", res); + return 0; + } + return (jlong)(INT_PTR)lpDirectInput; +} + +static BOOL CALLBACK enumerateDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID context) { + enum_context_t *enum_context = (enum_context_t *)context; +// LPCDIDATAFORMAT lpDataFormat; + LPDIRECTINPUTDEVICE8 lpDevice; + DWORD device_type; + DWORD device_subtype; + HRESULT res; + jclass obj_class; + jmethodID IDirectInput_addDevice; + jstring instance_name; + jstring product_name; + jbyteArray instance_guid; + jbyteArray product_guid; + + instance_guid = wrapGUID(enum_context->env, &(lpddi->guidInstance)); + if (instance_guid == NULL) + return DIENUM_STOP; + product_guid = wrapGUID(enum_context->env, &(lpddi->guidProduct)); + if (product_guid == NULL) + return DIENUM_STOP; + instance_name = (*enum_context->env)->NewStringUTF(enum_context->env, lpddi->tszInstanceName); + if (instance_name == NULL) + return DIENUM_STOP; + product_name = (*enum_context->env)->NewStringUTF(enum_context->env, lpddi->tszProductName); + if (product_name == NULL) + return DIENUM_STOP; + + obj_class = (*enum_context->env)->GetObjectClass(enum_context->env, enum_context->obj); + if (obj_class == NULL) + return DIENUM_STOP; + + IDirectInput_addDevice = (*enum_context->env)->GetMethodID(enum_context->env, obj_class, "addDevice", "(J[B[BIILjava/lang/String;Ljava/lang/String;)V"); + if (IDirectInput_addDevice == NULL) + return DIENUM_STOP; + + res = IDirectInput8_CreateDevice(enum_context->lpDirectInput, &(lpddi->guidInstance), &lpDevice, NULL); + if (FAILED(res)) { + throwIOException(enum_context->env, "Failed to create device (%d)\n", res); + return DIENUM_STOP; + } + + device_type = GET_DIDEVICE_TYPE(lpddi->dwDevType); + device_subtype = GET_DIDEVICE_SUBTYPE(lpddi->dwDevType); + + (*enum_context->env)->CallVoidMethod(enum_context->env, enum_context->obj, IDirectInput_addDevice, (jlong)(INT_PTR)lpDevice, instance_guid, product_guid, (jint)device_type, (jint)device_subtype, instance_name, product_name); + if ((*enum_context->env)->ExceptionOccurred(enum_context->env) != NULL) { + IDirectInputDevice8_Release(lpDevice); + return DIENUM_STOP; + } + + return DIENUM_CONTINUE; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInput_nEnumDevices(JNIEnv *env, jobject obj, jlong address) { + LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(INT_PTR)address; + HRESULT res; + + enum_context_t enum_context; + enum_context.lpDirectInput = lpDirectInput; + enum_context.env = env; + enum_context.obj = obj; + res = IDirectInput8_EnumDevices(lpDirectInput, DI8DEVCLASS_ALL, enumerateDevicesCallback, &enum_context, DIEDFL_ATTACHEDONLY); + if (FAILED(res)) { + throwIOException(env, "Failed to enumerate devices (%d)\n", res); + } +} + +JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInput_nRelease(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(INT_PTR)address; + IDirectInput8_Release(lpDirectInput); +} diff --git a/plugins/windows/src/native/dx8/net_java_games_input_IDirectInputDevice.c b/plugins/windows/src/native/dx8/net_java_games_input_IDirectInputDevice.c new file mode 100644 index 0000000..d4561b3 --- /dev/null +++ b/plugins/windows/src/native/dx8/net_java_games_input_IDirectInputDevice.c @@ -0,0 +1,532 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include <windows.h> +#include "dxversion.h" +#include <jni.h> +#include <dinput.h> +#include "net_java_games_input_IDirectInputDevice.h" +#include "util.h" +#include "winutil.h" + +typedef struct { + JNIEnv *env; + jobject device_obj; +} enum_context_t; + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetBufferSize(JNIEnv *env, jclass unused, jlong address, jint size) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + DIPROPDWORD dipropdw; + HRESULT res; + + dipropdw.diph.dwSize = sizeof(DIPROPDWORD); + dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipropdw.diph.dwObj = 0; + dipropdw.diph.dwHow = DIPH_DEVICE; + dipropdw.dwData = size; + res = IDirectInputDevice8_SetProperty(lpDevice, DIPROP_BUFFERSIZE, &dipropdw.diph); + return res; +} + +static const GUID *mapGUIDId(const jint guid_id) { + switch (guid_id) { + case net_java_games_input_IDirectInputDevice_GUID_XAxis: + return &GUID_XAxis; + case net_java_games_input_IDirectInputDevice_GUID_YAxis: + return &GUID_YAxis; + case net_java_games_input_IDirectInputDevice_GUID_ZAxis: + return &GUID_ZAxis; + case net_java_games_input_IDirectInputDevice_GUID_RxAxis: + return &GUID_RxAxis; + case net_java_games_input_IDirectInputDevice_GUID_RyAxis: + return &GUID_RyAxis; + case net_java_games_input_IDirectInputDevice_GUID_RzAxis: + return &GUID_RzAxis; + case net_java_games_input_IDirectInputDevice_GUID_Slider: + return &GUID_Slider; + case net_java_games_input_IDirectInputDevice_GUID_Button: + return &GUID_Button; + case net_java_games_input_IDirectInputDevice_GUID_Key: + return &GUID_Key; + case net_java_games_input_IDirectInputDevice_GUID_POV: + return &GUID_POV; + case net_java_games_input_IDirectInputDevice_GUID_Unknown: + default: + return NULL; + } +} + +static jint mapGUIDType(const GUID *guid) { + if (IsEqualGUID(guid, &GUID_XAxis)) { + return net_java_games_input_IDirectInputDevice_GUID_XAxis; + } else if (IsEqualGUID(guid, &GUID_YAxis)) { + return net_java_games_input_IDirectInputDevice_GUID_YAxis; + } else if (IsEqualGUID(guid, &GUID_ZAxis)) { + return net_java_games_input_IDirectInputDevice_GUID_ZAxis; + } else if (IsEqualGUID(guid, &GUID_RxAxis)) { + return net_java_games_input_IDirectInputDevice_GUID_RxAxis; + } else if (IsEqualGUID(guid, &GUID_RyAxis)) { + return net_java_games_input_IDirectInputDevice_GUID_RyAxis; + } else if (IsEqualGUID(guid, &GUID_RzAxis)) { + return net_java_games_input_IDirectInputDevice_GUID_RzAxis; + } else if (IsEqualGUID(guid, &GUID_Slider)) { + return net_java_games_input_IDirectInputDevice_GUID_Slider; + } else if (IsEqualGUID(guid, &GUID_Button)) { + return net_java_games_input_IDirectInputDevice_GUID_Button; + } else if (IsEqualGUID(guid, &GUID_Key)) { + return net_java_games_input_IDirectInputDevice_GUID_Key; + } else if (IsEqualGUID(guid, &GUID_POV)) { + return net_java_games_input_IDirectInputDevice_GUID_POV; + } else if (IsEqualGUID(guid, &GUID_ConstantForce)) { + return net_java_games_input_IDirectInputDevice_GUID_ConstantForce; + } else if (IsEqualGUID(guid, &GUID_RampForce)) { + return net_java_games_input_IDirectInputDevice_GUID_RampForce; + } else if (IsEqualGUID(guid, &GUID_Square)) { + return net_java_games_input_IDirectInputDevice_GUID_Square; + } else if (IsEqualGUID(guid, &GUID_Sine)) { + return net_java_games_input_IDirectInputDevice_GUID_Sine; + } else if (IsEqualGUID(guid, &GUID_Triangle)) { + return net_java_games_input_IDirectInputDevice_GUID_Triangle; + } else if (IsEqualGUID(guid, &GUID_SawtoothUp)) { + return net_java_games_input_IDirectInputDevice_GUID_SawtoothUp; + } else if (IsEqualGUID(guid, &GUID_SawtoothDown)) { + return net_java_games_input_IDirectInputDevice_GUID_SawtoothDown; + } else if (IsEqualGUID(guid, &GUID_Spring)) { + return net_java_games_input_IDirectInputDevice_GUID_Spring; + } else if (IsEqualGUID(guid, &GUID_Damper)) { + return net_java_games_input_IDirectInputDevice_GUID_Damper; + } else if (IsEqualGUID(guid, &GUID_Inertia)) { + return net_java_games_input_IDirectInputDevice_GUID_Inertia; + } else if (IsEqualGUID(guid, &GUID_Friction)) { + return net_java_games_input_IDirectInputDevice_GUID_Friction; + } else if (IsEqualGUID(guid, &GUID_CustomForce)) { + return net_java_games_input_IDirectInputDevice_GUID_CustomForce; + } else + return net_java_games_input_IDirectInputDevice_GUID_Unknown; +} + +static BOOL CALLBACK enumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef) { + enum_context_t *enum_context = (enum_context_t *)pvRef; + jmethodID add_method; + jstring name; + DWORD instance; + DWORD type; + jint guid_type; + jbyteArray guid; + JNIEnv *env = enum_context->env; + jobject device_obj = enum_context->device_obj; + jint guid_id; + jclass obj_class = (*env)->GetObjectClass(env, device_obj); + + + if (obj_class == NULL) + return DIENUM_STOP; + guid = wrapGUID(env, &(pdei->guid)); + if (guid == NULL) + return DIENUM_STOP; + add_method = (*env)->GetMethodID(env, obj_class, "addEffect", "([BIIIILjava/lang/String;)V"); + if (add_method == NULL) + return DIENUM_STOP; + name = (*env)->NewStringUTF(env, pdei->tszName); + if (name == NULL) + return DIENUM_STOP; + guid_id = mapGUIDType(&(pdei->guid)); + (*env)->CallBooleanMethod(env, device_obj, add_method, guid, guid_id, (jint)pdei->dwEffType, (jint)pdei->dwStaticParams, (jint)pdei->dwDynamicParams, name); + if ((*env)->ExceptionOccurred(env)) { + return DIENUM_STOP; + } + return DIENUM_CONTINUE; +} + +static BOOL CALLBACK enumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { + enum_context_t *enum_context = (enum_context_t *)pvRef; + jmethodID add_method; + jstring name; + DWORD instance; + DWORD type; + jint guid_type; + jbyteArray guid; + JNIEnv *env = enum_context->env; + jobject device_obj = enum_context->device_obj; + jclass obj_class = (*env)->GetObjectClass(env, device_obj); + + if (obj_class == NULL) + return DIENUM_STOP; + guid = wrapGUID(env, &(lpddoi->guidType)); + if (guid == NULL) + return DIENUM_STOP; + add_method = (*env)->GetMethodID(env, obj_class, "addObject", "([BIIIIILjava/lang/String;)V"); + if (add_method == NULL) + return DIENUM_STOP; + name = (*env)->NewStringUTF(env, lpddoi->tszName); + if (name == NULL) + return DIENUM_STOP; + instance = DIDFT_GETINSTANCE(lpddoi->dwType); + type = DIDFT_GETTYPE(lpddoi->dwType); + guid_type = mapGUIDType(&(lpddoi->guidType)); +//printfJava(env, "name %s guid_type %d id %d\n", lpddoi->tszName, guid_type, lpddoi->dwType); + (*env)->CallBooleanMethod(env, device_obj, add_method, guid, (jint)guid_type, (jint)lpddoi->dwType, (jint)type, (jint)instance, (jint)lpddoi->dwFlags, name); + if ((*env)->ExceptionOccurred(env)) { + return DIENUM_STOP; + } + return DIENUM_CONTINUE; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetRangeProperty(JNIEnv *env, jclass unused, jlong address, jint object_id, jlongArray range_array_obj) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + DIPROPRANGE range; + HRESULT res; + jlong range_array[2]; + + range.diph.dwSize = sizeof(DIPROPRANGE); + range.diph.dwHeaderSize = sizeof(DIPROPHEADER); + range.diph.dwObj = object_id; + range.diph.dwHow = DIPH_BYID; + res = IDirectInputDevice8_GetProperty(lpDevice, DIPROP_RANGE, &(range.diph)); + range_array[0] = range.lMin; + range_array[1] = range.lMax; + (*env)->SetLongArrayRegion(env, range_array_obj, 0, 2, range_array); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeadzoneProperty(JNIEnv *env, jclass unused, jlong address, jint object_id) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + DIPROPDWORD deadzone; + HRESULT res; + + deadzone.diph.dwSize = sizeof(deadzone); + deadzone.diph.dwHeaderSize = sizeof(DIPROPHEADER); + deadzone.diph.dwObj = object_id; + deadzone.diph.dwHow = DIPH_BYID; + res = IDirectInputDevice8_GetProperty(lpDevice, DIPROP_DEADZONE, &(deadzone.diph)); + if (res != DI_OK && res != S_FALSE) + throwIOException(env, "Failed to get deadzone property (%x)\n", res); + return deadzone.dwData; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetDataFormat(JNIEnv *env, jclass unused, jlong address, jint flags, jobjectArray objects) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + DIDATAFORMAT data_format; + jsize num_objects = (*env)->GetArrayLength(env, objects); + /* + * Data size must be a multiple of 4, but since sizeof(jint) is + * 4, we're safe + */ + DWORD data_size = num_objects*sizeof(jint); + GUID *guids; + DIOBJECTDATAFORMAT *object_formats; + int i; + HRESULT res; + jclass clazz; + jmethodID getGUID_method; + jmethodID getFlags_method; + jmethodID getType_method; + jmethodID getInstance_method; + jobject object; + jint type; + jint guid_id; + jint object_flags; + jint instance; + jobject guid_array; + DWORD composite_type; + DWORD flags_masked; + LPDIOBJECTDATAFORMAT object_format; + + data_format.dwSize = sizeof(DIDATAFORMAT); + data_format.dwObjSize = sizeof(DIOBJECTDATAFORMAT); + data_format.dwFlags = flags; + data_format.dwDataSize = data_size; + data_format.dwNumObjs = num_objects; + + clazz = (*env)->FindClass(env, "net/java/games/input/DIDeviceObject"); + if (clazz == NULL) + return -1; + getGUID_method = (*env)->GetMethodID(env, clazz, "getGUID", "()[B"); + if (getGUID_method == NULL) + return -1; + getFlags_method = (*env)->GetMethodID(env, clazz, "getFlags", "()I"); + if (getFlags_method == NULL) + return -1; + getType_method = (*env)->GetMethodID(env, clazz, "getType", "()I"); + if (getType_method == NULL) + return -1; + getInstance_method = (*env)->GetMethodID(env, clazz, "getInstance", "()I"); + if (getInstance_method == NULL) + return -1; + + guids = (GUID *)malloc(num_objects*sizeof(GUID)); + if (guids == NULL) { + throwIOException(env, "Failed to allocate GUIDs"); + return -1; + } + object_formats = (DIOBJECTDATAFORMAT *)malloc(num_objects*sizeof(DIOBJECTDATAFORMAT)); + if (object_formats == NULL) { + free(guids); + throwIOException(env, "Failed to allocate data format"); + return -1; + } + for (i = 0; i < num_objects; i++) { + object = (*env)->GetObjectArrayElement(env, objects, i); + if ((*env)->ExceptionOccurred(env)) { + free(guids); + free(object_formats); + return -1; + } + guid_array = (*env)->CallObjectMethod(env, object, getGUID_method); + if ((*env)->ExceptionOccurred(env)) { + free(guids); + free(object_formats); + return -1; + } + unwrapGUID(env, guid_array, guids + i); + if ((*env)->ExceptionOccurred(env)) { + free(guids); + free(object_formats); + return -1; + } + type = (*env)->CallIntMethod(env, object, getType_method); + if ((*env)->ExceptionOccurred(env)) { + free(guids); + free(object_formats); + return -1; + } + object_flags = (*env)->CallIntMethod(env, object, getFlags_method); + if ((*env)->ExceptionOccurred(env)) { + free(guids); + free(object_formats); + return -1; + } + instance = (*env)->CallIntMethod(env, object, getInstance_method); + if ((*env)->ExceptionOccurred(env)) { + free(guids); + free(object_formats); + return -1; + } + (*env)->DeleteLocalRef(env, object); + composite_type = type | DIDFT_MAKEINSTANCE(instance); + flags_masked = flags & (DIDOI_ASPECTACCEL | DIDOI_ASPECTFORCE | DIDOI_ASPECTPOSITION | DIDOI_ASPECTVELOCITY); + object_format = object_formats + i; + object_format->pguid = guids + i; + object_format->dwType = composite_type; + object_format->dwFlags = flags_masked; + // dwOfs must be multiple of 4, but sizeof(jint) is 4, so we're safe + object_format->dwOfs = i*sizeof(jint); + } + data_format.rgodf = object_formats; + res = IDirectInputDevice8_SetDataFormat(lpDevice, &data_format); + free(guids); + free(object_formats); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nAcquire(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + + HRESULT res = IDirectInputDevice8_Acquire(lpDevice); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nUnacquire(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + + HRESULT res = IDirectInputDevice8_Unacquire(lpDevice); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nPoll(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + + HRESULT res = IDirectInputDevice8_Poll(lpDevice); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeviceState(JNIEnv *env, jclass unused, jlong address, jintArray device_state_array) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + jsize state_length = (*env)->GetArrayLength(env, device_state_array); + DWORD state_size = state_length*sizeof(jint); + HRESULT res; + jint *device_state = (*env)->GetIntArrayElements(env, device_state_array, NULL); + if (device_state == NULL) + return -1; + + res = IDirectInputDevice8_GetDeviceState(lpDevice, state_size, device_state); + (*env)->ReleaseIntArrayElements(env, device_state_array, device_state, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeviceData(JNIEnv *env, jclass unused, jlong address, jint flags, jobject queue, jobject queue_array, jint position, jint remaining) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + DWORD num_events = remaining; + DIDEVICEOBJECTDATA *data; + DIDEVICEOBJECTDATA *data_element; + jmethodID set_method; + HRESULT res; + int i; + jclass data_class; + jclass queue_class; + jmethodID position_method; + + data_class = (*env)->FindClass(env, "net/java/games/input/DIDeviceObjectData"); + if (data_class == NULL) + return -1; + set_method = (*env)->GetMethodID(env, data_class, "set", "(IIII)V"); + if (set_method == NULL) + return -1; + queue_class = (*env)->GetObjectClass(env, queue); + if (queue_class == NULL) + return -1; + position_method = (*env)->GetMethodID(env, queue_class, "position", "(I)V"); + if (position_method == NULL) + return -1; + + data = (DIDEVICEOBJECTDATA *)malloc(num_events*sizeof(DIDEVICEOBJECTDATA)); + + res = IDirectInputDevice8_GetDeviceData(lpDevice, sizeof(DIDEVICEOBJECTDATA), data, &num_events, flags); + if (res == DI_OK || res == DI_BUFFEROVERFLOW) { + for (i = 0; i < num_events; i++) { + jobject queue_element = (*env)->GetObjectArrayElement(env, queue_array, position + i); + if (queue_element == NULL) { + free(data); + return -1; + } + data_element = data + i; + (*env)->CallVoidMethod(env, queue_element, set_method, (jint)data_element->dwOfs, (jint)data_element->dwData, (jint)data_element->dwTimeStamp, (jint)data_element->dwSequence); + if ((*env)->ExceptionOccurred(env)) { + free(data); + return -1; + } + } + (*env)->CallVoidMethod(env, queue, position_method, position + num_events); + } + free(data); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nEnumEffects(JNIEnv *env, jobject device_obj, jlong address, jint flags) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + HRESULT res; + enum_context_t enum_context; + + enum_context.env = env; + enum_context.device_obj = device_obj; + res = IDirectInputDevice8_EnumEffects(lpDevice, enumEffectsCallback, &enum_context, flags); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nEnumObjects(JNIEnv *env, jobject device_obj, jlong address, jint flags) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + HRESULT res; + enum_context_t enum_context; + + enum_context.env = env; + enum_context.device_obj = device_obj; + res = IDirectInputDevice8_EnumObjects(lpDevice, enumObjectsCallback, &enum_context, flags); + return res; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetCooperativeLevel(JNIEnv *env, jclass unused, jlong address, jlong hwnd_address, jint flags) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + HWND hwnd = (HWND)(INT_PTR)hwnd_address; + + HRESULT res = IDirectInputDevice8_SetCooperativeLevel(lpDevice, hwnd, flags); + return res; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInputDevice_nRelease(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + + IDirectInputDevice8_Release(lpDevice); +} + +JNIEXPORT jlong JNICALL Java_net_java_games_input_IDirectInputDevice_nCreatePeriodicEffect(JNIEnv *env, jclass unused, jlong address, jbyteArray effect_guid_array, jint flags, jint duration, jint sample_period, jint gain, jint trigger_button, jint trigger_repeat_interval, jintArray axis_ids_array, jlongArray directions_array, jint envelope_attack_level, jint envelope_attack_time, jint envelope_fade_level, jint envelope_fade_time, jint periodic_magnitude, jint periodic_offset, jint periodic_phase, jint periodic_period, jint start_delay) { + LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; + LPDIRECTINPUTEFFECT lpdiEffect; + DIEFFECT effect; + GUID effect_guid; + jint *axis_ids; + jlong *directions; + jsize num_axes; + jsize num_directions; + LONG *directions_long; + DWORD *axis_ids_dword; + HRESULT res; + DIPERIODIC periodic; + DIENVELOPE envelope; + int i; + + num_axes = (*env)->GetArrayLength(env, axis_ids_array); + num_directions = (*env)->GetArrayLength(env, directions_array); + + if (num_axes != num_directions) { + throwIOException(env, "axis_ids.length != directions.length\n"); + return 0; + } + + unwrapGUID(env, effect_guid_array, &effect_guid); + if ((*env)->ExceptionOccurred(env)) + return 0; + axis_ids = (*env)->GetIntArrayElements(env, axis_ids_array, NULL); + if (axis_ids == NULL) + return 0; + directions = (*env)->GetLongArrayElements(env, directions_array, NULL); + if (axis_ids == NULL) + return 0; + axis_ids_dword = (DWORD *)malloc(sizeof(DWORD)*num_axes); + if (axis_ids_dword == NULL) { + throwIOException(env, "Failed to allocate axes array\n"); + return 0; + } + directions_long = (LONG *)malloc(sizeof(LONG)*num_directions); + if (directions_long == NULL) { + free(axis_ids_dword); + throwIOException(env, "Failed to allocate directions array\n"); + return 0; + } + for (i = 0; i < num_axes; i++) { + axis_ids_dword[i] = axis_ids[i]; + } + for (i = 0; i < num_directions; i++) { + directions_long[i] = directions[i]; + } + + envelope.dwSize = sizeof(DIENVELOPE); + envelope.dwAttackLevel = envelope_attack_level; + envelope.dwAttackTime = envelope_attack_time; + envelope.dwFadeLevel = envelope_fade_level; + envelope.dwFadeTime = envelope_fade_time; + + periodic.dwMagnitude = periodic_magnitude; + periodic.lOffset = periodic_offset; + periodic.dwPhase = periodic_phase; + periodic.dwPeriod = periodic_period; + + effect.dwSize = sizeof(DIEFFECT); + effect.dwFlags = flags; + effect.dwDuration = duration; + effect.dwSamplePeriod = sample_period; + effect.dwGain = gain; + effect.dwTriggerButton = trigger_button; + effect.dwTriggerRepeatInterval = trigger_repeat_interval; + effect.cAxes = num_axes; + effect.rgdwAxes = axis_ids_dword; + effect.rglDirection = directions_long; + effect.lpEnvelope = &envelope; + effect.cbTypeSpecificParams = sizeof(periodic); + effect.lpvTypeSpecificParams = &periodic; + effect.dwStartDelay = start_delay; + + res = IDirectInputDevice8_CreateEffect(lpDevice, &effect_guid, &effect, &lpdiEffect, NULL); + (*env)->ReleaseIntArrayElements(env, axis_ids_array, axis_ids, 0); + (*env)->ReleaseLongArrayElements(env, directions_array, directions, 0); + free(axis_ids_dword); + free(directions_long); + if (res != DI_OK) { + throwIOException(env, "Failed to create effect (0x%x)\n", res); + return 0; + } + return (jlong)(INT_PTR)lpdiEffect; +} diff --git a/plugins/windows/src/native/dx8/net_java_games_input_IDirectInputEffect.c b/plugins/windows/src/native/dx8/net_java_games_input_IDirectInputEffect.c new file mode 100644 index 0000000..4553817 --- /dev/null +++ b/plugins/windows/src/native/dx8/net_java_games_input_IDirectInputEffect.c @@ -0,0 +1,42 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include <windows.h> +#include "dxversion.h" +#include <jni.h> +#include <dinput.h> +#include "net_java_games_input_IDirectInputEffect.h" +#include "util.h" + +JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInputEffect_nRelease(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address; + + IDirectInputEffect_Release(ppdeff); +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputEffect_nSetGain(JNIEnv *env, jclass unused, jlong address, jint gain) { + LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address; + DIEFFECT params; + + ZeroMemory(¶ms, sizeof(params)); + params.dwSize = sizeof(params); + params.dwGain = gain; + + return IDirectInputEffect_SetParameters(ppdeff, ¶ms, DIEP_GAIN); +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputEffect_nStart(JNIEnv *env, jclass unused, jlong address, jint iterations, jint flags) { + LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address; + + return IDirectInputEffect_Start(ppdeff, iterations, flags); +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputEffect_nStop(JNIEnv *env, jclass unused, jlong address) { + LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address; + + return IDirectInputEffect_Stop(ppdeff); +} diff --git a/plugins/windows/src/native/net_java_games_input_DummyWindow.c b/plugins/windows/src/native/net_java_games_input_DummyWindow.c new file mode 100644 index 0000000..539e45c --- /dev/null +++ b/plugins/windows/src/native/net_java_games_input_DummyWindow.c @@ -0,0 +1,71 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include <windows.h> +#include <jni.h> +#include "net_java_games_input_DummyWindow.h" +#include "util.h" + +static const TCHAR* DUMMY_WINDOW_NAME = "JInputControllerWindow"; + +static LRESULT CALLBACK DummyWndProc( + HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + return DefWindowProc(hWnd, message, wParam, lParam); +} + +static BOOL RegisterDummyWindow(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)DummyWndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = NULL; + wcex.hCursor = NULL; + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = (LPCSTR)NULL; + wcex.lpszClassName = DUMMY_WINDOW_NAME; + wcex.hIconSm = NULL; + return RegisterClassEx(&wcex); +} + +JNIEXPORT jlong JNICALL Java_net_java_games_input_DummyWindow_createWindow(JNIEnv *env, jclass unused) { + HINSTANCE hInst = GetModuleHandle(NULL); + HWND hwndDummy; + WNDCLASSEX class_info; + class_info.cbSize = sizeof(WNDCLASSEX); + class_info.cbClsExtra = 0; + class_info.cbWndExtra = 0; + + if (!GetClassInfoEx(hInst, DUMMY_WINDOW_NAME, &class_info)) { + // Register the dummy input window + if (!RegisterDummyWindow(hInst)) { + throwIOException(env, "Failed to register window class (%d)\n", GetLastError()); + return 0; + } + } + + // Create the dummy input window + hwndDummy = CreateWindow(DUMMY_WINDOW_NAME, NULL, + WS_POPUP | WS_ICONIC, + 0, 0, 0, 0, NULL, NULL, hInst, NULL); + if (hwndDummy == NULL) { + throwIOException(env, "Failed to create window (%d)\n", GetLastError()); + return 0; + } + return (jlong)hwndDummy; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_DummyWindow_nDestroy(JNIEnv *env, jclass unused, jlong hwnd_address) { + HWND hwndDummy = (HWND)(INT_PTR)hwnd_address; + BOOL result = DestroyWindow(hwndDummy); + if (!result) { + throwIOException(env, "Failed to destroy window (%d)\n", GetLastError()); + } +} diff --git a/plugins/windows/src/native/raw/net_java_games_input_RawDevice.c b/plugins/windows/src/native/raw/net_java_games_input_RawDevice.c new file mode 100644 index 0000000..3730a6c --- /dev/null +++ b/plugins/windows/src/native/raw/net_java_games_input_RawDevice.c @@ -0,0 +1,69 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include "rawwinver.h" +#include <windows.h> +#include <jni.h> +#include "net_java_games_input_RawDevice.h" +#include "util.h" + +JNIEXPORT jstring JNICALL Java_net_java_games_input_RawDevice_nGetName(JNIEnv *env, jclass unused, jlong handle_addr) { + HANDLE handle = (HANDLE)(INT_PTR)handle_addr; + UINT res; + UINT name_length; + char *name; + jstring name_str; + + res = GetRawInputDeviceInfo(handle, RIDI_DEVICENAME, NULL, &name_length); + name = (char *)malloc(name_length*sizeof(char)); + res = GetRawInputDeviceInfo(handle, RIDI_DEVICENAME, name, &name_length); + if ((UINT)-1 == res) { + free(name); + throwIOException(env, "Failed to get device name (%d)\n", GetLastError()); + return NULL; + } + name_str = (*env)->NewStringUTF(env, name); + free(name); + return name_str; +} + +static jobject createKeyboardInfo(JNIEnv *env, jobject device_obj, RID_DEVICE_INFO_KEYBOARD *device_info) { + return newJObject(env, "net/java/games/input/RawKeyboardInfo", "(Lnet/java/games/input/RawDevice;IIIIII)V", device_obj, (jint)device_info->dwType, (jint)device_info->dwSubType, (jint)device_info->dwKeyboardMode, (jint)device_info->dwNumberOfFunctionKeys, (jint)device_info->dwNumberOfIndicators, (jint)device_info->dwNumberOfKeysTotal); +} + +static jobject createMouseInfo(JNIEnv *env, jobject device_obj, RID_DEVICE_INFO_MOUSE *device_info) { + return newJObject(env, "net/java/games/input/RawMouseInfo", "(Lnet/java/games/input/RawDevice;III)V", device_obj, (jint)device_info->dwId, (jint)device_info->dwNumberOfButtons, (jint)device_info->dwSampleRate); +} + +static jobject createHIDInfo(JNIEnv *env, jobject device_obj, RID_DEVICE_INFO_HID *device_info) { + return newJObject(env, "net/java/games/input/RawHIDInfo", "(Lnet/java/games/input/RawDevice;IIIII)V", device_obj, (jint)device_info->dwVendorId, (jint)device_info->dwProductId, (jint)device_info->dwVersionNumber, (jint)device_info->usUsagePage, (jint)device_info->usUsage); +} + +JNIEXPORT jobject JNICALL Java_net_java_games_input_RawDevice_nGetInfo(JNIEnv *env, jclass unused, jobject device_obj, jlong handle_addr) { + HANDLE handle = (HANDLE)(INT_PTR)handle_addr; + RID_DEVICE_INFO device_info; + UINT size = sizeof(RID_DEVICE_INFO); + UINT res; + + device_info.cbSize = sizeof(RID_DEVICE_INFO); + res = GetRawInputDeviceInfo(handle, RIDI_DEVICEINFO, &device_info, &size); + if ((UINT)-1 == res) { + throwIOException(env, "Failed to get device info (%d)\n", GetLastError()); + return NULL; + } + switch (device_info.dwType) { + case RIM_TYPEHID: + return createHIDInfo(env, device_obj,&(device_info.hid)); + case RIM_TYPEKEYBOARD: + return createKeyboardInfo(env, device_obj, &(device_info.keyboard)); + case RIM_TYPEMOUSE: + return createMouseInfo(env, device_obj, &(device_info.mouse)); + default: + throwIOException(env, "Unknown device type: %d\n", device_info.dwType); + return NULL; + } +} diff --git a/plugins/windows/src/native/raw/net_java_games_input_RawInputEnvironmentPlugin.c b/plugins/windows/src/native/raw/net_java_games_input_RawInputEnvironmentPlugin.c new file mode 100644 index 0000000..9814b7d --- /dev/null +++ b/plugins/windows/src/native/raw/net_java_games_input_RawInputEnvironmentPlugin.c @@ -0,0 +1,166 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include "rawwinver.h" +#include <windows.h> +#include <setupapi.h> +#include <devguid.h> +#include <regstr.h> +#include <jni.h> +#include "net_java_games_input_RawInputEnvironmentPlugin.h" +#include "util.h" +#include "winutil.h" + +JNIEXPORT jbyteArray JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_getKeyboardClassGUID(JNIEnv *env, jclass unused) { + return wrapGUID(env, &GUID_DEVCLASS_KEYBOARD); +} + +JNIEXPORT jbyteArray JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_getMouseClassGUID(JNIEnv *env, jclass unused) { + return wrapGUID(env, &GUID_DEVCLASS_MOUSE); +} + +JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_nEnumSetupAPIDevices(JNIEnv *env, jclass unused, jbyteArray guid_array, jobject device_list) { + jclass list_class; + jmethodID add_method; + HDEVINFO hDevInfo; + SP_DEVINFO_DATA DeviceInfoData; + int i; + GUID setup_class_guid; + jstring device_name; + jstring device_instance_id; + jobject setup_api_device; + + list_class = (*env)->GetObjectClass(env, device_list); + if (list_class == NULL) + return; + add_method = (*env)->GetMethodID(env, list_class, "add", "(Ljava/lang/Object;)Z"); + if (add_method == NULL) + return; + unwrapGUID(env, guid_array, &setup_class_guid); + if ((*env)->ExceptionOccurred(env)) + return; + + hDevInfo = SetupDiGetClassDevs(&setup_class_guid, + NULL, + NULL, + DIGCF_PRESENT); + + if (hDevInfo == INVALID_HANDLE_VALUE) { + throwIOException(env, "Failed to create device enumerator (%d)\n", GetLastError()); + return; + } + + + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { + DWORD DataT; + LPTSTR buffer = NULL; + DWORD buffersize = 0; + + + while (!SetupDiGetDeviceRegistryProperty( + hDevInfo, + &DeviceInfoData, + SPDRP_DEVICEDESC, + &DataT, + (PBYTE)buffer, + buffersize, + &buffersize)) { + if (buffer != NULL) + free(buffer); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + buffer = malloc(buffersize); + } else { + throwIOException(env, "Failed to get device description (%x)\n", GetLastError()); + SetupDiDestroyDeviceInfoList(hDevInfo); + return; + } + } + + device_name = (*env)->NewStringUTF(env, buffer); + if (device_name == NULL) { + free(buffer); + SetupDiDestroyDeviceInfoList(hDevInfo); + return; + } + + while (!SetupDiGetDeviceInstanceId( + hDevInfo, + &DeviceInfoData, + buffer, + buffersize, + &buffersize)) + { + if (buffer != NULL) + free(buffer); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + buffer = malloc(buffersize); + } else { + throwIOException(env, "Failed to get device instance id (%x)\n", GetLastError()); + SetupDiDestroyDeviceInfoList(hDevInfo); + return; + } + } + + device_instance_id = (*env)->NewStringUTF(env, buffer); + if (buffer != NULL) + free(buffer); + if (device_instance_id == NULL) { + SetupDiDestroyDeviceInfoList(hDevInfo); + return; + } + setup_api_device = newJObject(env, "net/java/games/input/SetupAPIDevice", "(Ljava/lang/String;Ljava/lang/String;)V", device_instance_id, device_name); + if (setup_api_device == NULL) { + SetupDiDestroyDeviceInfoList(hDevInfo); + return; + } + (*env)->CallBooleanMethod(env, device_list, add_method, setup_api_device); + if ((*env)->ExceptionOccurred(env)) { + SetupDiDestroyDeviceInfoList(hDevInfo); + return; + } + } + SetupDiDestroyDeviceInfoList(hDevInfo); +} + +JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_enumerateDevices(JNIEnv *env, jclass unused, jobject queue, jobject device_list) { + UINT num_devices; + UINT res; + RAWINPUTDEVICELIST *devices; + RAWINPUTDEVICELIST *device; + jobject device_object; + jclass list_class; + jmethodID add_method; + int i; + + list_class = (*env)->GetObjectClass(env, device_list); + if (list_class == NULL) + return; + add_method = (*env)->GetMethodID(env, list_class, "add", "(Ljava/lang/Object;)Z"); + if (add_method == NULL) + return; + + res = GetRawInputDeviceList(NULL, &num_devices, sizeof(RAWINPUTDEVICELIST)); + if ((UINT)-1 == res) { + throwIOException(env, "Failed to get number of devices (%d)\n", GetLastError()); + return; + } + devices = (RAWINPUTDEVICELIST *)malloc(num_devices*sizeof(RAWINPUTDEVICELIST)); + GetRawInputDeviceList(devices, &num_devices, sizeof(RAWINPUTDEVICELIST)); + for (i = 0; i < num_devices; i++) { + device = devices + i; + device_object = newJObject(env, "net/java/games/input/RawDevice", "(Lnet/java/games/input/RawInputEventQueue;JI)V", queue, (jlong)(INT_PTR)device->hDevice, (jint)device->dwType); + if (device_object == NULL) { + free(devices); + return; + } + (*env)->CallBooleanMethod(env, device_list, add_method, device_object); + (*env)->DeleteLocalRef(env, device_object); + } + free(devices); +} + diff --git a/plugins/windows/src/native/raw/net_java_games_input_RawInputEventQueue.c b/plugins/windows/src/native/raw/net_java_games_input_RawInputEventQueue.c new file mode 100644 index 0000000..130430f --- /dev/null +++ b/plugins/windows/src/native/raw/net_java_games_input_RawInputEventQueue.c @@ -0,0 +1,168 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include "rawwinver.h" +#include <windows.h> +#include <jni.h> +#include "net_java_games_input_RawInputEventQueue.h" +#include "util.h" + +static void handleMouseEvent(JNIEnv *env, jobject self, jmethodID add_method, LONG time, RAWINPUT *data) { + (*env)->CallVoidMethod(env, self, add_method, + (jlong)(INT_PTR)data->header.hDevice, + (jlong)time, + (jint)data->data.mouse.usFlags, + (jint)data->data.mouse.usButtonFlags, + /* + * The Raw Input spec says that the usButtonData + * is a signed value, if RI_MOUSE_WHEEL + * is set in usFlags. However, usButtonData + * is an unsigned value, for unknown reasons, + * and since its only known use is the wheel + * delta, we'll convert it to a signed value here + */ + (jint)(SHORT)data->data.mouse.usButtonData, + (jlong)data->data.mouse.ulRawButtons, + (jlong)data->data.mouse.lLastX, + (jlong)data->data.mouse.lLastY, + (jlong)data->data.mouse.ulExtraInformation + ); +} + +static void handleKeyboardEvent(JNIEnv *env, jobject self, jmethodID add_method, LONG time, RAWINPUT *data) { + (*env)->CallVoidMethod(env, self, add_method, + (jlong)(INT_PTR)data->header.hDevice, + (jlong)time, + (jint)data->data.keyboard.MakeCode, + (jint)data->data.keyboard.Flags, + (jint)data->data.keyboard.VKey, + (jint)data->data.keyboard.Message, + (jlong)data->data.keyboard.ExtraInformation + ); +} + +JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEventQueue_nRegisterDevices(JNIEnv *env, jclass unused, jint flags, jlong hwnd_addr, jobjectArray device_infos) { + BOOL res; + jclass device_info_class; + jmethodID getUsage_method; + jmethodID getUsagePage_method; + RAWINPUTDEVICE *devices; + RAWINPUTDEVICE *device; + jsize num_devices = (*env)->GetArrayLength(env, device_infos); + USHORT usage; + USHORT usage_page; + int i; + HWND hwnd = (HWND)(INT_PTR)hwnd_addr; + + device_info_class = (*env)->FindClass(env, "net/java/games/input/RawDeviceInfo"); + if (device_info_class == NULL) + return; + getUsage_method = (*env)->GetMethodID(env, device_info_class, "getUsage", "()I"); + if (getUsage_method == NULL) + return; + getUsagePage_method = (*env)->GetMethodID(env, device_info_class, "getUsagePage", "()I"); + if (getUsagePage_method == NULL) + return; + devices = (RAWINPUTDEVICE *)malloc(num_devices*sizeof(RAWINPUTDEVICE)); + if (devices == NULL) { + throwIOException(env, "Failed to allocate device structs\n"); + return; + } + for (i = 0; i < num_devices; i++) { + jobject device_obj = (*env)->GetObjectArrayElement(env, device_infos, i); + if (device_obj == NULL) { + free(devices); + return; + } + usage = (*env)->CallIntMethod(env, device_obj, getUsage_method); + if ((*env)->ExceptionOccurred(env)) { + free(devices); + return; + } + usage_page = (*env)->CallIntMethod(env, device_obj, getUsagePage_method); + if ((*env)->ExceptionOccurred(env)) { + free(devices); + return; + } + device = devices + i; + device->usUsagePage = usage_page; + device->usUsage = usage; + device->dwFlags = flags; + device->hwndTarget = hwnd; + } + res = RegisterRawInputDevices(devices, num_devices, sizeof(RAWINPUTDEVICE)); + free(devices); + if (!res) + throwIOException(env, "Failed to register raw devices (%d)\n", GetLastError()); + +/* + + + + res = GetRegisteredRawInputDevices(NULL, &num_devices, sizeof(RAWINPUTDEVICE)); + devices = (RAWINPUTDEVICE *)malloc(num_devices*sizeof(RAWINPUTDEVICE)); + res = GetRegisteredRawInputDevices(devices, &num_devices, sizeof(RAWINPUTDEVICE)); + if (res == -1) { + throwIOException(env, "Failed to get registered raw devices (%d)\n", GetLastError()); + return; + } + for (i = 0; i < num_devices; i++) { +printfJava(env, "from windows: registered: %d %d %p (of %d)\n", devices[i].usUsagePage, devices[i].usUsage, devices[i].hwndTarget, num_devices); + } + free(devices);*/ +} + +JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEventQueue_nPoll(JNIEnv *env, jobject self, jlong hwnd_handle) { + MSG msg; + HWND hwnd = (HWND)(INT_PTR)hwnd_handle; + jmethodID addMouseEvent_method; + jmethodID addKeyboardEvent_method; + UINT input_size; + RAWINPUT *input_data; + LONG time; + jclass self_class = (*env)->GetObjectClass(env, self); + + if (self_class == NULL) + return; + addMouseEvent_method = (*env)->GetMethodID(env, self_class, "addMouseEvent", "(JJIIIJJJJ)V"); + if (addMouseEvent_method == NULL) + return; + addKeyboardEvent_method = (*env)->GetMethodID(env, self_class, "addKeyboardEvent", "(JJIIIIJ)V"); + if (addKeyboardEvent_method == NULL) + return; + if (GetMessage(&msg, hwnd, 0, 0) != 0) { + if (msg.message != WM_INPUT) + return; // ignore it + time = GetMessageTime(); + if (GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, NULL, &input_size, sizeof(RAWINPUTHEADER)) == (UINT)-1) { + throwIOException(env, "Failed to get raw input data size (%d)\n", GetLastError()); + return; + } + input_data = (RAWINPUT *)malloc(input_size); + if (input_data == NULL) { + throwIOException(env, "Failed to allocate input data buffer\n"); + return; + } + if (GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, input_data, &input_size, sizeof(RAWINPUTHEADER)) == (UINT)-1) { + free(input_data); + throwIOException(env, "Failed to get raw input data (%d)\n", GetLastError()); + return; + } + switch (input_data->header.dwType) { + case RIM_TYPEMOUSE: + handleMouseEvent(env, self, addMouseEvent_method, time, input_data); + break; + case RIM_TYPEKEYBOARD: + handleKeyboardEvent(env, self, addKeyboardEvent_method, time, input_data); + break; + default: + /* ignore other types of message */ + break; + } + free(input_data); + } +} diff --git a/plugins/windows/src/native/raw/rawwinver.h b/plugins/windows/src/native/raw/rawwinver.h new file mode 100644 index 0000000..882341a --- /dev/null +++ b/plugins/windows/src/native/raw/rawwinver.h @@ -0,0 +1,14 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef RAWWINVER_H +#define RAWWINVER_H + +#define _WIN32_WINNT 0x0501 +#define WINVER 0x0501 + +#endif diff --git a/plugins/windows/src/native/winutil.c b/plugins/windows/src/native/winutil.c new file mode 100644 index 0000000..93606dd --- /dev/null +++ b/plugins/windows/src/native/winutil.c @@ -0,0 +1,21 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include "winutil.h" + +jbyteArray wrapGUID(JNIEnv *env, const GUID *guid) { + jbyteArray guid_array = (*env)->NewByteArray(env, sizeof(GUID)); + if (guid_array == NULL) + return NULL; + (*env)->SetByteArrayRegion(env, guid_array, 0, sizeof(GUID), (jbyte *)guid); + return guid_array; +} + +void unwrapGUID(JNIEnv *env, const jobjectArray byte_array, GUID *guid) { + (*env)->GetByteArrayRegion(env, byte_array, 0, sizeof(GUID), (jbyte *)guid); +} + diff --git a/plugins/windows/src/native/winutil.h b/plugins/windows/src/native/winutil.h new file mode 100644 index 0000000..169280e --- /dev/null +++ b/plugins/windows/src/native/winutil.h @@ -0,0 +1,17 @@ +/* + * %W% %E% + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _WINUTIL_H +#define _WINUTIL_H + +#include <windows.h> +#include <jni.h> + +extern jbyteArray wrapGUID(JNIEnv *env, const GUID *guid); +extern void unwrapGUID(JNIEnv *env, const jobjectArray byte_array, GUID *guid); + +#endif |