This is example 17. This example demonstrates the following:

  1. Processing online saccade events

This example is based on example 10. This example adds an onSaccadeEvent() event handler function to print saccade start and end events.

Source code

Source file: example17.c

Initialization

In the eyevec_create_thread() function in the initialization part we provide a saccade event callback function.

int main(void)
{
    .
    .

    EyeVecResult err = eyevec_create_thread(eyevec,
        onModeChange,
        NULL,   // onDisplayData,
        NULL,   // onEyeData,
        NULL,   // onBlinkEvent,
        onSaccadeEvent, (1)
        NULL,   // onFixationEvent,
        NULL,   // onTestItemEvent,
        &clientdata);
    printError("eyevec_create_thread()", err);
    if (err) return EXIT_FAILURE;

    .
    .
1 Callback function for saccade start and end events.

processInput()

onSaccadeEvent()

In the onSaccadeEvent() event handler function we call onSaccadeStart() or onSaccadeEnd() depending on the flag parameter provided to the onSaccadeEvent() function.

static int onSaccadeEvent(const EyeVec* eyevec, int64_t eventtime,
    const EyeVecSaccadeEventData* saccadedata, int flag, void* cldata)
{
    const ClientData* clientdata = (const ClientData*)cldata;
    if (clientdata == NULL) return 0;

    if (flag == 0)
        return onSaccadeStart(eyevec, eventtime, saccadedata, clientdata); (1)

    return onSaccadeEnd(eyevec, eventtime, saccadedata, clientdata); (2)
}
1 Call onSaccadeStart() with provided saccade data.
2 Call onSaccadeEnd() with provided saccade data.

onSaccadeStart()

This function prints the relevant EyeVecSaccadeEventData attributes defined for the saccade start event.

static int onSaccadeStart(const EyeVec* eyevec, int64_t eventtime,
    const EyeVecSaccadeEventData* saccadedata, const ClientData* clientdata)
{
    (void)eyevec;

    if (clientdata->showgazeevents) {
        printf("onSaccadeStart:\n");
        printf("    eventtime:                  %" PRId64 "\n",
            eventtime);
        printf("    side:                       %s\n",
            side_string(saccadedata->side));
        printf("    starttime:                  %" PRId64 "\n",
            saccadedata->starttime);
        printf("    gaze_start:                 %.3f, %.3f\n",
            (double)saccadedata->gaze_start.x,
            (double)saccadedata->gaze_start.y);
        printf("    pupil_start:                %.3f\n",
            (double)saccadedata->pupil_start);
    }

    return 0;
}

onSaccadeEnd()

This function prints the relevant EyeVecSaccadeEventData attributes defined for the saccade end event.

static int onSaccadeEnd(const EyeVec* eyevec, int64_t eventtime,
    const EyeVecSaccadeEventData* saccadedata, const ClientData* clientdata)
{
    (void)eyevec;

    if (clientdata->showgazeevents) {
        printf("onSaccadeEnd:\n");
        printf("    eventtime:                  %" PRId64 "\n",
            eventtime);
        printf("    side:                       %s\n",
            side_string(saccadedata->side));
        printf("    starttime:                  %" PRId64 "\n",
            saccadedata->starttime);
        if (saccadedata->endtime >= 0) {
            printf("    duration:                   %d\n",
                (int)(saccadedata->endtime - saccadedata->starttime));
        }
        printf("    gaze_end:                   %.3f, %.3f\n",
            (double)saccadedata->gaze_end.x,
            (double)saccadedata->gaze_end.y);
        printf("    pupil_end:                  %.3f\n",
            (double)saccadedata->pupil_end);
        printf("    gaze_avg:                   %.3f, %.3f\n",
            (double)saccadedata->gaze_avg.x,
            (double)saccadedata->gaze_avg.y);
        printf("    pupil_avg:                  %.3f\n",
            (double)saccadedata->pupil_avg);
    }

    return 0;
}

Running

After a succesful build run the program:

  1. Press o to call eyevec_open(). Eye-tracker should go from off mode to idle mode.

  2. Press z to call eyevec_enter_data_mode(). Eye-tracker should go from idle mode to data mode. Note, we’re skipping setup and calibration here; still make sure the eye-tracker can see your eyes.

  3. Press g to call eyevec_set_gaze_event_enabled(0, EYEVEC_ENABLE_SEND_WHILE_IN_RECORDING_MODE).

  4. Press r to call eyevec_start_recording(). Eye-tracker should go from data mode to recording mode. Saccade events should be printed.

  5. Press r to call eyevec_stop_recording(). Eye-tracker should go from recording mode to data mode. No more saccade events will be printed.

  6. Press q to quit.

Output might look like this (empty lines added for clarity):

eyevec_create_thread(): OK
eyevec_initialize(): OK
Type q to quit, ? for help.

[o]
onModeChange:
    eventtime:                  1750691913324342
    oldmode:                    TRACKER_MODE_OFF
    newmode:                    TRACKER_MODE_IDLE
eyevec_open(): OK

[z]
onModeChange:
    eventtime:                  1750691914693985
    oldmode:                    TRACKER_MODE_IDLE
    newmode:                    TRACKER_MODE_DATA
eyevec_enter_data_mode(): OK

[g]
eyevec_set_gaze_event_enabled(0, 0x1): OK

[r]
onModeChange:
    eventtime:                  1750691946585808
    oldmode:                    TRACKER_MODE_DATA
    newmode:                    TRACKER_MODE_RECORDING
eyevec_start_recording(): OK

onSaccadeStart:
    eventtime:                  1750691946818243
    side:                       LEFT
    starttime:                  1750691946818243
    gaze_start:                 0.354, 0.472
    pupil_start:                4.269
onSaccadeStart:
    eventtime:                  1750691946820244
    side:                       RIGHT
    starttime:                  1750691946820244
    gaze_start:                 0.348, 0.465
    pupil_start:                4.065
onSaccadeStart:
    eventtime:                  1750691946820244
    side:                       MEAN
    starttime:                  1750691946820244
    gaze_start:                 0.348, 0.471
    pupil_start:                4.176
onSaccadeEnd:
    eventtime:                  1750691946894257
    side:                       LEFT
    starttime:                  1750691946818243
    duration:                   76014
    gaze_end:                   0.067, 0.904
    pupil_end:                  4.253
    gaze_avg:                   0.147, 0.754
    pupil_avg:                  4.281
onSaccadeEnd:
    eventtime:                  1750691946894257
    side:                       MEAN
    starttime:                  1750691946820244
    duration:                   74013
    gaze_end:                   0.076, 0.917
    pupil_end:                  4.170
    gaze_avg:                   0.145, 0.769
    pupil_avg:                  4.193
onSaccadeEnd:
    eventtime:                  1750691946908260
    side:                       RIGHT
    starttime:                  1750691946820244
    duration:                   88016
    gaze_end:                   0.079, 0.927
    pupil_end:                  4.057
    gaze_avg:                   0.138, 0.800
    pupil_avg:                  4.097
.
.
.

[q]
eyevec_cleanup(): OK
eyevec_destroy_thread(): OK