package edu.ysu.itrace.trackers; import edu.ysu.itrace.*; import edu.ysu.itrace.calibration.CalibrationStatusDisplay; import edu.ysu.itrace.calibration.Calibrator; import edu.ysu.itrace.exceptions.CalibrationException; import java.awt.Dimension; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.MouseInfo; import java.awt.Point; import java.awt.Toolkit; import java.io.*; import java.util.concurrent.LinkedBlockingQueue; import javax.swing.JFrame; import java.util.Date; import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.ui.PlatformUI; /** * Tracker which follows the mouse cursor. Useful for testing when no eye * tracker is present. */ public class SystemMouseTracker implements IEyeTracker { private static class TrackerThread extends Thread { private enum RunState { RUNNING, STOPPING, STOPPED } private SystemMouseTracker parent = null; private volatile RunState running = RunState.STOPPED; private IEventBroker eventBroker; public TrackerThread(SystemMouseTracker parent) { this.parent = parent; this.eventBroker = PlatformUI.getWorkbench().getService(IEventBroker.class); } public void startTracking() { start(); } public void stopTracking() { //Already stopped. if (running != RunState.RUNNING) return; running = RunState.STOPPING; while (running != RunState.STOPPED) { try { Thread.sleep(25); } catch (InterruptedException e) { //Just try again. } } } //Executed on separate thread to get mouse "gaze" data. public void run() { running = RunState.RUNNING; while (running == RunState.RUNNING) { Point cursorPosition = MouseInfo.getPointerInfo(). getLocation(); Dimension screenSize = Toolkit.getDefaultToolkit(). getScreenSize(); double x = (double) cursorPosition.x / (double) screenSize.width; double y = (double) cursorPosition.y / (double) screenSize.height; Gaze gaze = new Gaze(x - 0.05, x + 0.05, y, y, 1.0, 1.0, 0.0, 0.0, System.currentTimeMillis()); parent.calibrator.moveCrosshair(cursorPosition.x, cursorPosition.y); parent.gazePoints.add(gaze); //if(Activator.getDefault().recording) eventBroker.post("iTrace/newgaze", gaze); try { Thread.sleep(25); } catch (InterruptedException e) { //Just try again. } } running = RunState.STOPPED; } } private class SystemMouseCalibrator extends Calibrator { public SystemMouseCalibrator() throws IOException { super(); } protected void startCalibration() throws Exception { //Do nothing. } protected void stopCalibration() throws Exception { //Do nothing. } protected void useCalibrationPoint(double x, double y) throws Exception { //Do nothing. } @Override protected void displayCalibrationStatus(JFrame frame) throws Exception { CalibrationStatusDisplay calibDisplay = new CalibrationStatusDisplay(frame, calibrationPoints,new java.awt.geom.Point2D.Double[9]); frame.setMinimumSize(new Dimension(600,300)); frame.add(calibDisplay); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.setVisible(true); frame.setTitle("Calibration: "+new Date()); Insets insets = frame.getInsets(); int width = frame.getSize().width-(insets.left+insets.right); int height = frame.getSize().height-(insets.top+insets.bottom); calibDisplay.windowDimension = new Dimension(width,height); frame.toFront(); calibDisplay.repaint(); } } private LinkedBlockingQueue<Gaze> gazePoints = new LinkedBlockingQueue<Gaze>(); private SystemMouseCalibrator calibrator; private TrackerThread trackerThread = null; public SystemMouseTracker() throws IOException { calibrator = new SystemMouseCalibrator(); } public void close() { try { stopTracking(); } catch (IOException e) { //There's not really much that can be done at this point. } } public void clear() { gazePoints = new LinkedBlockingQueue<Gaze>(); } public void calibrate() throws CalibrationException { calibrator.calibrate(); try { //calibrator.displayCalibrationStatus(); } catch (Exception e) { e.printStackTrace(); throw new CalibrationException("Cannot display calibration status!"); } } public void startTracking() throws IOException { if (trackerThread != null) return; trackerThread = new TrackerThread(this); trackerThread.startTracking(); } public void stopTracking() throws IOException { if (trackerThread == null) return; trackerThread.stopTracking(); trackerThread = null; } public Gaze getGaze() { return gazePoints.poll(); } public void displayCrosshair(boolean enabled) { calibrator.displayCrosshair(enabled); } public void setXDrift(int drift) { } public void setYDrift(int drift) { } }