diff --git a/src/core/net/java/games/input/ControllerEnvironment.java b/src/core/net/java/games/input/ControllerEnvironment.java index 6aa9ad8..90533d8 100644 --- a/src/core/net/java/games/input/ControllerEnvironment.java +++ b/src/core/net/java/games/input/ControllerEnvironment.java @@ -37,13 +37,8 @@ * *****************************************************************************/ package net.java.games.input; - -import java.io.File; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -71,6 +66,9 @@ import java.util.logging.Logger; * */ public abstract class ControllerEnvironment { + static void logln(String msg) { + log(msg + "\n"); + } static void log(String msg) { Logger.getLogger(ControllerEnvironment.class.getName()).info(msg); @@ -85,17 +83,12 @@ public abstract class ControllerEnvironment { /** * List of controller listeners */ - protected final ArrayList controllerListeners = new ArrayList<>(); + protected final ArrayList controllerListeners = new ArrayList(); /** * Protected constructor for subclassing. */ protected ControllerEnvironment() { - if(System.getProperty("jinput.loglevel") != null) { - String loggerName = ControllerEnvironment.class.getPackage().getName(); - Level level = Level.parse(System.getProperty("jinput.loglevel")); - Logger.getLogger(loggerName).setLevel(level); - } } /** @@ -103,6 +96,11 @@ public abstract class ControllerEnvironment { * or an empty array if there are no controllers in this environment. */ public abstract Controller[] getControllers(); + /** + * Rescans the devices and provides a list of new controllers. + * @return a list of all controllers available to this environment. + */ + public abstract Controller[] rescanControllers(); /** * Adds a listener for controller state change events. @@ -133,9 +131,9 @@ public abstract class ControllerEnvironment { */ protected void fireControllerAdded(Controller c) { ControllerEvent ev = new ControllerEvent(c); - Iterator it = controllerListeners.iterator(); + Iterator it = controllerListeners.iterator(); while (it.hasNext()) { - it.next().controllerAdded(ev); + ((ControllerListener)it.next()).controllerAdded(ev); } } @@ -145,9 +143,9 @@ public abstract class ControllerEnvironment { */ protected void fireControllerRemoved(Controller c) { ControllerEvent ev = new ControllerEvent(c); - Iterator it = controllerListeners.iterator(); + Iterator it = controllerListeners.iterator(); while (it.hasNext()) { - it.next().controllerRemoved(ev); + ((ControllerListener)it.next()).controllerRemoved(ev); } } @@ -158,4 +156,4 @@ public abstract class ControllerEnvironment { public static ControllerEnvironment getDefaultEnvironment() { return defaultEnvironment; } -} \ No newline at end of file +} // ControllerEnvironment \ No newline at end of file diff --git a/src/core/net/java/games/input/DefaultControllerEnvironment.java b/src/core/net/java/games/input/DefaultControllerEnvironment.java index 1cb0b54..29645a1 100644 --- a/src/core/net/java/games/input/DefaultControllerEnvironment.java +++ b/src/core/net/java/games/input/DefaultControllerEnvironment.java @@ -1,4 +1,10 @@ /* + * %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: @@ -29,20 +35,24 @@ * You acknowledge that this software is not designed or intended for us in * the design, construction, operation or maintenance of any nuclear facility * - */ + *****************************************************************************/ package net.java.games.input; -import net.java.games.util.plugins.Plugins; - import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.Properties; import java.util.StringTokenizer; import java.util.logging.Logger; +import net.java.games.util.plugins.*; + /** * The default controller environment. * @@ -62,23 +72,34 @@ class DefaultControllerEnvironment extends ControllerEnvironment { * */ static void loadLibrary(final String lib_name) { - AccessController.doPrivileged((PrivilegedAction) () -> { + AccessController.doPrivileged( + new PrivilegedAction() { + public final Object run() { String lib_path = System.getProperty("net.java.games.input.librarypath"); if (lib_path != null) System.load(lib_path + File.separator + System.mapLibraryName(lib_name)); else System.loadLibrary(lib_name); return null; + } }); } static String getPrivilegedProperty(final String property) { - return AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty(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 AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty(property, default_value)); + return (String)AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(property, default_value); + } + }); } /** @@ -86,7 +107,8 @@ class DefaultControllerEnvironment extends ControllerEnvironment { */ private ArrayList controllers; - private Collection loadedPluginNames = new ArrayList<>(); + private Collection loadedPlugins = new ArrayList(); + private ArrayList environments = new ArrayList(); /** * Public no-arg constructor. @@ -98,67 +120,129 @@ class DefaultControllerEnvironment extends ControllerEnvironment { * Returns a list of all controllers available to this environment, * or an empty array if there are no controllers in this environment. */ - public Controller[] getControllers() - { - reloadControllers(); + public Controller[] getControllers() { + if (controllers == null) { + // Controller list has not been scanned. + controllers = new ArrayList(); + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + scanControllers(); + return null; + } + }); + //Check the properties for specified controller classes + String pluginClasses = getPrivilegedProperty("jinput.plugins", "") + " " + getPrivilegedProperty("net.java.games.input.plugins", ""); + if(!getPrivilegedProperty("jinput.useDefaultPlugin", "true").toLowerCase().trim().equals("false") && !getPrivilegedProperty("net.java.games.input.useDefaultPlugin", "true").toLowerCase().trim().equals("false")) { + String osName = getPrivilegedProperty("os.name", "").trim(); + if(osName.equals("Linux")) { + pluginClasses = pluginClasses + " net.java.games.input.LinuxEnvironmentPlugin"; + } else if(osName.equals("Mac OS X")) { + pluginClasses = pluginClasses + " net.java.games.input.OSXEnvironmentPlugin"; + } else if(osName.equals("Windows XP") || osName.equals("Windows Vista") || osName.equals("Windows 7")) { + pluginClasses = pluginClasses + " net.java.games.input.DirectAndRawInputEnvironmentPlugin"; + } else if(osName.equals("Windows 98") || osName.equals("Windows 2000")) { + pluginClasses = pluginClasses + " net.java.games.input.DirectInputEnvironmentPlugin"; + } else if (osName.startsWith("Windows")) { + log.warning("Found unknown Windows version: " + osName); + log.warning("Attempting to use default windows plug-in."); + pluginClasses = pluginClasses + " net.java.games.input.DirectAndRawInputEnvironmentPlugin"; + } else { + log.warning("Trying to use default plugin, OS name " + osName +" not recognised"); + } + } + + StringTokenizer pluginClassTok = new StringTokenizer(pluginClasses, " \t\n\r\f,;:"); + while(pluginClassTok.hasMoreTokens()) { + String className = pluginClassTok.nextToken(); + try { + if(!loadedPlugins.contains(className)) { + log.fine("Loading: " + className); + Class ceClass = Class.forName(className); + ControllerEnvironment ce = (ControllerEnvironment) ceClass.newInstance(); + if(ce.isSupported()) { + environments.add(ce); + addControllers(ce.getControllers()); + loadedPlugins.add(ce.getClass().getName()); + } else { + logln(ceClass.getName() + " is not supported"); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + if(!environments.isEmpty()){ + Controller[] newScanControllers = environments.get(0).getControllers(); + Controller[] ret = new Controller[newScanControllers.length]; + for(int i = 0; i < newScanControllers.length; i++){ + ret[i] = newScanControllers[i]; + } + return ret; + } + Controller[] ret = new Controller[controllers.size()]; Iterator it = controllers.iterator(); int i = 0; - while (it.hasNext()) - { - ret[i] = it.next(); + while (it.hasNext()) { + ret[i] = (Controller)it.next(); i++; } return ret; } - - private void reloadControllers() - { - controllers = new ArrayList<>(); - AccessController.doPrivileged((PrivilegedAction) () -> scanControllers()); - //Check the properties for specified controller classes - String pluginClasses = getPrivilegedProperty("jinput.plugins", "") + " " + getPrivilegedProperty("net.java.games.input.plugins", ""); - if(!getPrivilegedProperty("jinput.useDefaultPlugin", "true").toLowerCase().trim().equals("false") && !getPrivilegedProperty("net.java.games.input.useDefaultPlugin", "true").toLowerCase().trim().equals("false")) { - String osName = getPrivilegedProperty("os.name", "").trim(); - if(osName.equals("Linux")) { - pluginClasses = pluginClasses + " net.java.games.input.LinuxEnvironmentPlugin"; - } else if(osName.equals("Mac OS X")) { - pluginClasses = pluginClasses + " net.java.games.input.OSXEnvironmentPlugin"; - } else if(osName.equals("Windows XP") || osName.equals("Windows Vista") || osName.equals("Windows 7") || osName.equals("Windows 8") || osName.equals("Windows 8.1") || osName.equals("Windows 10")) { - pluginClasses = pluginClasses + " net.java.games.input.DirectAndRawInputEnvironmentPlugin"; - } else if(osName.equals("Windows 98") || osName.equals("Windows 2000")) { - pluginClasses = pluginClasses + " net.java.games.input.DirectInputEnvironmentPlugin"; - } else if (osName.startsWith("Windows")) { - log.warning("Found unknown Windows version: " + osName); - log.warning("Attempting to use default windows plug-in."); - pluginClasses = pluginClasses + " net.java.games.input.DirectAndRawInputEnvironmentPlugin"; - } else { - log.warning("Trying to use default plugin, OS name " + osName +" not recognised"); - } - } - - StringTokenizer pluginClassTok = new StringTokenizer(pluginClasses, " \t\n\r\f,;:"); - while(pluginClassTok.hasMoreTokens()) { - String className = pluginClassTok.nextToken(); - try { - log.fine("Loading: " + className); - Class ceClass = Class.forName(className); - ControllerEnvironment ce = (ControllerEnvironment) ceClass.getDeclaredConstructor().newInstance(); - if(ce.isSupported()) { - addControllers(ce.getControllers()); - loadedPluginNames.add(ce.getClass().getName()); - } else { - log(ceClass.getName() + " is not supported"); - } - } catch (Throwable e) { - e.printStackTrace(); + /** + * Returns a list of all controllers available to this environment, + * or an empty array if there are no controllers in this environment. + */ + public Controller[] rescanControllers() { + if(!environments.isEmpty()){ + Controller[] newScanControllers = environments.get(0).rescanControllers(); + // need to add controllers that were connected + for(int i = 0; i < newScanControllers.length; i++){ + boolean controllerExist = false; + for(Controller controller:controllers){ + if(newScanControllers[i] == controller){ + controllerExist = true; + break; + } + } + if(!controllerExist){ + controllers.add(newScanControllers[i]); + } + } + ArrayList removeControllers = new ArrayList(); + // need to remove controllers that have disconnected + for(Controller controller:controllers){ + boolean controllerExist = false; + for(int i = 0; i < newScanControllers.length; i++){ + if(controller == newScanControllers[i]){ + controllerExist = true; + break; + } + } + if(!controllerExist){ + //controllers.remove(controller); + removeControllers.add(controller); + } + } + for(Controller controller: removeControllers){ + controllers.remove(controller); } } - } + Controller[] ret = new Controller[controllers.size()]; + Iterator it = controllers.iterator(); + int i = 0; + while (it.hasNext()) { + ret[i] = (Controller)it.next(); + i++; + } + return ret; + } + /* This is jeff's new plugin code using Jeff's Plugin manager */ - private Void scanControllers() { + private void scanControllers() { String pluginPathName = getPrivilegedProperty("jinput.controllerPluginPath"); if(pluginPathName == null) { pluginPathName = "controller"; @@ -168,8 +252,6 @@ class DefaultControllerEnvironment extends ControllerEnvironment { File.separator + "lib"+File.separator + pluginPathName); scanControllersAt(getPrivilegedProperty("user.dir")+ File.separator + pluginPathName); - - return null; } private void scanControllersAt(String path) { @@ -179,19 +261,19 @@ class DefaultControllerEnvironment extends ControllerEnvironment { } try { Plugins plugins = new Plugins(file); - @SuppressWarnings("unchecked") - Class[] envClasses = plugins.getExtends(ControllerEnvironment.class); + Class[] envClasses = plugins.getExtends(ControllerEnvironment.class); for(int i=0;i event_components, LinuxEventDevice device) { LinuxEventComponent[][] povs = new LinuxEventComponent[4][2]; List components = new ArrayList<>(); diff --git a/src/plugins/windows/net/java/games/input/DirectAndRawInputEnvironmentPlugin.java b/src/plugins/windows/net/java/games/input/DirectAndRawInputEnvironmentPlugin.java index 29b6c07..8e96ea7 100644 --- a/src/plugins/windows/net/java/games/input/DirectAndRawInputEnvironmentPlugin.java +++ b/src/plugins/windows/net/java/games/input/DirectAndRawInputEnvironmentPlugin.java @@ -84,6 +84,11 @@ public class DirectAndRawInputEnvironmentPlugin extends ControllerEnvironment { return controllers; } + public final Controller[] rescanControllers() { + controllers=null; + return getControllers(); + } + /** * @see net.java.games.input.ControllerEnvironment#isSupported() */ diff --git a/src/plugins/windows/net/java/games/input/DirectInputEnvironmentPlugin.java b/src/plugins/windows/net/java/games/input/DirectInputEnvironmentPlugin.java index ed507f9..d28b2df 100644 --- a/src/plugins/windows/net/java/games/input/DirectInputEnvironmentPlugin.java +++ b/src/plugins/windows/net/java/games/input/DirectInputEnvironmentPlugin.java @@ -138,6 +138,10 @@ public final class DirectInputEnvironmentPlugin extends ControllerEnvironment im return controllers; } + public Controller[] rescanControllers() { + return enumControllers(window); + } + private final Component[] createComponents(IDirectInputDevice device, boolean map_mouse_buttons) { List device_objects = device.getObjects(); List controller_components = new ArrayList<>(); diff --git a/src/plugins/windows/net/java/games/input/RawInputEnvironmentPlugin.java b/src/plugins/windows/net/java/games/input/RawInputEnvironmentPlugin.java index 9d409aa..2293e96 100644 --- a/src/plugins/windows/net/java/games/input/RawInputEnvironmentPlugin.java +++ b/src/plugins/windows/net/java/games/input/RawInputEnvironmentPlugin.java @@ -121,6 +121,11 @@ public final class RawInputEnvironmentPlugin extends ControllerEnvironment imple return controllers; } + public Controller[] rescanControllers() { + RawInputEventQueue queue = new RawInputEventQueue(); + return enumControllers(queue); + } + 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 diff --git a/src/plugins/wintab/net/java/games/input/WinTabEnvironmentPlugin.java b/src/plugins/wintab/net/java/games/input/WinTabEnvironmentPlugin.java index aa0c839..32e747d 100644 --- a/src/plugins/wintab/net/java/games/input/WinTabEnvironmentPlugin.java +++ b/src/plugins/wintab/net/java/games/input/WinTabEnvironmentPlugin.java @@ -120,12 +120,19 @@ public class WinTabEnvironmentPlugin extends ControllerEnvironment implements Pl return controllers; } + public Controller[] rescanControllers() { + winTabContext.close(); + winTabContext = new WinTabContext(window); + winTabContext.open(); + return winTabContext.getControllers(); + } + 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++) { + /*for (int i = 0; i < active_devices.size(); i++) { // TODO free the devices - } + }*/ //Close the context winTabContext.close(); /* We won't release the window since it is