File: EyelinkInitialize.c

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (299 lines) | stat: -rw-r--r-- 9,540 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
 
	PsychSourceGL/Source/Common/Eyelink/EyelinkInitialize.c
 
	PROJECTS: Eyelink 
 
	AUTHORS:
	 cburns@berkeley.edu			cdb
	 E.Peters@ai.rug.nl				emp
	 f.w.cornelissen@med.rug.nl		fwc
 
	PLATFORMS:	All.
 
	HISTORY:
 
	 11/23/05  cdb		Created.
	 28/06/06	fwc		added EyelinkInitializeDummy function. Unlike in the OS9 version, 
						I decided to make it a seperate function rather than option in EyelinkInitialize.
						Eyelink manual actually seems to advice to use eyelink_open_connection()
						rather than the way we do it now.
	 29/06/06	fwc		fixed EyelinkInitializeDummy (didn't set giSystemInitialized)
	 30-10-06	fwc		no longer use PsychErrorExitMsg to report error, otherwise we cannot connect in dummy mode later on
	 4-4-09     mk+edf  added registration of callback
 
	TARGET LOCATION:
 
	 Eyelink.mexmac resides in:
	 PsychHardware/EyelinkToolbox/EyelinkBasic
 
	NOTES:
	 This is a scaled down version compared to the OS9 version that Enno and Frans wrote.
	 I hardcode in the buffersize and ignore other params.

*/

#include "PsychEyelink.h"

char useString[] = "[status =] Eyelink('Initialize' [, displayCallbackFunction])";
char useDummyString[] = "[status =] Eyelink('InitializeDummy' [, displayCallbackFunction])";
char useTestString[] = "Eyelink('TestSuite')";

static char synopsisString[] = 
"Initializes Eyelink and Ethernet system.\n"
"Opens tracker connection, reports any problems.\n"
"The optional argument 'displayCallbackFunction' registers the name "
"of an m-file on the path that will handle callbacks from eyelink "
"(typically 'PsychEyelinkDispatchCallback' to display the camera "
"image in PTB). No callbacks will be generated if that argument "
"is omitted.\n"
"Returns: 0 if OK, -1 if error";

static char synopsisDummyString[] = 
"Initializes Eyelink in dummy mode, useful for debugging\n"
"The optional argument 'displayCallbackFunction' registers the name "
"of an m-file on the path that will handle callbacks from eyelink "
"(typically 'PsychEyelinkDispatchCallback' to display the camera "
"image in PTB). No callbacks will be generated if that argument "
"is omitted.\n"
"Returns: 0 if OK, -1 if error";

static char synopsisTestString[] = 
"Perform test routines, e.g., display of synthetic test image, "
"exercising the callback functions.\n";

static char seeAlsoString[] = "";

#define ERR_BUFF_LEN 1000

// Check if optional callback passed, and if so, if it is valid.
// If passed and valid, enable callbacks:
void CheckAndAssignCallback(int argpos)
{
	char    errMsg[ERR_BUFF_LEN];
	char*   callbackString;
	PsychGenericScriptType	*input[1];
	PsychGenericScriptType	*output[1];
	
	// Initialize graphics callbacks for eye camera et al.:
	if (PsychAllocInCharArg(argpos, FALSE, &callbackString) && strlen(callbackString) > 0) {
		// Callback string passed. Check if it corresponds to a valid function on
		// Matlab's path:
		input[0] = mxCreateString(callbackString);
		output[0]=NULL;

		// mexCallMatlab should be safe here, as not called from within eyelink callbacks:
		if(mexCallMATLAB(1, output, 1, input, "exist")) {
			mxDestroyArray(input[0]);
			PsychErrorExitMsg(PsychError_system, "Fatal error calling runtime's 'exist' function!");
		}

		mxDestroyArray(input[0]);
		
		if(mxGetScalar(output[0]) <= 0) {
			mxDestroyArray(output[0]);
			snprintf(errMsg, ERR_BUFF_LEN, "Eyelink: The provided callback function '%s' is not a defined function, MEX file or M-File on your path as required!", callbackString);
			PsychErrorExitMsg(PsychError_user, errMsg);
		}

		mxDestroyArray(output[0]);
		
		// Everything good: Initialize callbacks and enable them:
		PsychEyelink_init_core_graphics(callbackString);
	}
	else {
		// No callback passed: Disable use of callbacks:
		PsychEyelink_uninit_core_graphics();
    }
	
	return;
}

PsychError EyelinkInitialize(void)
{
	int		iBufferSize = 20000; // Hardcode default
	int		iStatus		= -1;
	
	// Add help strings
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	
	// Output help if asked
	if(PsychIsGiveHelp()) {
		PsychGiveHelp();
		return(PsychError_none);
	}
	
	// Check arguments
	PsychErrorExit(PsychCapNumInputArgs(1));
	PsychErrorExit(PsychRequireNumInputArgs(0));
	PsychErrorExit(PsychCapNumOutputArgs(1));
	
	if(giSystemInitialized == 1) {
		// Is there a psych function for this?
		mexPrintf("Eyelink already initialized!\n");
		iStatus = 0;
	} else {
		
		iStatus = (int) open_eyelink_system((UINT16) iBufferSize, NULL);
        
		// If library is properly initialized, open connection:
		if(iStatus != 0) {
			msec_delay(300);
			iStatus = eyelink_open();
		}
        else {
            // Failed to open eyelink runtime library:
            PsychErrorExitMsg(PsychError_system, "Eyelink: Initialize: Failed to initialize eyelink runtime library! open_eyelink_system() failed.");
        }
		
		// Check for errors and report
		if(iStatus != 0) {
			close_eyelink_system();
			if(iStatus == CONNECT_TIMEOUT_FAILED) {
			//	PsychErrorExitMsg(PsychError_user, "EyeLink: Initialize:  Cannot connect to EyeLink\n");
				mexPrintf("EyeLink: Initialize:  Cannot connect to EyeLink\n");
			} else if(iStatus == WRONG_LINK_VERSION) {
			//	PsychErrorExitMsg(PsychError_user, "EyeLink: Initialize:  Link version mismatch to EyeLink tracker\n");
				mexPrintf( "EyeLink: Initialize:  Link version mismatch to EyeLink tracker\n");
			} else if(iStatus == LINK_INITIALIZE_FAILED) {
			//	PsychErrorExitMsg(PsychError_user, "EyeLink: Initialize:  Cannot initialize link\n");
				mexPrintf( "EyeLink: Initialize:  Cannot initialize link\n");
			}
		} else {
			giSystemInitialized = 1;
		}
	}

	// Check for optional callbackString as argument 1, sanity check and enable callbacks, if provided:
	CheckAndAssignCallback(1);

	// Copy output arg
	PsychCopyOutDoubleArg(1, FALSE, iStatus);
	
	return(PsychError_none);
	
}


PsychError EyelinkInitializeDummy(void)
{
	int		iStatus		= -1;
	
	// Add help strings
	PsychPushHelp(useDummyString, synopsisDummyString, seeAlsoString);
	
	// Output help if asked
	if(PsychIsGiveHelp()) {
		PsychGiveHelp();
		return(PsychError_none);
	}
	
	// Check arguments
	PsychErrorExit(PsychCapNumInputArgs(1));
	PsychErrorExit(PsychRequireNumInputArgs(0));
	PsychErrorExit(PsychCapNumOutputArgs(1));
	
	if(giSystemInitialized == 1) {
		// Is there a psych function for this?
		mexPrintf("Eyelink already initialized!\n");
		iStatus = 0;
	} else {
		
		mexPrintf("Eyelink: Opening Eyelink in DUMMY mode\n");

		#if PSYCH_SYSTEM == PSYCH_WINDOWS
			// Need to open an eyelink connection on Windows, otherwise the beast will crash!
			iStatus = (int) open_eyelink_connection(-1);
			if (iStatus == 0) iStatus = (int) eyelink_dummy_open();
		#else
			iStatus = (int) eyelink_dummy_open();
		#endif

		// Check for errors and report
		if(iStatus != 0) {
			close_eyelink_system();
			if(iStatus == CONNECT_TIMEOUT_FAILED) {
				PsychErrorExitMsg(PsychError_user, "EyeLink: InitializeDummy:  Cannot connect to EyeLink\n");
			} else if(iStatus == WRONG_LINK_VERSION) {
				PsychErrorExitMsg(PsychError_user, "EyeLink: InitializeDummy:  Link version mismatch to EyeLink tracker\n");
			} else if(iStatus == LINK_INITIALIZE_FAILED) {
				PsychErrorExitMsg(PsychError_user, "EyeLink: InitializeDummy:  Cannot initialize link\n");
			}
		} else {
			giSystemInitialized = 1;
		}				
	}

	// Check for optional callbackString as argument 1, sanity check and enable callbacks, if provided:
	CheckAndAssignCallback(1);
	
	// Copy output arg
	PsychCopyOutDoubleArg(1, FALSE, iStatus);

	return(PsychError_none);	
}

PsychError EyelinkTestSuite(void)
{
	// Add help strings
	PsychPushHelp(useTestString, synopsisTestString, seeAlsoString);
	
	// Output help if asked
	if(PsychIsGiveHelp()) {
		PsychGiveHelp();
		return(PsychError_none);
	}
	
	// Check arguments
	PsychErrorExit(PsychCapNumInputArgs(0));
	PsychErrorExit(PsychRequireNumInputArgs(0));
	PsychErrorExit(PsychCapNumOutputArgs(0));
	
	// Execute internal tests:
	PsychEyelink_TestEyeImage();
	
	return(PsychError_none);	
}

PsychError EyelinkSetAddress(void)
{
    static char useAddressString[] = "[status =] Eyelink('SetAddress', ipaddress);";
    static char synopsisAddressString[] =
    "Set IP address of eyelink tracker computer to connect to.\n"
    "Call this before opening a tracker connection if you want to use "
    "a non-default IP address for the tracker computer.\n"
    "'ipaddress' is a character string containing the tracker address.\n"
    "Returns: 0 if OK, -1 on error\n";
    static char seeAlsoAddressString[] = "Initialize";
    
    char* ipAddress;
    int	iStatus = -1;
    
    // Add help strings:
    PsychPushHelp(useAddressString, synopsisAddressString, seeAlsoAddressString);
    
    // Output help if asked:
    if (PsychIsGiveHelp()) {
        PsychGiveHelp();
        return(PsychError_none);
    }
    
    // Check arguments:
    PsychErrorExit(PsychCapNumInputArgs(1));
    PsychErrorExit(PsychRequireNumInputArgs(1));
    PsychErrorExit(PsychCapNumOutputArgs(1));
    
    // Must call this function before opening a tracker connection:
    if (giSystemInitialized == 1) PsychErrorExitMsg(PsychError_user, "Tried to set target tracker host ip address, but connection already initialized!");
    
    // Get mandatory string with IP address spec:
    PsychAllocInCharArg(1, kPsychArgRequired, &ipAddress);
    
    // Assign new address:
    iStatus = set_eyelink_address(ipAddress);
    
    // Copy out status:
    PsychCopyOutDoubleArg(1, kPsychArgOptional, iStatus);
    
    return(PsychError_none);
}