// Given trial number, execute trials
// Returns trial result code
int do_simple_trial(int num)
{
  // This supplies the title at the bottom of the eyetracker display
  eyecmd_printf("record_status_message 'SIMPLE WORDS, TRIAL %d/%d' ", num, NTRIALS);
  
  /* Always send a TRIALID message before starting to record.
  It should contain trial condition data required for analysis.
  */
  eyemsg_printf("TRIALID %s", trial_word[num-1]);
  
  /* TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
  It specifies the list of trial variables value for the trial
  This must be specified within the scope of an individual trial (i.e., after
  "TRIALID" and before "TRIAL_RESULT") */
  eyemsg_printf("!V TRIAL_VAR_DATA %s", trial_word[num-1]);
  
  // Before recording, we place reference graphics on the EyeLink display
  set_offline_mode();		     // Must be offline to draw to EyeLink screen
  eyecmd_printf("clear_screen 0");   // clear tracker display and draw box at center
  eyecmd_printf("draw_box %d %d %d %d  7", SCRWIDTH/2-16, SCRHEIGHT/2-16,
    SCRWIDTH/2+16, SCRHEIGHT/2+16);
  
  // Actually run the trial: display a single word
  
  
  //SEAN 20000L --> 5000L
  //return simple_recording_trial(trial_word[num-1], 5000L);
  // above was the original; intercept this with
  return 1;  //sean_recording_trial();

}
// ######################################################################
void EyeTrackerEyeLink::startTracking()
{
#ifndef HAVE_EYELINK
  LFATAL("Proprietary EyeLink developer API not installed");
#else
  // Show message at bottom of tracker display:
  eyecmd_printf(const_cast<char*>("record_status_message 'Recording [%d]...' "), getSession());

	// set FIXUPDATE event property
  eyecmd_printf(const_cast<char*>("fixation_update_interval = 50"));
  eyecmd_printf(const_cast<char*>("fixation_update_accumulate = 50"));

  // Always send a TRIALID message before starting to record.  It
  // should contain trial condition data required for analysis:
  eyemsg_printf(const_cast<char*>("TRIALID EYETRACK"));

  // TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer
  // analysis It specifies the list of trial variables value for the
  // trial This must be specified within the scope of an individual
  // trial (i.e., after "TRIALID" and before "TRIAL_RESULT"):
  eyemsg_printf(const_cast<char*>("!V TRIAL_VAR_DATA EYETRACKING"));

  // Log eye tracker time at onset of clip:
  if (itsEventLog.isValid())
    itsEventLog->pushEvent(sformat("Eye Tracker Time = %d", int(current_msec())));

  // Actually start the recording:
  if (start_recording(1, 1, 1, 1))
    LFATAL("Error trying to start recording");
#endif
}
/* End recording: adds 100 msec of data to catch final events */
static void end_trial(void)
{
  clear_full_screen_window(target_background_color);    /* hide display */
  end_realtime_mode();   /* NEW: ensure we release realtime lock */
  pump_delay(100);       /* CHANGED: allow Windows to clean up   */
                         /* while we record additional 100 msec of data  */
  stop_recording();
  
    /* Reset link data, disable fixation event data */
  eyecmd_printf("link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON");
  eyecmd_printf("fixation_update_interval = 0");
  eyecmd_printf("fixation_update_accumulate = 0");
 
}
// ######################################################################
void EyeTrackerEyeLink::stop1()
{
#ifndef HAVE_EYELINK
  LFATAL("Proprietary EyeLink developer API not installed");
#else
  set_offline_mode();
  pump_delay(500); // give some time to tracker to stop

  // close EDF data file if any:
  if (itsEDFfname.getVal().empty() == false)
    eyecmd_printf(const_cast<char*>("close_data_file"));
	

  // shutdown EyeLink properly:
  close_expt_graphics();

  // transfer the EDF file if any:
  if (itsEDFfname.getVal().empty() == false)
    {
      LINFO("Transferring EDF file to '%s'", itsEDFfname.getVal().c_str());
      receive_data_file((char *)itsEDFfname.getVal().c_str(),
                        (char *)itsEDFfname.getVal().c_str(), 0);
    }

  // Disconnect from eyelink:
  close_eyelink_connection();

  EyeTracker::stop1();
#endif
}
// ######################################################################
void EyeTrackerEyeLink::stopTracking()
{
#ifndef HAVE_EYELINK
  LFATAL("Proprietary EyeLink developer API not installed");
#else
  // report response result: 0=timeout, else button number:
  eyemsg_printf(const_cast<char*>("TRIAL_RESULT 1"));

  // stop the tracker:
  stop_recording();

	// set FIXUPDATE event property (close it)
  eyecmd_printf(const_cast<char*>("fixation_update_interval = 0"));
  eyecmd_printf(const_cast<char*>("fixation_update_accumulate = 0"));

	set_offline_mode();
#endif
}
/*
	FOR EACH TRIAL:
		- set title, TRIALID
		- Create bitmaps and EyeLink display graphics
		- Check for errors in creating bitmaps
		- Run the trial recording loop
		- Delete bitmaps
		- Return any error code

	Given trial number, execute trials
	Returns trial result code
*/
int do_simple_trial(int num)
{
        /* This supplies the title at the bottom of the eyetracker display  */
  eyecmd_printf("record_status_message 'SIMPLE WORDS, TRIAL %d/%d' ", num, NTRIALS);

        /*	
			Always send a TRIALID message before starting to record. 
			It should contain trial condition data required for analysis.
		*/
  eyemsg_printf("TRIALID %s", trial_word[num-1]);

        /*	Before recording, we place reference graphics on the EyeLink display */
  set_offline_mode();		     /* Must be offline to draw to EyeLink screen */
  eyecmd_printf("clear_screen 0");   /* clear tracker display and draw box at center  */
  eyecmd_printf("draw_box %d %d %d %d  7", SCRWIDTH/2-16, SCRHEIGHT/2-16, 
  					   SCRWIDTH/2+16, SCRHEIGHT/2+16);

        /* Actually run the trial: display a single word */
  return simple_recording_trial(trial_word[num-1], 20000L); 
}
         // Create foreground and background bitmaps of picture
         // EyeLink graphics: blank display with box at center
         // type: 0 = blank background, 1= blank fovea (mask), 2 = blurred background
static int create_image_bitmaps(int type)
{ 
  target_foreground_color = RGB(0,0,0);         // color of calibration target
  target_background_color = RGB(128,128,128);   // background for drift correction
  set_calibration_colors(target_foreground_color, target_background_color); // tell EXPTSPPT the colors

  clear_full_screen_window(target_background_color);
// NOTE:  *** THE FOLLOWING TEXT SHOULD NOT APPEAR IN A REAL EXPERIMENT!!!! ****
  get_new_font("Arial", 24, 1);
  graphic_printf(target_foreground_color, -1, 1, SCRWIDTH/2, SCRHEIGHT/2, "Loading image...");

  switch(type)
    {  
      case 0:     // blank background
        fgbm = image_file_bitmap("images/sacrmeto.jpg", 0, SCRWIDTH,SCRHEIGHT,target_background_color);
        bgbm = blank_bitmap(target_background_color);
        break;
      case 1:     // blank fovea
        fgbm = blank_bitmap(target_background_color);
        bgbm = image_file_bitmap("images/sacrmeto.jpg", 0, SCRWIDTH,SCRHEIGHT,target_background_color);
        break;
      case 2:     // normal and blurred bitmaps, stretched to fit display
        fgbm = image_file_bitmap("images/sacrmeto.jpg", 0, SCRWIDTH,SCRHEIGHT,target_background_color);
        bgbm = image_file_bitmap("images/sac_blur.jpg", 0, SCRWIDTH,SCRHEIGHT,target_background_color);
        break;
    }

  eyecmd_printf("clear_screen 0");                   // clear EyeLink display
  eyecmd_printf("draw_box %d %d %d %d 15",          // Box around fixation point
           SCRWIDTH/2-16, SCRHEIGHT/2-16, SCRWIDTH/2+16, SCRHEIGHT/2+16);

  if(!fgbm || !bgbm)  // Check that both bitmaps exist.
    {
      eyemsg_printf("ERROR: could not load image");
      alert_printf("ERROR: could not load an image file");
      if(fgbm) DeleteObject(fgbm);
      if(bgbm) DeleteObject(bgbm);
      return SKIP_TRIAL;
    }
  return 0;
}
// ######################################################################
void EyeTrackerEyeLink::openSDL()
{
#ifdef HAVE_EYELINK
  // set the display characteristics:
	DISPLAYINFO di;
  di.width = itsDims.getVal().w(); di.height = itsDims.getVal().h();
  di.left = 0; di.top = 0; di.right = di.width-1; di.bottom = di.height-1;
  di.bits = 24; di.palsize = 0; di.pages = 0; di.refresh = 60.0F;
  di.winnt = 0;

  // open the display with our wishes:
  if (init_expt_graphics(NULL, &di))
    LFATAL("Cannot open display");

  // see what we actually got:
  get_display_information(&di);
  LINFO("DISPLAYINFO: [%dx%d}: (%d,%d)-(%d,%d) %dbpp %.1fHz",
        int(di.width), int(di.height), int(di.left), int(di.top),
        int(di.right), int(di.bottom), int(di.bits), di.refresh);
  if (di.palsize) LFATAL("Paletized color modes not supported");

  // Prepare for calibration and other settings:
  set_target_size(10, 2);
  set_calibration_colors(&target_foreground_color, &target_background_color);
  set_cal_sounds(const_cast<char*>(""), const_cast<char*>(""), const_cast<char*>(""));
  set_dcorr_sounds(const_cast<char*>(""), const_cast<char*>("off"), const_cast<char*>("off"));

  // Setup calibration type:
  eyecmd_printf(const_cast<char*>("calibration_type = HV9"));

  // Configure tracker for display:
  eyecmd_printf(const_cast<char*>("screen_pixel_coords = %ld %ld %ld %ld"),
                di.left, di.top, di.right, di.bottom);

        if (di.refresh > 40.0F)
    eyemsg_printf(const_cast<char*>("FRAMERATE %1.2f Hz."), di.refresh);
#endif
}
// ######################################################################
void EyeTrackerEyeLink::manualDriftCorrection(Point2D<double> eyepos, 
								                              Point2D<double> targetpos)
{
#ifndef HAVE_EYELINK
  LFATAL("Proprietary EyeLink developer API not installed");
#else
	char message[256];
	eyecmd_printf(const_cast<char*>("drift_correction %ld %ld %ld %ld"), 
									                 targetpos.i-eyepos.i, targetpos.j-eyepos.j,
																	 targetpos.i, targetpos.j);

	// Get drift correction result
	eyelink_cal_message(message);
	eyemsg_printf(message);
#endif
}
Exemple #10
0
int end_expt(char * our_file_name)
{
	/*END: close, transfer EDF file */
	set_offline_mode(); /* set offline mode so we can transfer file */
	pump_delay(500);    /* delay so tracker is ready */
	/* close data file */
	eyecmd_printf("close_data_file");

	if(break_pressed())
	  return exit_eyelink(); /* don't get file if we aborted experiment */
	if(our_file_name[0])   /* make sure we created a file */
	{
		close_expt_graphics();           /* tell EXPTSPPT to release window */
		receive_data_file(our_file_name, "", 0);
	}
	/* transfer the file, ask for a local name */

	return exit_eyelink();
}
Exemple #11
0
app_main()
{
  int i, j;
  char our_file_name[260] = "TEST";

  if(open_eyelink_connection(0)) return -1;    // abort if we can't open link
  set_offline_mode();                          
  flush_getkey_queue();                        // initialize getkey() system
  is_eyelink2 = (2 == eyelink_get_tracker_version(NULL) );

  get_display_information(&dispinfo);          // get window size, characteristics
      
     // NOTE: Camera display does not support 16-color modes
     // NOTE: Picture display examples don't work well with 256-color modes
     //       However, all other sample programs should work well.
  if(dispinfo.palsize==16)      // 16-color modes not functional
    {
      alert_printf("This program cannot use 16-color displays");
      goto shutdown;
    }
  if(dispinfo.refresh < 40)  // wait_for_refresh doesn't work!
    {
      alert_printf("No refresh synchroniztion available!");
    }
  if(dispinfo.palsize)     // 256-color modes: palettes not supported by this example
    {
      alert_printf("This program is not optimized for 256-color displays");
    }



  //SEAN  -display window
  if(make_full_screen_window(application_instance)) goto shutdown;  // create the window
  if(init_expt_graphics(full_screen_window, NULL)) goto shutdown;   // register window with EXPTSPPT

  i = SCRWIDTH/60;        // select best size for calibration target
  j = SCRWIDTH/300;       // and focal spot in target
  if(j < 2) j = 2;
  set_target_size(i, j);  // tell DLL the size of target features

  target_foreground_color = RGB(0,0,0);    // color of calibration target
  target_background_color = RGB(128,128,128);       // background for calibration and drift correction
  set_calibration_colors(target_foreground_color, target_background_color); // tell EXPTSPPT the colors

  set_cal_sounds("", "", "");
  set_dcorr_sounds("", "off", "off");
                                     // draw a title screen
  
  // SEAN
  clear_full_screen_window(target_background_color);    // clear screen

  get_new_font("Times Roman", SCRHEIGHT/32, 1);         // select a font
                                                        // Draw text
  graphic_printf(target_foreground_color, target_background_color, 1, SCRWIDTH/2, 1*SCRHEIGHT/30, 
                 "EyeLink Demonstration Experiment: Sample Code");
  graphic_printf(target_foreground_color, target_background_color, 1, SCRWIDTH/2, 2*SCRHEIGHT/30,
                 "Included with the Experiment Programming Kit for Windows");
  graphic_printf(target_foreground_color, target_background_color, 1, SCRWIDTH/2, 3*SCRHEIGHT/30, 
                 "All code is Copyright (c) 1997-2002 SR Research Ltd.");
  graphic_printf(target_foreground_color, target_background_color, 0, SCRWIDTH/5, 4*SCRHEIGHT/30, 
                 "Source code may be used as template for your experiments.");




//SEAN - file i/o
  i = edit_dialog(full_screen_window, "Create EDF File",            // Get the EDF file name
                 "Enter Tracker EDF file name:", our_file_name, 8);

  if(i==-1) goto shutdown;          // ALT-F4: terminate
  if(i==1)  our_file_name[0] = 0;   // Cancelled: No file name
  
  if(our_file_name[0])    // If file name set, open it
    {           
      if(!strstr(our_file_name, ".")) strcat(our_file_name, ".EDF");  // add extension
      i = open_data_file(our_file_name);                              // open file
      if(i!=0)                                                        // check for error
        {
          alert_printf("Cannot create EDF file '%s'", our_file_name);
          goto shutdown;
        }                                                              // add title to preamble
      eyecmd_printf("add_file_preamble_text 'RECORDED BY %s' ", program_name);
    }
                                      // Now configure tracker for display resolution
  eyecmd_printf("screen_pixel_coords = %ld %ld %ld %ld",    // Set display resolution   
                 dispinfo.left, dispinfo.top, dispinfo.right, dispinfo.bottom);
  eyecmd_printf("calibration_type = HV9");                  // Setup calibration type
  eyemsg_printf("DISPLAY_COORDS %ld %ld %ld %ld",           // Add resolution to EDF file
                 dispinfo.left, dispinfo.top, dispinfo.right, dispinfo.bottom);
  if(dispinfo.refresh>40)
    eyemsg_printf("FRAMERATE %1.2f Hz.", dispinfo.refresh);




		// SET UP TRACKER CONFIGURATION 
		      // set parser saccade thresholds (conservative settings)
  if(is_eyelink2)
    {
      eyecmd_printf("select_parser_configuration 0");  // 0 = standard sensitivity
    }
  else
    {
      eyecmd_printf("saccade_velocity_threshold = 35");
      eyecmd_printf("saccade_acceleration_threshold = 9500");
    }
		      // set EDF file contents 
  eyecmd_printf("file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON");
  eyecmd_printf("file_sample_data  = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS");
		      // set link data (used for gaze cursor) 
  eyecmd_printf("link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON");
  eyecmd_printf("link_sample_data  = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS");
                      // Program button #5 for use in drift correction
  eyecmd_printf("button_function 5 'accept_target_fixation'");

  if(!eyelink_is_connected() || break_pressed()) goto end_expt;  // make sure we're still alive


	
       // RUN THE EXPERIMENTAL TRIALS (code depends on type of experiment)
                // Calling run_trials() performs a calibration followed by trials
                // This is equivalent to one block of an experiment 
                // It will return ABORT_EXPT if the program should exit

  i = run_trials();
  

end_expt:                // END: close, transfer EDF file
  set_offline_mode();               // set offline mode so we can transfer file
  pump_delay(500);                  // delay so tracker is ready
  eyecmd_printf("close_data_file"); // close data file

  if(break_pressed()) goto shutdown;          // don't get file if we aborted experiment
  if(our_file_name[0])                        // make sure we created a file
    receive_data_file(our_file_name, "", 0);  // transfer the file, ask for a local name

shutdown:                // CLEANUP
  close_expt_graphics();           // tell EXPTSPPT to release window
  close_eyelink_connection();      // disconnect from tracker
  close_full_screen_window();
  return 0;
}
int gaze_control_trial(UINT32 time_limit)
{
	UINT32 trial_start;		/* trial start time (for timeout) */
	UINT32 drawing_time;	/* retrace-to-draw delay*/
	int button;				/* the button pressed (0 if timeout) */
	int error;				/* trial result code*/

	ALLF_DATA evt;			/* buffer to hold sample and event data*/
	int eye_used = -1;		/* indicates which eye's data to display*/
	int i;

	SDL_Surface *gbm;			/* The bitmap containing the stimulus display*/

	   /* This supplies the title at the bottom of the eyetracker display */
	eyecmd_printf("record_status_message 'GAZE CONTROL TRIAL' ");

	/*	
	Always send a TRIALID message before starting to record. 
	It should contain trial condition data required for analysis.
	*/
	eyemsg_printf("TRIALID CONTROL");

  /* TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
	It specifies the list of trial variables value for the trial 
	This must be specified within the scope of an individual trial (i.e., after 
	"TRIALID" and before "TRIAL_RESULT") 
	*/
	eyemsg_printf("!V TRIAL_VAR_DATA GAZECTRL");
	/* 
	IMGLOAD command is recorded for EyeLink Data Viewer analysis
	It displays a default image on the overlay mode of the trial viewer screen. 
	Writes the image filename + path info
     */
	eyemsg_printf("!V IMGLOAD FILL images/grid.png");	

	/* 
	IAREA command is recorded for EyeLink Data Viewer analysis
	It creates a set of interest areas by reading the segment files
	Writes segmentation filename + path info
	*/
	eyemsg_printf("!V IAREA FILE segments/grid.ias"); 

	/* Before recording, we place reference graphics on the EyeLink display*/
	set_offline_mode();			/* Must be offline to draw to EyeLink screen*/
	gbm = draw_grid_to_bitmap_segment("grid.ias", "segments", 1);;/* Draw bitmap and EyeLink reference graphics*/
	segment_source = gbm;

	/* 
		Save bitmap and transfer to the tracker pc.
		Since it takes a long to save the bitmap to the file, the 
		value of sv_options should be set as SV_NOREPLACE to save time
	*/

	bitmap_save_and_backdrop(gbm, 0, 0, 0, 0, "grid.png", "images", SV_NOREPLACE,
				  0, 0, (UINT16)(BX_MAXCONTRAST|((eyelink_get_tracker_version(NULL)>=2)?0:BX_GRAYSCALE)));

	   /* DO PRE-TRIAL DRIFT CORRECTION */
	   /* We repeat if ESC key pressed to do setup. */
	while(1)
	{              /* Check link often so we can exit if tracker stopped*/
	  if(!eyelink_is_connected()) return ABORT_EXPT;
	   /* We let do_drift_correct() draw target in this example*/
	   /* 3rd argument would be 0 if we already drew the display*/
	  error = do_drift_correct((INT16)(SCRWIDTH/2), (INT16)(SCRHEIGHT/2), 1, 1);
		   /* repeat if ESC was pressed to access Setup menu */
	  if(error!=27) break;
	}

	clear_full_screen_window(target_background_color);  /* make sure display is blank*/

		/* Configure EyeLink to send fixation updates every 50 msec*/
	eyecmd_printf("link_event_filter = LEFT,RIGHT,FIXUPDATE");
	eyecmd_printf("fixation_update_interval = 50");
	eyecmd_printf("fixation_update_accumulate = 50");

	init_regions();	/* Initialize regions for this display*/

	/* 
		Start data recording to EDF file, BEFORE DISPLAYING STIMULUS 
		You should always start recording 50-100 msec before required
		otherwise you may lose a few msec of data 
	*/
	error = start_recording(1,1,0,1);   /* send events only through link*/
	if(error != 0)           /* ERROR: couldn't start recording*/
	{
	  SDL_FreeSurface(gbm);   /* Be sure to delete bitmap before exiting!*/
	  return error;        /* Return the error code*/
	}
							  /* record for 100 msec before displaying stimulus */
	begin_realtime_mode(100);   /* Windows 2000/XP: no interruptions from now on*/

	/* 
		DISPLAY OUR IMAGE TO SUBJECT  by copying bitmap to display
		Because of faster drawing speeds and good refresh locking,
		we now place the stimulus onset message just after display refresh 
		and before drawing the stimulus.  This is accurate and will allow 
		drawing a new stimulus each display refresh.
	 
		However, we do NOT send the message after the retrace--this may take too long
		instead, we add a number to the message that represents the delay 
		from the event to the message in msec
	*/


	/* COPY BITMAP to display*/
	SDL_BlitSurface(gbm, NULL, window,NULL);
	Flip(window);
	drawing_time = current_msec();                   /* time of retrace*/
	trial_start = drawing_time;
	SDL_BlitSurface(gbm, NULL, window,NULL);
	



	/* delay from retrace (time to draw)*/
	drawing_time = current_msec()-drawing_time;    
	/* message for RT recording in analysis */
	eyemsg_printf("%d DISPLAY ON", drawing_time);
	/* message marks zero-plot time for EDFVIEW */
	eyemsg_printf("SYNCTIME %d", drawing_time);	 

	

	/* Print a title for the trial (for demo only)*/
	get_new_font("Times Roman", 24, 1);     
	graphic_printf(window,target_foreground_color, NONE, SCRWIDTH/2, 24, "Gaze Control Trial");
	

	if(!eyelink_wait_for_block_start(100, 0, 1))  /* wait for link event data*/
	{
	  end_trial();
	  alert_printf("ERROR: No link events received!");
	  return TRIAL_ERROR;
	}
	eye_used = eyelink_eye_available(); /* determine which eye(s) are available*/ 
	switch(eye_used)		      /* select eye, add annotation to EDF file	*/
	{			
	  case RIGHT_EYE:
		eyemsg_printf("EYE_USED 1 RIGHT");
		break;
	  case BINOCULAR:           /* both eye's data present: use left eye only*/
		eye_used = LEFT_EYE;
	  case LEFT_EYE:
		eyemsg_printf("EYE_USED 0 LEFT");
		break;
	}
								 
	/* Now get ready for trial loop*/
	eyelink_flush_keybuttons(0);   /* reset keys and buttons from tracker */

	/* 
		we don't use getkey() especially in a time-critical trial
		as Windows may interrupt us and cause an unpredicatable delay
		so we would use buttons or tracker keys only  
		Trial loop: till timeout or response -- added code for processing
		FIXUPDATE events
	*/
	while(1) 
	{ 
		/* First, check if recording aborted */
	  if((error=check_recording())!=0) return error;  
								 
	  /* Check if trial time limit expired*/
	  if(current_time() > trial_start+time_limit)
		{
			eyemsg_printf("TIMEOUT");    /* message to log the timeout */
			end_trial();                 /* local function to stop recording*/
			button = 0;                  /* trial result message is 0 if timeout */
			break;                       /* exit trial loop*/
		}

	  if(break_pressed())     /* check for program termination or ALT-F4 or CTRL-C keys*/
		{
			end_trial();         /* local function to stop recording*/
			return ABORT_EXPT;   /* return this code to terminate experiment*/
		}

	  /* check for local ESC key to abort trial (useful in debugging)   */
	  if(escape_pressed())    
		 {
			end_trial();         /* local function to stop recording*/
			return SKIP_TRIAL;   /* return this code if trial terminated*/
		 }

		/* BUTTON RESPONSE TEST */
		/* Check for eye-tracker buttons pressed
		/* This is the preferred way to get response data or end trials	*/
	  button = eyelink_last_button_press(NULL);
	  if(button!=0)       /* button number, or 0 if none pressed*/
		{
		  /* message to log the button press*/
			eyemsg_printf("ENDBUTTON %d", button);  
			/* local function to stop recording*/
			end_trial();                            
			break; /* exit trial loop*/
		}

		/* GET FIXUPDATE EVENTS, PROCESS*/

		i = eyelink_get_next_data(NULL);    /* Check for data from link*/
		if(i == FIXUPDATE)	  /* only process FIXUPDATE events*/
		{
			/* get a copy of the FIXUPDATE event */
			eyelink_get_float_data(&evt);  
			/* only process if it's from the desired eye?*/
			if(evt.fe.eye == eye_used)	   
			{   
				/* get average position and duration of the update */
				process_fixupdate((int)(evt.fe.gavx), (int)(evt.fe.gavy),/* Process event */
	       			 evt.fe.entime-evt.fe.sttime);
			}
		}
	}/* end of loop*/
	/* report response result: 0=timeout, else button number*/
	eyemsg_printf("TRIAL_RESULT %d", button);
		/* Call this at the end of the trial, to handle special conditions*/
	SDL_FreeSurface(gbm);
	segment_source = NULL;
	return check_record_exit();
}
         // Given trial number, execute trials
         // Returns trial result code
int do_gcwindow_trial(int num)
{
  int i;


   set_offline_mode();		     // Must be offline to draw to EyeLink screen

  switch(num)
    {            // #1: gaze-contingent text, normal in window, "xx" outside
      case 1:
	   // This supplies the title at the bottom of the eyetracker display 
        eyecmd_printf("record_status_message 'GC TEXT (WINDOW)' ");
	   // Always send a TRIALID message before starting to record. 
	   // It should contain trial condition data required for analysis.
        eyemsg_printf("TRIALID GCTXTW");
		
		// TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
		// It specifies the list of trial variables value for the trial 
		// This must be specified within the scope of an individual trial (i.e., after 
		// "TRIALID" and before "TRIAL_RESULT") 
		eyemsg_printf("!V TRIAL_VAR_DATA TEXT TEXT MASK");

		if(create_text_bitmaps())
          {
            eyemsg_printf("ERROR: could not create bitmap");
            return SKIP_TRIAL;
          }
		
		// IMGLOAD command is recorded for EyeLink Data Viewer analysis
		// It displays a default image on the overlay mode of the trial viewer screen. 
		// Writes the image filename + path info
		eyemsg_printf("!V IMGLOAD FILL images/text.png");	
		
		// Save the bitmap and transfer to the tracker pc
		// Since it takes a long time to save a bitmap to disk, the sv_options option 
		// should be set as SV_NOREPLACE
		bitmap_save_and_backdrop(fgbm, 0, 0, 0, 0,
                       "text.png", "images", SV_NOREPLACE,
			      0, 0, BX_NODITHER|BX_GRAYSCALE);
		
        i = gc_window_trial(fgbm, bgbm, SCRWIDTH/4, SCRHEIGHT/3, 0, 60000L);  // Gaze-contingent window, normal text
        DeleteObject(fgbm);
        DeleteObject(bgbm);
        return i;

      case 2:    // #2: gaze-contingent text, "xx" in window, normal outside
        eyecmd_printf("record_status_message 'GC TEXT (MASK)' ");
        eyemsg_printf("TRIALID GCTXTM");

		// TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
		// It specifies the list of trial variables value for the trial 
		// This must be specified within the scope of an individual trial (i.e., after 
		// "TRIALID" and before "TRIAL_RESULT") 
		eyemsg_printf("!V TRIAL_VAR_DATA TEXT MASK TEXT");
        if(create_text_bitmaps())
          {
            eyemsg_printf("ERROR: could not create bitmap");
            return SKIP_TRIAL;
          }

		// IMGLOAD command is recorded for EyeLink Data Viewer analysis
		// It displays a default image on the overlay mode of the trial viewer screen. 
		// Writes the image filename + path info
		eyemsg_printf("!V IMGLOAD FILL images/text.png");	
		
		// Save the bitmap and transfer to the tracker pc
		// Since it takes a long time to save a bitmap to disk, the sv_options option 
		// should be set as SV_NOREPLACE
		bitmap_save_and_backdrop(fgbm, 0, 0, 0, 0,
                       "text.png", "images", SV_NOREPLACE,
			      0, 0, BX_NODITHER|BX_GRAYSCALE);

        i = gc_window_trial(bgbm, fgbm, SCRWIDTH/4, SCRHEIGHT/3, 1, 60000L);  // Gaze-contingent window, masked text
        DeleteObject(fgbm);
        DeleteObject(bgbm);
        return i;

      case 3:    // #3: Image, normal in window, blank outside
        eyecmd_printf("record_status_message 'GC IMAGE (WINDOW)' ");
        eyemsg_printf("TRIALID GCTXTW");

		// TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
		// It specifies the list of trial variables value for the trial 
		// This must be specified within the scope of an individual trial (i.e., after 
		// "TRIALID" and before "TRIAL_RESULT") 		
		eyemsg_printf("!V TRIAL_VAR_DATA IMAGE IMAGE MASK");

        if(create_image_bitmaps(0))
          {
            eyemsg_printf("ERROR: could not create bitmap");
            return SKIP_TRIAL;
          }

		// IMGLOAD command is recorded for EyeLink Data Viewer analysis
		// It displays a default image on the overlay mode of the trial viewer screen. 
		// Writes the image filename + path info
		eyemsg_printf("!V IMGLOAD FILL images/sacrmeto.jpg");	

  
		// Transfer the bitmap to tracker PC as backdrop for gaze cursors
		bitmap_to_backdrop(fgbm, 0, 0, 0, 0,
			0, 0, (UINT16)(BX_MAXCONTRAST|((eyelink_get_tracker_version(NULL)>=2)?0:BX_GRAYSCALE)));
		
        i = gc_window_trial(fgbm, bgbm, SCRWIDTH/4, SCRHEIGHT/3, 0, 60000L);  // Gaze-contingent window, normal image
        DeleteObject(fgbm);
        DeleteObject(bgbm);
        return i;

      case 4:    // #4: Image, blank in window, normal outside
        eyecmd_printf("record_status_message 'GC IMAGE (MASK)' ");
        eyemsg_printf("TRIALID GCTXTM");

		// TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
		// It specifies the list of trial variables value for the trial 
		// This must be specified within the scope of an individual trial (i.e., after 
		// "TRIALID" and before "TRIAL_RESULT") 		
		eyemsg_printf("!V TRIAL_VAR_DATA IMAGE MASK IMAGE");

        if(create_image_bitmaps(1))
          {
            eyemsg_printf("ERROR: could not create bitmap");
            return SKIP_TRIAL;
          }

		// IMGLOAD command is recorded for EyeLink Data Viewer analysis
		// It displays a default image on the overlay mode of the trial viewer screen. 
		// Writes the image filename + path info
		eyemsg_printf("!V IMGLOAD FILL images/sacrmeto.jpg");	
		
		// Transfer the bitmap to tracker PC as backdrop for gaze cursors
		bitmap_to_backdrop(bgbm, 0, 0, 0, 0,
			0, 0, (UINT16)(BX_MAXCONTRAST|((eyelink_get_tracker_version(NULL)>=2)?0:BX_GRAYSCALE)));
		

        i = gc_window_trial(fgbm, bgbm, SCRWIDTH/4, SCRHEIGHT/3, 1, 60000L);  // Gaze-contingent window, masked image
        DeleteObject(fgbm);
        DeleteObject(bgbm);
        return i;

      case 5:    // #5: Image, blurred outside window
        eyecmd_printf("record_status_message 'GC IMAGE (BLURRED)' ");
        eyemsg_printf("TRIALID GCTXTB");

		// TRIAL_VAR_DATA message is recorded for EyeLink Data Viewer analysis
		// It specifies the list of trial variables value for the trial 
		// This must be specified within the scope of an individual trial (i.e., after 
		// "TRIALID" and before "TRIAL_RESULT") 		
		eyemsg_printf("!V TRIAL_VAR_DATA IMAGE IMAGE BLURRED");

        if(create_image_bitmaps(2))
          {
            eyemsg_printf("ERROR: could not create bitmap");
            return SKIP_TRIAL;
          }


		// IMGLOAD command is recorded for EyeLink Data Viewer analysis
		// It displays a default image on the overlay mode of the trial viewer screen. 
		// Writes the image filename + path info
		eyemsg_printf("!V IMGLOAD FILL images/sacrmeto.jpg");	
		
		// Transfer the bitmap to tracker PC as backdrop for gaze cursors
		bitmap_to_backdrop(fgbm, 0, 0, 0, 0,
			0, 0, (UINT16)(BX_MAXCONTRAST|((eyelink_get_tracker_version(NULL)>=2)?0:BX_GRAYSCALE)));
		
        i = gc_window_trial(fgbm, bgbm, SCRWIDTH/4, SCRHEIGHT/3, 0, 60000L);  // Gaze-contingent window, masked image
        DeleteObject(fgbm);
        DeleteObject(bgbm);
        return i;
    }
  return ABORT_EXPT;  // illegal trial number  
}
       // Draw text within margins, left-justified, with word-wrap.
       // Draw to <hdc> context, so it supports display and bitmaps   
       // (bitmap must already be created and selected into context).
       // Draw boxes for each word on EyeLink tracker display if <dotrack> set
       // Use font selected with get_new_font(), and draws it in <color>
       // RECT <margins> sets margins, and <lspace> sets pixels between lines
	   // Save the segmentation info into the text. 
	   // In the current implementation, the bottom edge of the line N overlaps with the 
	   // top edge of line N+1 and in each line, the left edge of word N overlaps with 
	   // the right edge of word N+1;  
	   // Extra space (twice the width of letter 'M') is added to the the first and 
       // last segments of each line 
void draw_text_box_segment(HDC hdc, char *txt, COLORREF color, 
		RECT margins, int lspace, int dotrack, char *filename)
{
  long x, y;				// drawing position
  int count_AI=0, j;		// count the total number of segments        
  char *sword, *eword, wholeword[200], previous_word[200];     // word start, end pointer, wholeword and prebious word
  int swx, ewx;				// word start, end position
  char *sispace, *c;		// text pointers
  int height ;				// height of characters
  int  end_line=0, previous_end_line=1, further_left, end_text=1;  // check whether it is end of a line  
  SIZE size, M_size;		// Size info (width and height of a rectangle)
  TEXTMETRIC tm;			// Text Metrics
  FILE *seg_file;			// handle to segment file
  RECT previous;			// Rect info for the previous segment


  further_left = margins.left;
  previous.left = margins.left;
  previous.right = margins.left;
  previous.top = margins.top;
  previous.bottom = margins.top;	// Initialization of the previous segment information;

  seg_file = fopen(filename, "wt");		// open segmentation file; overwritten if previous such file exists
  if(!seg_file) 
	eyemsg_printf("Error in opening the file to record segments");
  
  // REQUIRED FOR EVIEW
  if(dotrack) eyecmd_printf("clear_screen 0");	// clear eye tracker display
      
  GetTextExtentPoint32(hdc, "M", 1, &M_size);   // width of word                 
  SetBkMode(hdc, TRANSPARENT);        // set text color
  SetTextColor(hdc, color);
  SelectObject(hdc, current_font);    // Select cached font into context

  GetTextMetrics(hdc, &tm);           // Get height of characters
  height = tm.tmHeight;
  SetTextJustification(hdc, 0, 0) ;   // set normal text spacing
  SetTextAlign(hdc, TA_LEFT | TA_TOP);

  x = margins.left;                   // initial drawing position
  y = margins.top;  
  c = txt;                            // initial text to scan
	
  strcpy(previous_word, "");		 // Intialize strings 
  strcpy(wholeword, "");

  while(*c)   // loop through lines of text
    {
	  end_line=0;

nextword:                 // START NEW WORD:
      sispace = c;            // scan over any leading spaces
      while(*c==' ') c++;
      if(c!=sispace)          // advance over the spaces (if any)
        {
          GetTextExtentPoint32(hdc, sispace, c-sispace, &size);                    
          x += size.cx;
        }
	  
		if(*c==0)			// handle end-of-text 
			break;		
	
		 if(*c=='\n')        // handle end-of-line before word
        {
          c++;            // skip over end-of-line character
nextline: 
		  end_line=1;
// START NEW LINE:
          x = margins.left;                      // return to start of line
          y += lspace;                           // top of new  line
         
		  if(y+height > margins.bottom)			 // Exceeding the page limit
		  {  
			fprintf(seg_file, "RECTANGLE\t%d\t%d\t%d\t%d\t%d\t%s\n",
				count_AI, previous_end_line? (previous.left-2*M_size.cx):(previous.left+further_left)/2, 
				previous.top, end_line?(previous.right+2*M_size.cx):(previous.right+swx)/2, 
				previous.bottom, previous_word);
			
			end_text=0;						// Abnormal end of text	  
			break;  
		  }	  
			   // stop if it would go outside margins
          goto nextword;                         // continue to print
        }
      swx = x;            // continue in current line: 
      sword = c;          // record start of this word
      
	  j=0;
	  while(*c && !isspace(*c) && *c!='\n') 
	  {	  
		  wholeword[j]=*c;
		  j++;
		  c++;				// scan till end of word and copy the word
	  }  
	  wholeword[j]='\0';	// Zero terminate the string
		  
	if(sword==c) goto nextword;                 // no word: continue by skipping spaces

	  eword = c;                                  // record end of word
      GetTextExtentPoint32(hdc, sword, eword-sword, &size);   // width of word                 
      ewx = size.cx + swx;                        // position of end of word
      if(ewx > margins.right)    // would it extend past right margin?
        {
          c = sword;                   // restore text pointer
          goto nextline;               // start a new line with current word
        }
      TextOut(hdc, x, y, sword, eword-sword);      // Print the word
      if(dotrack)                                  // draw box on EyeLink display
          eyecmd_printf("draw_box %d %d %d %d 15", swx, y, ewx, y+height);

    // If it is the first segment in the text.
	if (count_AI==1)
		previous_end_line=1;				

	// General cases: Record the information regarding the last segment;
	if (count_AI>=1)
		fprintf(seg_file, "RECTANGLE\t%d\t%d\t%d\t%d\t%d\t%s\n",
			count_AI, previous_end_line? (previous.left-2*M_size.cx):(previous.left+further_left)/2, 
			previous.top, end_line?(previous.right+2*M_size.cx):(previous.right+swx)/2, 
			previous.bottom, previous_word);


	  further_left = previous.right;		    // The right border of the word before the previous word 
	  previous.left=swx;
	  previous.right=ewx;
	  previous.top=y-(lspace-height)/2;
	  previous.bottom=y+(height+lspace)/2;
	  strcpy(previous_word, wholeword);
	  previous_end_line=end_line;				// Record information regarding the last segment

	  x = ewx;                                  // update current printing location
	  count_AI++;												
 }

  // Normal ending of the text: record the current segment info
  if (end_text)
	fprintf(seg_file, "RECTANGLE\t%d\t%d\t%d\t%d\t%d\t%s\n",
		count_AI, previous_end_line? (previous.left-2*M_size.cx):(swx+further_left)/2, y-(lspace-height)/2, 
		ewx+2*M_size.cx, y+(height+lspace)/2, wholeword);

  GdiFlush();     // ADDED for Wimdows 2000/XP: Forces drawing to be immediate      

  SelectObject(hdc, GetStockObject(SYSTEM_FONT));  // deselect the font
  fclose(seg_file);
}
// ######################################################################
void EyeTrackerEyeLink::start1()
{
#ifndef HAVE_EYELINK
  LFATAL("Proprietary EyeLink developer API not installed");
#else
  // get the link to the eye-tracker going:
  if (open_eyelink_connection(0))
    LFATAL("Cannot open link to EyeLink tracker - make sure your "
           "hostname resolves to 100.1.1.2 (check /etc/hosts)");

  // Basic initializations:
  set_offline_mode();
  flush_getkey_queue();/* initialize getkey() system */

  // Open EyeLink version of SDL
  openSDL();

  // set the display characteristics: 
  DISPLAYINFO di; // defined in eyelink/core_expt.h
  di.width = itsDims.getVal().w(); di.height = itsDims.getVal().h();
  di.left = 0; di.top = 0; di.right = di.width-1; di.bottom = di.height-1;
  di.bits = 24; di.palsize = 0; di.pages = 0; di.refresh = 60.0F;
  di.winnt = 0;

  set_calibration_colors(&target_foreground_color, &target_background_color);

	// open EDF file if set:
  if (itsEDFfname.getVal().empty() == false)
    {
      if (open_data_file((char *)(itsEDFfname.getVal().c_str())) != 0)
        LFATAL("Cannot open EDF file '%s'", itsEDFfname.getVal().c_str());

      eyecmd_printf(const_cast<char*>("add_file_preamble_text 'RECORDED BY iLab code' "));
    }

  // Add resolution to EDF file:
  eyemsg_printf(const_cast<char*>("DISPLAY_COORDS %ld %ld %ld %ld"),
                di.left, di.top, di.right, di.bottom);

  /* SET UP TRACKER CONFIGURATION */
  /* set parser saccade thresholds (conservative settings) */
  /* 0 = standard sensitivity */
  eyecmd_printf(const_cast<char*>("select_parser_configuration 0"));

  // set EDF file contents:
  eyecmd_printf(const_cast<char*>("file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,"
                                  "BLINK,MESSAGE,BUTTON"));
  eyecmd_printf(const_cast<char*>("file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS"));

  // set link data (used for gaze cursor):
  eyecmd_printf(const_cast<char*>("link_event_filter = LEFT,RIGHT,FIXATION,FIXUPDATE,SACCADE,BLINK,BUTTON"));
  eyecmd_printf(const_cast<char*>("link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS"));

  // Program button #5 for use in drift correction:
  eyecmd_printf(const_cast<char*>("button_function 5 'accept_target_fixation'"));
  
	// setup eyelink filtering: default is "1 2"
	eyecmd_printf(const_cast<char*>("heuristic_filter = 1 2"));
	eyelink_wait_for_mode_ready(500);

  // make sure we're still alive:
  if (!eyelink_is_connected() || break_pressed())
    LFATAL("Connection to EyeLink broken or aborted");

  /* TRIAL_VAR_LABELS message is recorded for EyeLink Data Viewer analysis
     It specifies the list of trial variables for the trial
     This should be written once only and put before the recording of
     individual trials */
  eyemsg_printf(const_cast<char*>("TRIAL_VAR_LABELS CONDITION"));

  // Configure EyeLink to send fixation updates every 50 msec:
  //eyecmd_printf("link_event_filter = LEFT,RIGHT,FIXUPDATE");
  //eyecmd_printf("fixation_update_interval = 50");
  //eyecmd_printf("fixation_update_accumulate = 50");

  EyeTracker::start1();
#endif
}
       // Draw text within margins, left-justified, with word-wrap.
       // Draw to <hdc> context, so it supports display and bitmaps   
       // (bitmap must already be created and selected into context).
       // Draw boxes for each word on EyeLink tracker display if <dotrack> set
       // Use font selected with get_new_font(), and draws it in <color>
       // RECT <margins> sets margins, and <lspace> sets pixels between lines
void draw_text_box(HDC hdc, char *txt, COLORREF color, RECT margins, int lspace, int dotrack)
{
  short x, y;              // drawing position
  char *sword, *eword;     // word start, end pointer
  int swx, ewx;            // word start, end position
  char *sispace, *c;       // text pointers
  int height;              // height of characters
  SIZE size;
  TEXTMETRIC tm;

  if(dotrack) eyecmd_printf("clear_screen 0");	// clear eye tracker display

  SetBkMode(hdc, TRANSPARENT);        // set text color
  SetTextColor(hdc, color);
  SelectObject(hdc, current_font);    // Select cached font into context

  GetTextMetrics(hdc, &tm);           // Get height of characters
  height = tm.tmHeight;
  SetTextJustification(hdc, 0, 0) ;   // set normal text spacing
  SetTextAlign(hdc, TA_LEFT | TA_TOP);

  x = (short)margins.left;                   // initial drawing position
  y = (short)margins.top;  
  c = txt;                            // initial text to scan

  while(*c)   // loop through lines of text
    {
nextword:                 // START NEW WORD:
      sispace = c;            // scan over any leading spaces
      while(*c==' ') c++;
      if(c!=sispace)          // advance over the spaces (if any)
        {
          GetTextExtentPoint32(hdc, sispace, c-sispace, &size);                    
          x += (short)size.cx;
        }
      if(*c==0) break;    // handle end-of-text 
      if(*c=='\n')        // handle end-of-line before word
        {
          c++;            // skip over end-of-line character
nextline:                        // START NEW LINE:
          x = (short)margins.left;                      // return to start of line
          y += lspace;                           // top of new  line
          if(y+height > margins.bottom) break;  // stop if it would go outside margins
          goto nextword;                         // continue to print
        }
      swx = x;            // continue in current line: 
      sword = c;                                  // record start of this word
      while(*c && !isspace(*c) && *c!='\n') c++;  // scan till end of word
      if(sword==c) goto nextword;                 // no word: continue by skipping spaces
      eword = c;                                  // record end of word
      GetTextExtentPoint32(hdc, sword, eword-sword, &size);   // width of word                 
      ewx = size.cx + swx;                        // position of end of word
      if(ewx > margins.right)    // would it extend past right margin?
        {
          c = sword;                   // restore text pointer
          goto nextline;               // start a new line with current word
        }
      TextOut(hdc, x, y, sword, eword-sword);      // Print the word
      if(dotrack)                                  // draw box on EyeLink display
          eyecmd_printf("draw_box %d %d %d %d 15", swx, y, ewx, y+height);
      x = ewx;                                     // update current printing location
    }

  GdiFlush();     // ADDED for Wimdows 2000/XP: Forces drawing to be immediate      

  SelectObject(hdc, GetStockObject(SYSTEM_FONT));  // deselect the font
}
bool Eyelink::initialize(){
	
    boost::mutex::scoped_lock lock(EyelinkDriverLock);
	
	if (Eyelink_Initialized) {
        merror(M_IODEVICE_MESSAGE_DOMAIN,"Eyelink was previously initialized! Trying again, but this is dangerous!!");
    }
	
    Eyelink_Initialized = false;
    
	// Initializes the link
	//mprintf(M_IODEVICE_MESSAGE_DOMAIN, "Trying to find Eyelink System at %s",tracker_ip);
	if (set_eyelink_address( &tracker_ip[0] ) )
	    merror(M_IODEVICE_MESSAGE_DOMAIN,"Failed to set Tracker to address %s", tracker_ip.c_str());
	
	if(open_eyelink_connection(0))
	    merror(M_IODEVICE_MESSAGE_DOMAIN,"Failed to connect to Tracker at %s", tracker_ip.c_str());
	else {
		ELINKNODE node;
        
        // generate data file name
        time_t now = time(NULL);
        struct tm* t = gmtime(&now);
        
        sprintf(data_file_name, "%02d%06d.edf",(t->tm_year-100),t->tm_yday*1440 + t->tm_hour*60 + t->tm_min);
        //YYMMMMMM : YY=Years since 2k, MMMMMM=Minutes in current year
        
        if ( open_data_file( data_file_name ) ) {
            mwarning(M_IODEVICE_MESSAGE_DOMAIN,"Eyelink datafile setting failed (%s)",data_file_name);
        }
        else {
            mprintf(M_IODEVICE_MESSAGE_DOMAIN,"Eyelink logs to local file %s",data_file_name);
        }
        
        // Tell the tracker what data to include in samples
        if (OK_RESULT != eyecmd_printf("link_sample_data = LEFT,RIGHT,GAZE,HREF,PUPIL,AREA")) {
            mwarning(M_IODEVICE_MESSAGE_DOMAIN,
                     "Eyelink did not respond to link_sample_data command; sample data may be incomplete");
        }
		
		// tell the tracker who we are
		eyelink_set_name((char*)("MWorks_over_Socket"));
		
		// verify the name
		if( eyelink_get_node(0,&node) != OK_RESULT )
			merror(M_IODEVICE_MESSAGE_DOMAIN,"Error, EyeLink doesn't respond");
		else eyemsg_printf((char*)("%s connected"), node.name);
		
		// Enable link data reception
		eyelink_reset_data(1);
	}
	
	// Eyelink should now be in "TCP-Link Open" mode
	
	if(eyelink_is_connected()) {
		
		tracker_version = eyelink_get_tracker_version(version_info);
		mprintf(M_IODEVICE_MESSAGE_DOMAIN, "Eyelink %d System Version %s connected via Socket",tracker_version,version_info);
		
		Eyelink_Initialized = true;
        stopped = true;
	}
	else {
		merror(M_IODEVICE_MESSAGE_DOMAIN,"Error, Eyelink Connection could not be established");
	}
	
	return Eyelink_Initialized;
}
Exemple #18
0
int app_main(char * trackerip, DISPLAYINFO * disp)
{
  UINT16 i, j;
  char our_file_name[260] = "TEST";
  char verstr[50];
  int eyelink_ver = 0;
  int tracker_software_ver = 0;
  
  if(trackerip)
		set_eyelink_address(trackerip);
  if(open_eyelink_connection(0)) return -1;    /* abort if we can't open link */
  set_offline_mode();
  flush_getkey_queue();                        /* initialize getkey() system */

  eyelink_ver = eyelink_get_tracker_version(verstr);
  if (eyelink_ver == 3)
	  tracker_software_ver = get_tracker_sw_version(verstr);



  if(init_expt_graphics(NULL, disp))
	  goto shutdown;   /* register window with EXPTSPPT */


  window = SDL_GetVideoSurface();
  get_display_information(&dispinfo);          /* get window size, characteristics */

    /*
		NOTE: Camera display does not support 16-color modes
		NOTE: Picture display examples don't work well with 256-color modes
		However, all other sample programs should work well.
	*/

  if(dispinfo.palsize)     /* 256-color modes: palettes not supported by this example */
      alert_printf("This program is not optimized for 256-color displays");


 

  
  i = SCRWIDTH/60;		  /* select best size for calibration target */
  j = SCRWIDTH/300;       /* and focal spot in target */
  if(j < 2) j = 2;
  set_target_size(i, j);  /* tell DLL the size of target features */


  /* color of calibration target */
  SETCOLOR(target_foreground_color, 0,0,0);
  /* background for calibration and drift correction */
  SETCOLOR(target_background_color, 128,128,128);
  /* tell EXPTSPPT the colors */
  set_calibration_colors(&target_foreground_color, &target_background_color);

  set_cal_sounds("", "", "");
  set_dcorr_sounds("", "off", "off");

  /* draw a title screen */
  clear_full_screen_window(target_background_color);    /* clear screen */
  get_new_font("Times Roman", SCRHEIGHT/32, 1);         /* select a font */
                                                        /* Draw text */
  graphic_printf(window, target_foreground_color,  CENTER, SCRWIDTH/2, 1*SCRHEIGHT/30,
                 "EyeLink Demonstration Experiment: Communicate with Listener");
  graphic_printf(window, target_foreground_color,  CENTER, SCRWIDTH/2, 2*SCRHEIGHT/30,
                 "Included with the Experiment Programming Kit for Windows");
  graphic_printf(window, target_foreground_color,  CENTER, SCRWIDTH/2, 3*SCRHEIGHT/30,
                 "All code is Copyright (c) 1997-2002 SR Research Ltd.");
  graphic_printf(window, target_foreground_color,  CENTER, SCRWIDTH/5, 4*SCRHEIGHT/30,
                 "Source code may be used as template for your experiments.");
  SDL_Flip(window);

  eyelink_set_name("comm_simple");  /* NEW: set our network name */

  if(check_for_listener())   /* check for COMM_LISTENER application */
    {
      alert_printf("Could not communicate with COMM_LISTENER application.");
      goto shutdown;
    }

  if(i==1)  our_file_name[0] = 0;   /* Cancelled: No file name */
  if(our_file_name[0])    /* If file name set, open it */
    {
      if(!strstr(our_file_name, ".")) strcat(our_file_name, ".EDF");  /* add extension   */
      i = open_data_file(our_file_name);                              /* open file       */
      if(i!=0)                                                        /* check for error */
        {
          alert_printf("Cannot create EDF file '%s'", our_file_name);
          goto shutdown;
        }
	  /* add title to preamble */
      eyecmd_printf("add_file_preamble_text 'RECORDED BY %s' ", program_name);
    }
  /*
		SET UP TRACKER CONFIGURATION
		NOTE: set contents before sending messages!
		set EDF file contents
  */
   if(eyelink_ver>=2)
    {
      eyecmd_printf("select_parser_configuration 0");  // 0 = standard sensitivity
	  if(eyelink_ver == 2) //turn off scenelink camera stuff
	  {
		eyecmd_printf("scene_camera_gazemap = NO");
	  }
    }
  else
    {
      eyecmd_printf("saccade_velocity_threshold = 35");
      eyecmd_printf("saccade_acceleration_threshold = 9500");
    }
  // NOTE: set contents before sending messages!
		     // set EDF file contents 
  eyecmd_printf("file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON");
  eyecmd_printf("file_sample_data  = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS%s",(tracker_software_ver>=4)?",HTARGET":"");
		      // set link data (used for gaze cursor) 
  eyecmd_printf("link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON");
  eyecmd_printf("link_sample_data  = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS%s",(tracker_software_ver>=4)?",HTARGET":"");

  /* NEW: Allow EyeLink I (v2.1+) to echo messages back to listener */
  eyecmd_printf("link_nonrecord_events = BUTTONS, MESSAGES");

  /* Program button #5 for use in drift correction */
  eyecmd_printf("button_function 5 'accept_target_fixation'");

  /* Now configure tracker for display resolution */
  eyecmd_printf("screen_pixel_coords = %ld %ld %ld %ld",    /* Set display resolution */
                 dispinfo.left, dispinfo.top, dispinfo.right, dispinfo.bottom);
  eyecmd_printf("calibration_type = HV9");       /* Setup calibration type */
  eyemsg_printf("DISPLAY_COORDS %ld %ld %ld %ld",/* Add resolution to EDF file */
                 dispinfo.left, dispinfo.top, dispinfo.right, dispinfo.bottom);
  if(dispinfo.refresh>40)
    eyemsg_printf("FRAMERATE %1.2f Hz.", dispinfo.refresh);

  

  /* make sure we're still alive */
  if(!eyelink_is_connected() || break_pressed()) goto end_expt;

  /*
	 RUN THE EXPERIMENTAL TRIALS (code depends on type of experiment)
     Calling run_trials() performs a calibration followed by trials
     This is equivalent to one block of an experiment
     It will return ABORT_EXPT if the program should exit
   */
  i = run_trials();

end_expt:                /* END: close, transfer EDF file */
  set_offline_mode();    /* set offline mode so we can transfer file */
  pump_delay(500);       /* delay so tracker is ready */
  eyecmd_printf("close_data_file"); /* close data file */

  if(break_pressed()) goto shutdown;/* don't get file if we aborted experiment */
  if(our_file_name[0])              /* make sure we created a file */
    receive_data_file(our_file_name, "", 0);  /* transfer the file, ask for a local name */

shutdown:                /* CLEANUP */
  close_expt_graphics();           /* tell EXPTSPPT to release window */
  close_eyelink_connection();      /* disconnect from tracker */
  return 0;
}
PsychError EyelinkCommand(void)
{
	int					i				= 0;
	int					iNumInArgs		= 0;
	int					iStatus			= -1;
	PsychArgFormatType	psychArgType	= PsychArgType_none;
	double				fTempValue		= 0.0;
	char				*pstrTemp		= NULL;
	char				*pstrFormat		= NULL;
	void				**pArgs			= NULL;
	char				strCommand[256];
	
	// Clear strings
	memset(strCommand, 0, sizeof(strCommand));

	// Add help strings
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	
	// Output help if asked
	if(PsychIsGiveHelp()) {
		PsychGiveHelp();
		return(PsychError_none);
	}

	// Check arguments
	PsychErrorExit(PsychRequireNumInputArgs(1));
//	PsychErrorExit(PsychCapNumOutputArgs(0));
	PsychErrorExit(PsychCapNumOutputArgs(1));
	
	// Verify eyelink is up and running
	EyelinkSystemIsConnected();
	EyelinkSystemIsInitialized();

	// Alloc and grab the input format string
	PsychAllocInCharArg(1, TRUE, &pstrFormat);
	iNumInArgs = PsychGetNumInputArgs();   

	// Alloc and grab input args
	if (iNumInArgs > 1) {
		pArgs = (void **)mxMalloc((iNumInArgs-1) * sizeof(char *));
		// loop over the args
		for (i = 2; i <= iNumInArgs; i++) {
			psychArgType = PsychGetArgType(i);
			switch(psychArgType) {
				case PsychArgType_double:
					if ((PsychGetArgM(i) == 1) && (PsychGetArgN(i) == 1)) {
						PsychCopyInDoubleArg(i, TRUE, &fTempValue);
						pArgs[i-2] = (void *) (int) fTempValue; 
					} else {
						PsychGiveHelp();
						return(PsychError_user);
					}
					break;
				case PsychArgType_char:
					pArgs[i-2] = NULL;
					PsychAllocInCharArg(i, TRUE, &pstrTemp);
					pArgs[i-2] = pstrTemp;
					break;
				default:
					PsychGiveHelp();
					return(PsychError_user);
					break;
			} 
		}
	}
	
	// Build eyelink command and execute
	vsprintf(strCommand, pstrFormat, (va_list)pArgs);
	iStatus = eyecmd_printf(strCommand);
	if (pArgs != NULL) {
		mxFree(pArgs);
	}
	
	// Copy out the command result
	PsychCopyOutDoubleArg(1, FALSE, iStatus);
   
	return(PsychError_none);
}