Refactor the sources

This commit is contained in:
Endolf 2018-05-09 20:38:48 +01:00
parent c71f96a708
commit 682ebbaf69
46 changed files with 5 additions and 12 deletions

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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;
/**
* @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);
DIComponent component = device.mapObject(object);
if (component == null)
return false;
int event_value;
if (object.isRelative()) {
event_value = object.getRelativeEventValue(di_event.getData());
} else {
event_value = di_event.getData();
}
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);
}
}

View file

@ -0,0 +1,211 @@
/*
* %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) {
if (device.areAxesRelative())
return 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) {
if (device.areAxesRelative())
return 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;
}
public 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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,546 @@
/*
* %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._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;
}
}
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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,94 @@
/**
* Copyright (C) 2007 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* 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.util.ArrayList;
import java.util.List;
/**
* Combines the list of seperate keyboards and mice found with the raw plugin,
* with the game controllers found with direct input.
*
* @author Jeremy
*/
public class DirectAndRawInputEnvironmentPlugin extends ControllerEnvironment {
private RawInputEnvironmentPlugin rawPlugin;
private DirectInputEnvironmentPlugin dinputPlugin;
private Controller[] controllers = null;
public DirectAndRawInputEnvironmentPlugin() {
// These two *must* be loaded in this order for raw devices to work.
dinputPlugin = new DirectInputEnvironmentPlugin();
rawPlugin = new RawInputEnvironmentPlugin();
}
/**
* @see net.java.games.input.ControllerEnvironment#getControllers()
*/
public Controller[] getControllers() {
if(controllers == null) {
boolean rawKeyboardFound = false;
boolean rawMouseFound = false;
List tempControllers = new ArrayList();
Controller[] dinputControllers = dinputPlugin.getControllers();
Controller[] rawControllers = rawPlugin.getControllers();
for(int i=0;i<rawControllers.length;i++) {
tempControllers.add(rawControllers[i]);
if(rawControllers[i].getType()==Controller.Type.KEYBOARD) {
rawKeyboardFound = true;
} else if(rawControllers[i].getType()==Controller.Type.MOUSE) {
rawMouseFound = true;
}
}
for(int i=0;i<dinputControllers.length;i++) {
if(dinputControllers[i].getType()==Controller.Type.KEYBOARD) {
if(!rawKeyboardFound) {
tempControllers.add(dinputControllers[i]);
}
} else if(dinputControllers[i].getType()==Controller.Type.MOUSE) {
if(!rawMouseFound) {
tempControllers.add(dinputControllers[i]);
}
} else {
tempControllers.add(dinputControllers[i]);
}
}
controllers = (Controller[]) tempControllers.toArray(new Controller[]{});
}
return controllers;
}
/**
* @see net.java.games.input.ControllerEnvironment#isSupported()
*/
public boolean isSupported() {
return rawPlugin.isSupported() || dinputPlugin.isSupported();
}
}

View file

@ -0,0 +1,254 @@
/*
* %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.File;
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 {
private static boolean supported = false;
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
try {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
supported = false;
}
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static {
String osName = getPrivilegedProperty("os.name", "").trim();
if(osName.startsWith("Windows")) {
supported = true;
if("x86".equals(getPrivilegedProperty("os.arch"))) {
loadLibrary("jinput-dx8");
} else {
loadLibrary("jinput-dx8_64");
}
}
}
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[]{};
if(isSupported()) {
try {
window = new DummyWindow();
try {
controllers = enumControllers(window);
} catch (IOException e) {
window.destroy();
throw e;
}
} catch (IOException e) {
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;
}
});
} else {
// These are final fields, so can't set them, then over ride
// them if we are supported.
this.window = null;
this.controllers = controllers;
}
}
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 (identifier == null)
continue;
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.getPrimaryButton() != 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_1STPERSON:
/* Fall through */
case IDirectInputDevice.DI8DEVTYPE_FLIGHT:
/* Fall through */
case IDirectInputDevice.DI8DEVTYPE_JOYSTICK:
return createControllerFromDevice(device, Controller.Type.STICK);
default:
return createControllerFromDevice(device, Controller.Type.UNKNOWN);
}
}
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.
*/
}
}
public boolean isSupported() {
return supported;
}
} // class DirectInputEnvironment

View file

@ -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;
}
}

View file

@ -0,0 +1,100 @@
/*
* %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 {
try {
IDirectInputDevice device = new IDirectInputDevice(window, address, instance_guid, product_guid, dev_type, dev_subtype, instance_name, product_name);
devices.add(device);
} catch (IOException e) {
DirectInputEnvironmentPlugin.logln("Failed to initialize device " + product_name + " because of: " + e);
}
}
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);
}

View file

@ -0,0 +1,546 @@
/*
* %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_POLLEDDEVICE = 0x00000002;
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 final boolean axes_in_relative_mode;
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) {
DirectInputEnvironmentPlugin.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.
*
* Unless, of course, all axes are relative like a mouse device,
* in which case setting the DIDF_ABSAXIS flag will result in
* incorrect axis values returned from GetDeviceData for some
* obscure reason.
*/
boolean all_relative = true;
boolean has_axis = false;
for (int i = 0; i < objects.size(); i++) {
DIDeviceObject obj = (DIDeviceObject)objects.get(i);
if (obj.isAxis()) {
has_axis = true;
if (!obj.isRelative()) {
all_relative = false;
break;
}
}
}
this.axes_in_relative_mode = all_relative && has_axis;
int axis_mode = all_relative ? DIDF_RELAXIS : DIDF_ABSAXIS;
setDataFormat(axis_mode);
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 boolean areAxesRelative() {
return axes_in_relative_mode;
}
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 Component.Identifier.Axis.UNKNOWN;
}
}
public final synchronized void setBufferSize(int size) throws IOException {
checkReleased();
unacquire();
int res = nSetBufferSize(address, size);
if (res != DI_OK && res != DI_PROPNOEFFECT && res != DI_POLLEDDEVICE)
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();
}
}

View file

@ -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) {
DirectInputEnvironmentPlugin.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();
}
}

View file

@ -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;
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}

View file

@ -0,0 +1,216 @@
/*
* %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.File;
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 {
private static boolean supported = false;
/**
* Static utility method for loading native libraries.
* It will try to load from either the path given by
* the net.java.games.input.librarypath property
* or through System.loadLibrary().
*
*/
static void loadLibrary(final String lib_name) {
AccessController.doPrivileged(
new PrivilegedAction() {
public final Object run() {
try {
String lib_path = System.getProperty("net.java.games.input.librarypath");
if (lib_path != null)
System.load(lib_path + File.separator + System.mapLibraryName(lib_name));
else
System.loadLibrary(lib_name);
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
supported = false;
}
return null;
}
});
}
static String getPrivilegedProperty(final String property) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property);
}
});
}
static String getPrivilegedProperty(final String property, final String default_value) {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(property, default_value);
}
});
}
static {
String osName = getPrivilegedProperty("os.name", "").trim();
if(osName.startsWith("Windows")) {
supported = true;
if("x86".equals(getPrivilegedProperty("os.arch"))) {
loadLibrary("jinput-raw");
} else {
loadLibrary("jinput-raw_64");
}
}
}
private final Controller[] controllers;
/** Creates new DirectInputEnvironment */
public RawInputEnvironmentPlugin() {
RawInputEventQueue queue;
Controller[] controllers = new Controller[]{};
if(isSupported()) {
try {
queue = new RawInputEventQueue();
controllers = enumControllers(queue);
} catch (IOException e) {
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;
}
public boolean isSupported() {
return supported;
}
/*
* 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

View file

@ -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;
}
}
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}

View file

@ -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[]{});
}
}

View file

@ -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, getPrimaryButton(), 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, getSecondaryButton(), 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, getTertiaryButton(), 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, getButton3(), 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, getButton4(), 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;
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1 @@
/net_java_games_input_DummyWindow.h

View file

@ -0,0 +1,103 @@
<?xml version="1.0"?>
<project name="JInput dx8 port, Native code" basedir="." default="compile">
<property environment="env"/>
<property name="dxhome" location="${env.DXSDK_DIR}"/>
<property name="sdkhome" location="${env.WindowsSdkDir}"/>
<target name="init">
<mkdir dir="target/natives"/>
</target>
<target name="compile_dir">
<echo message="${compiledir}"/>
<echo message="sdkhome: ${sdkhome}"/>
<echo message="dxhome: ${dxhome}"/>
<echo message="target arch: ${os.arch}"/>
<apply dir="${compiledir}" failonerror="true" executable="cl" dest="${compiledir}" skipemptyfilesets="true">
<arg line="/Ox /W2 /nologo /c"/>
<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:${dxhomelib}"/>
<arg value="/LIBPATH:${sdkhomelib}"/>
<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"/>
<fileset dir="." includes="*.exp"/>
<fileset dir="." includes="*.lib"/>
<fileset dir="../../../common/src/native" includes="*.obj"/>
</delete>
</target>
<target name="compile">
<property name="rawlibs" value="Kernel32.lib User32.lib Setupapi.lib"/>
<property name="dx8libs" value="Kernel32.lib dinput8.lib dxguid.lib User32.lib"/>
<property name="commonhome" location="../../../common"/>
<condition property="dx8dllname" value="jinput-dx8.dll" else="jinput-dx8_64.dll">
<equals arg1="${os.arch}" arg2="x86"/>
</condition>
<condition property="rawdllname" value="jinput-raw.dll" else="jinput-raw_64.dll">
<equals arg1="${os.arch}" arg2="x86"/>
</condition>
<condition property="dxhomelib" value="${dxhome}\lib\x86" else="${dxhome}\lib\x64">
<equals arg1="${os.arch}" arg2="x86"/>
</condition>
<condition property="sdkhomelib" value="${sdkhome}\lib" else="${sdkhome}\lib\x64">
<equals arg1="${os.arch}" arg2="x86"/>
</condition>
<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>

View file

@ -0,0 +1,3 @@
/net_java_games_input_IDirectInput.h
/net_java_games_input_IDirectInputDevice.h
/net_java_games_input_IDirectInputEffect.h

View file

@ -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

View file

@ -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);
}

View file

@ -0,0 +1,502 @@
/*
* %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 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;
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 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));
if (data == NULL)
return -1;
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;
}

View file

@ -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(&params, sizeof(params));
params.dwSize = sizeof(params);
params.dwGain = gain;
return IDirectInputEffect_SetParameters(ppdeff, &params, 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);
}

View file

@ -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)(intptr_t)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());
}
}

View file

@ -0,0 +1,4 @@
/net_java_games_input_RawDevice.h
/net_java_games_input_RawInputEnvironmentPlugin.h
/net_java_games_input_RawInputEventQueue_QueueThread.h
/net_java_games_input_RawInputEventQueue.h

View file

@ -0,0 +1,70 @@
/*
* %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 <winuser.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;
}
}

View file

@ -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);
}

View file

@ -0,0 +1,171 @@
/*
* %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;
/* res = GetRegisteredRawInputDevices(NULL, &num_devices, sizeof(RAWINPUTDEVICE));
if (num_devices > 0) {
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);
}*/
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());
}
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) {
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
return; // ignore it
}
time = msg.time;
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());
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
return;
}
input_data = (RAWINPUT *)malloc(input_size);
if (input_data == NULL) {
throwIOException(env, "Failed to allocate input data buffer\n");
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
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());
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
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);
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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