PageRenderTime 62ms CodeModel.GetById 14ms app.highlight 42ms RepoModel.GetById 1ms app.codeStats 1ms

/src/org/mt4j/input/InputManager.java

http://mt4j.googlecode.com/
Java | 391 lines | 199 code | 50 blank | 142 comment | 22 complexity | 63307f5c176f7ad32c1fbe2a7905aedc MD5 | raw file
  1/***********************************************************************
  2 * mt4j Copyright (c) 2008 - 2009, C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3 *  
  4 *   This program is free software: you can redistribute it and/or modify
  5 *   it under the terms of the GNU General Public License as published by
  6 *   the Free Software Foundation, either version 3 of the License, or
  7 *   (at your option) any later version.
  8 *
  9 *   This program is distributed in the hope that it will be useful,
 10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *   GNU General Public License for more details.
 13 *
 14 *   You should have received a copy of the GNU General Public License
 15 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 16 *
 17 ***********************************************************************/
 18package org.mt4j.input;
 19
 20import java.awt.Cursor;
 21import java.awt.Image;
 22import java.awt.Point;
 23import java.awt.Toolkit;
 24import java.awt.image.MemoryImageSource;
 25import java.io.FileInputStream;
 26import java.io.IOException;
 27import java.io.InputStream;
 28import java.util.ArrayList;
 29import java.util.Arrays;
 30import java.util.Collection;
 31import java.util.HashMap;
 32import java.util.List;
 33import java.util.Map;
 34import java.util.Properties;
 35import java.util.Set;
 36
 37import org.mt4j.MTApplication;
 38import org.mt4j.input.inputProcessors.globalProcessors.AbstractGlobalInputProcessor;
 39import org.mt4j.input.inputSources.AbstractInputSource;
 40import org.mt4j.input.inputSources.IinputSourceListener;
 41import org.mt4j.input.inputSources.KeyboardInputSource;
 42import org.mt4j.input.inputSources.MouseInputSource;
 43import org.mt4j.input.inputSources.MultipleMiceInputSource;
 44import org.mt4j.input.inputSources.TuioInputSource;
 45import org.mt4j.input.inputSources.Win7NativeTouchSource;
 46import org.mt4j.sceneManagement.Iscene;
 47import org.mt4j.util.MT4jSettings;
 48import org.mt4j.util.logging.ILogger;
 49import org.mt4j.util.logging.MTLoggerFactory;
 50
 51
 52
 53/**
 54 * Manages the InputSources and Inputprocessors for each scene.
 55 * Starts up the default input sources.
 56 * 
 57 * @author Christopher Ruff
 58 */
 59public class InputManager {
 60	/** The Constant logger. */
 61	private static final ILogger logger = MTLoggerFactory.getLogger(InputManager.class.getName());
 62	static{
 63//		logger.setLevel(ILogger.ERROR);
 64//		logger.setLevel(ILogger.DEBUG);
 65		logger.setLevel(ILogger.INFO);
 66	}
 67	
 68	/** The registered input sources. */
 69	private List<AbstractInputSource> registeredInputSources;
 70	
 71	/** The In processor to scene. */
 72	private Map<AbstractGlobalInputProcessor, Iscene> inputProcessorsToScene;
 73	
 74	/** The pa. */
 75	private MTApplication app;
 76	
 77	
 78	/**
 79	 * Instantiates a new input manager.
 80	 * 
 81	 * @param pa the processing context
 82	 */
 83	public InputManager(MTApplication pa) {
 84		this(pa, true);
 85	}
 86	
 87	
 88	/**
 89	 * Instantiates a new input manager.
 90	 * 
 91	 * @param pa the processing context
 92	 */
 93	public InputManager(MTApplication pa, boolean registerDefaultSources) {
 94		super();
 95		this.registeredInputSources	= new ArrayList<AbstractInputSource>();
 96		this.inputProcessorsToScene = new HashMap<AbstractGlobalInputProcessor, Iscene>();
 97		this.app = pa;
 98		
 99		if (registerDefaultSources)
100			this.registerDefaultInputSources();
101	}
102	
103	
104	/**
105	 * Initialize default input sources.
106	 */
107	protected void registerDefaultInputSources(){
108		boolean enableMultiMouse = false;
109		Properties properties = new Properties();
110
111		try {
112			FileInputStream fi = new FileInputStream(MT4jSettings.getInstance().getDefaultSettingsPath() + "Settings.txt");
113			properties.load(fi); 
114			enableMultiMouse = Boolean.parseBoolean(properties.getProperty("MultiMiceEnabled", "false").trim());
115		}catch (Exception e) {
116			logger.debug("Failed to load Settings.txt from the File system. Trying to load it from classpath..");
117			try {
118				InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("Settings.txt");
119				if (in != null){
120					properties.load(in);
121					enableMultiMouse = Boolean.parseBoolean(properties.getProperty("MultiMiceEnabled", "false").trim());
122				}else{
123					logger.debug("Couldnt load Settings.txt as a resource. Using defaults.");
124				}
125			} catch (IOException e1) {
126				logger.error("Couldnt load Settings.txt. Using defaults.");
127				e1.printStackTrace();
128			}
129		}
130
131		if (enableMultiMouse){
132			try {
133				//Register single or multiple mice input source
134				int connectedMice = MultipleMiceInputSource.getConnectedMouseCount();
135				//	    		/*
136				logger.info("Found mice: " + connectedMice);
137				if (connectedMice >= 2){ //FIXME should be > 1, but manymouse often detects more that arent there!?
138					logger.info("-> Multiple Mice detected!");
139					MultipleMiceInputSource multipleMice = new MultipleMiceInputSource(app);
140	    			multipleMice.setMTApp(app);
141	    			this.registerInputSource(multipleMice);
142	    			this.hideCursorInFrame();
143	    		}else{
144//	    			*/
145	    			MouseInputSource mouseInput = new MouseInputSource(app);
146	    			this.registerInputSource(mouseInput);
147	    		}
148//	    		*/
149	    	} catch (Exception e) {
150	    		e.printStackTrace();
151	    		//Use default mouse input source
152	    		MouseInputSource mouseInput = new MouseInputSource(app);
153	    		this.registerInputSource(mouseInput);
154	    	}
155	    }
156	    else{
157//	    	*/
158	    	MouseInputSource mouseInput = new MouseInputSource(app);
159	    	this.registerInputSource(mouseInput);
160	    }
161//	    */
162
163	    //Check if we run windows 7
164	    if (System.getProperty("os.name").toLowerCase().contains("windows 7")){
165	    	Win7NativeTouchSource win7NativeInput = new Win7NativeTouchSource(app);
166	    	if (win7NativeInput.isSuccessfullySetup()){
167	    		this.registerInputSource(win7NativeInput);
168	    	}
169	    }
170	    
171	    //check which versions it supports and only start there!
172	    /*
173	    if (System.getProperty("os.name").toLowerCase().contains("mac os x")){
174	    	this.registerInputSource(new MacTrackpadSource(app));
175	    }
176	    */
177
178	    KeyboardInputSource keyInput= new KeyboardInputSource(app);
179		TuioInputSource tuioInput 	= new TuioInputSource(app);
180//		MuitoInputSource muitoInput = new MuitoInputSource(pa, "localhost", 6666);
181		
182		this.registerInputSource(keyInput);
183		this.registerInputSource(tuioInput);
184	}
185	
186	
187	/**
188	 * Registers a new input source for the application.
189	 * 
190	 * @param newInputSource the new input source
191	 */
192	public void registerInputSource(AbstractInputSource newInputSource){
193		if (!registeredInputSources.contains(newInputSource)){
194			registeredInputSources.add(newInputSource);
195			//Add all processors to the new input source
196			Set<AbstractGlobalInputProcessor> set = inputProcessorsToScene.keySet();
197            for (AbstractGlobalInputProcessor processor : set) {
198                //newInputSource.addInputListener(processor);
199                this.saveAddInputListenerToSource(newInputSource, processor);
200            }
201			
202			//Inform the input source that it is now registered with the application
203			newInputSource.onRegistered();
204		}else{
205			logger.error("input source already registered! - " + newInputSource);
206		}
207	}
208	
209	
210	/**
211	 * Unregisters a input source.
212	 * @param is the input source
213	 */
214	public void unregisterInputSource(AbstractInputSource is){
215		synchronized (registeredInputSources) {
216			if (registeredInputSources.contains(is)){
217				registeredInputSources.remove(is);
218				
219				//Inform the input source that it is now UN-registered from the application
220				is.onUnregistered();
221			}
222		}
223	}
224	
225	/**
226	 * Gets the input sources.
227	 * @return the input sources
228	 */
229	public AbstractInputSource[] getInputSources(){
230		return this.registeredInputSources.toArray(new AbstractInputSource[this.registeredInputSources.size()]);
231	}
232	
233	/**
234	 * Gets the registered input sources.
235	 * 
236	 * @return the registered input sources
237	 * @deprecated use getInputSources() instead
238	 */
239	public Collection<AbstractInputSource> getRegisteredInputSources(){
240		return this.registeredInputSources;
241	}
242	
243	
244	/**
245	 * Hides the mousecursor in multiple mice mode.
246	 */
247	private void hideCursorInFrame(){
248		int[] pixels = new int[16 * 16];
249		Image image = Toolkit.getDefaultToolkit().createImage(
250		        new MemoryImageSource(16, 16, pixels, 0, 16));
251		Cursor transparentCursor =
252		        Toolkit.getDefaultToolkit().createCustomCursor
253		             (image, new Point(0, 0), "invisibleCursor");
254		app.frame.setCursor(transparentCursor);
255	}
256	
257	
258	/**
259	 * Registers a new inputprocessor and adds it to the inputsources as listeners.
260	 * 
261	 * @param scene the scene
262	 * @param inputprocessor the input processor
263	 */
264	public void registerGlobalInputProcessor(Iscene scene, AbstractGlobalInputProcessor inputprocessor){
265		//By default disable the registered global input processor, so it doesent accidently
266		//send events to a not even visible scene
267		//-Only enable it if the scene is the currently active scene
268		//-If a scene becomes active the processors will also be enabled
269//		if (app.getCurrentScene() != null && app.getCurrentScene().equals(scene)){
270		if (scene.equals(app.getCurrentScene())){
271			inputprocessor.setDisabled(false);
272		}else{
273			inputprocessor.setDisabled(true);
274		}
275		
276		inputProcessorsToScene.put(inputprocessor, scene);
277		//Register the processor with all registered inputsources
278		for (AbstractInputSource source: registeredInputSources){
279			this.saveAddInputListenerToSource(source, inputprocessor);
280		}
281	}
282	
283	
284	private void saveAddInputListenerToSource(AbstractInputSource source, AbstractGlobalInputProcessor inputprocessor){
285		//Only add input processor to input sources 
286		//that fire the event type that the processor is interested in
287//		if (source.firesEventType(inputprocessor.getListenEventType())){
288		
289			List<IinputSourceListener> sourceListener = Arrays.asList(source.getInputListeners());
290			if (!sourceListener.contains(inputprocessor)){ //Prevent adding same global input processor twice
291				source.addInputListener(inputprocessor);
292			}
293//		}
294	}
295	
296	/**
297	 * Unregisters a inputprocessor from _all_ the registered inputsources.
298	 * 
299	 * @param inputprocessor the input processor
300	 */
301	public void unregisterGlobalInputProcessor(AbstractGlobalInputProcessor inputprocessor){
302		/*
303		Set set = InprocessorToScene.keySet(); 
304		for (Iterator iter = set.iterator(); iter.hasNext();) {
305			AbstractInputprocessor processor = (AbstractInputprocessor) iter.next();
306			
307			//Check if the processor is registered here with a scene
308			if (processor.equals(inputprocessor)){
309				if (InprocessorToScene.get(processor).equals(scene)){
310					for (AbstractInputSource source: registeredInputSources){
311						source.removeInputListener(inputprocessor);
312					}
313				}
314			}
315		}
316		*/
317		
318		//Remove the input processor from the processor->scene map
319		if (inputProcessorsToScene.containsKey(inputprocessor)){
320			inputProcessorsToScene.remove(inputprocessor);	
321		}
322		
323		for (AbstractInputSource source: registeredInputSources){
324			source.removeInputListener(inputprocessor);
325		}
326	}
327	
328	
329	/**
330	 * Gets the global inputprocessors associated with the specified scene.
331	 * 
332	 * @param scene the scene
333	 * 
334	 * @return the scene inputprocessors
335	 */
336	public AbstractGlobalInputProcessor[] getGlobalInputProcessors(Iscene scene){
337		List<AbstractGlobalInputProcessor> processors = new ArrayList<AbstractGlobalInputProcessor>();
338		
339		Set<AbstractGlobalInputProcessor> set = inputProcessorsToScene.keySet();
340        for (AbstractGlobalInputProcessor processor : set) {
341            if (inputProcessorsToScene.get(processor).equals(scene)) {
342                processors.add(processor);
343            }
344        }
345		return processors.toArray(new AbstractGlobalInputProcessor[processors.size()]);
346	}
347	
348	/**
349	 * Enables the global inputprocessors that are associated with the given scene.
350	 * 
351	 * @param scene the scene
352	 */
353	public void enableGlobalInputProcessors(Iscene scene){
354		Set<AbstractGlobalInputProcessor> set = inputProcessorsToScene.keySet();
355        for (AbstractGlobalInputProcessor processor : set) {
356            if (inputProcessorsToScene.get(processor).equals(scene)) {
357                processor.setDisabled(false);
358            }
359        }
360	}
361	
362	/**
363	 * Disables the global inputprocessors that are associated with the given scene.
364	 * 
365	 * @param scene the scene
366	 */
367	public void disableGlobalInputProcessors(Iscene scene){
368		Set<AbstractGlobalInputProcessor> set = inputProcessorsToScene.keySet();
369        for (AbstractGlobalInputProcessor processor : set) {
370            if (inputProcessorsToScene.get(processor).equals(scene)) {
371                processor.setDisabled(true);
372            }
373        }
374	}
375	
376	
377	/**
378	 * Removes input processors of the specified scene from listening to the registered input sources.
379	 * 
380	 * @param scene the scene
381	 */
382	public void removeGlobalInputProcessors(Iscene scene){
383		AbstractGlobalInputProcessor[] sceneProcessors = this.getGlobalInputProcessors(scene);
384        for (AbstractGlobalInputProcessor abstractGlobalInputProcessor : sceneProcessors) {
385            this.unregisterGlobalInputProcessor(abstractGlobalInputProcessor);
386        }
387	}
388
389
390	
391}