diff options
author | endolf <[email protected]> | 2006-04-29 22:29:27 +0000 |
---|---|---|
committer | endolf <[email protected]> | 2006-04-29 22:29:27 +0000 |
commit | 986c6106aa165d4168f6b8e1216eceb5353fce14 (patch) | |
tree | 1a61954c62909e8e4a4b4c578665a4df40d013cf /plugins | |
parent | 09bdd72a93f2a5498137d22540d035df87cff174 (diff) |
Make version 2 the main jinput version
git-svn-id: file:///home/sven/projects/JOGL/git-svn/svn-server-sync/jinput/trunk@139 e343933a-64c8-49c5-92b1-88f2ce3e89e8
Diffstat (limited to 'plugins')
133 files changed, 12543 insertions, 9833 deletions
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/native/MixedDevice.h b/plugins/linux/src/java/net/java/games/input/LinuxDeviceTask.java index 3239ed4..3dbdeda 100644 --- a/plugins/linux/src/native/MixedDevice.h +++ b/plugins/linux/src/java/net/java/games/input/LinuxDeviceTask.java @@ -23,48 +23,40 @@ * 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 MixedDevice_h -#define MixedDevice_h +import java.io.IOException; -#include <stdint.h> -#include <linux/input.h> -#include "eventInterfaceTypes.h" -#include "Device.h" -#include "EventDevice.h" -#include "JoystickDevice.h" -#include "MixedDevice.h" +abstract class LinuxDeviceTask { + public final static int INPROGRESS = 1; + public final static int COMPLETED = 2; + public final static int FAILED = 3; + + private Object result; + private IOException exception; + private int state = INPROGRESS; + + public final void doExecute() { + try { + result = execute(); + state = COMPLETED; + } catch (IOException e) { + exception = e; + state = FAILED; + } + } -class MixedDevice : public Device { + public final IOException getException() { + return exception; + } - private: - JoystickDevice *joystickDevice; - EventDevice *eventDevice; + public final Object getResult() { + return result; + } - 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 + public final int getState() { + return state; + } + + protected abstract Object execute() throws IOException; +} diff --git a/plugins/linux/src/java/net/java/games/input/LinuxDeviceThread.java b/plugins/linux/src/java/net/java/games/input/LinuxDeviceThread.java new file mode 100644 index 0000000..62d1849 --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxDeviceThread.java @@ -0,0 +1,91 @@ +/** + * 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.List; +import java.util.ArrayList; + +/** + * Linux doesn't have proper support for force feedback + * from different threads since it relies on PIDs + * to determine ownership of a particular effect slot. + * Therefore we have to hack around this by + * making sure everything related to FF + * (including the final device close that performs + * and implicit deletion of all the process' effects) + * is run on a single thread. + */ +final class LinuxDeviceThread extends Thread { + private final List tasks = new ArrayList(); + + public LinuxDeviceThread() { + setDaemon(true); + start(); + } + + public synchronized final void run() { + while (true) { + if (!tasks.isEmpty()) { + LinuxDeviceTask task = (LinuxDeviceTask)tasks.remove(0); + task.doExecute(); + synchronized (task) { + task.notify(); + } + } else { + try { + wait(); + } catch (InterruptedException e) { + // ignore + } + } + } + } + + public final Object execute(LinuxDeviceTask task) throws IOException { + synchronized (this) { + tasks.add(task); + notify(); + } + synchronized (task) { + while (task.getState() == LinuxDeviceTask.INPROGRESS) { + try { + task.wait(); + } catch (InterruptedException e) { + // ignore + } + } + } + switch (task.getState()) { + case LinuxDeviceTask.COMPLETED: + return task.getResult(); + case LinuxDeviceTask.FAILED: + throw task.getException(); + default: + throw new RuntimeException("Invalid task state: " + task.getState()); + } + } +} 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..d6afb96 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,47 @@ 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(); + private final static LinuxDeviceThread device_thread = new LinuxDeviceThread(); - /** 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 final static Object execute(LinuxDeviceTask task) throws IOException { + return device_thread.execute(task); + } + 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 +74,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..bcd941a --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxEventDevice.java @@ -0,0 +1,393 @@ +/** + * 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 synchronized final void close() throws IOException { + if (closed) + return; + closed = true; + LinuxEnvironmentPlugin.execute(new LinuxDeviceTask() { + protected final Object execute() throws IOException { + nClose(fd); + return null; + } + }); + } + 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/java/net/java/games/input/LinuxForceFeedbackEffect.java b/plugins/linux/src/java/net/java/games/input/LinuxForceFeedbackEffect.java new file mode 100644 index 0000000..528cbff --- /dev/null +++ b/plugins/linux/src/java/net/java/games/input/LinuxForceFeedbackEffect.java @@ -0,0 +1,110 @@ +/** + * 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 + */ +abstract class LinuxForceFeedbackEffect implements Rumbler { + private final LinuxEventDevice device; + private final int ff_id; + private final WriteTask write_task = new WriteTask(); + private final UploadTask upload_task = new UploadTask(); + + public LinuxForceFeedbackEffect(LinuxEventDevice device) throws IOException { + this.device = device; + this.ff_id = upload_task.doUpload(-1, 0); + } + + protected abstract int upload(int id, float intensity) throws IOException; + + protected final LinuxEventDevice getDevice() { + return device; + } + + public synchronized final void rumble(float intensity) { + try { + if (intensity > 0) { + upload_task.doUpload(ff_id, intensity); + write_task.write(1); + } else { + write_task.write(0); + } + } catch (IOException e) { + ControllerEnvironment.logln("Failed to rumble: " + e); + } + } + + /* + * Erase doesn't seem to be implemented on Logitech joysticks, + * so we'll rely on the kernel cleaning up on device close + */ +/* + public final void erase() throws IOException { + device.eraseEffect(ff_id); + } +*/ + public final String getAxisName() { + return null; + } + + public final Component.Identifier getAxisIdentifier() { + return null; + } + + private final class UploadTask extends LinuxDeviceTask { + private int id; + private float intensity; + + public final int doUpload(int id, float intensity) throws IOException { + this.id = id; + this.intensity = intensity; + LinuxEnvironmentPlugin.execute(this); + return this.id; + } + + protected final Object execute() throws IOException { + this.id = upload(id, intensity); + return null; + } + } + + private final class WriteTask extends LinuxDeviceTask { + private int value; + + public final void write(int value) throws IOException { + this.value = value; + LinuxEnvironmentPlugin.execute(this); + } + + protected final Object execute() throws IOException { + device.writeEvent(NativeDefinitions.EV_FF, ff_id, value); + 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/awt/src/net/java/games/input/AWTAxis.java b/plugins/linux/src/java/net/java/games/input/LinuxRumbleFF.java index daa2e12..578793a 100644 --- a/plugins/awt/src/net/java/games/input/AWTAxis.java +++ b/plugins/linux/src/java/net/java/games/input/LinuxRumbleFF.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,30 @@ */ 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); +final class LinuxRumbleFF extends LinuxForceFeedbackEffect { + public LinuxRumbleFF(LinuxEventDevice device) throws IOException { + super(device); } - /** - * 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 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); + } - /* (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; - } - - void setValue(float value) { - this.value = value; - } + return getDevice().uploadRumbleEffect(id, 0, 0, 0, -1, 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/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..a7fa563 --- /dev/null +++ b/plugins/windows/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java @@ -0,0 +1,190 @@ +/* + * %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_GAMEPAD: + return createControllerFromDevice(device, Controller.Type.GAMEPAD); + case IDirectInputDevice.DI8DEVTYPE_DRIVING: + return createControllerFromDevice(device, Controller.Type.WHEEL); + case IDirectInputDevice.DI8DEVTYPE_FLIGHT: + /* Fall through */ + case IDirectInputDevice.DI8DEVTYPE_JOYSTICK: + /* Fall through */ + default: + return createControllerFromDevice(device, Controller.Type.STICK); + } + } + + 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..2e3e22f --- /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, DI_FFNOMINALMAX, 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 |