summaryrefslogtreecommitdiffhomepage
path: root/Tobii EyeX/samples/MinimalGazeDataStream/MinimalGazeDataStream.c
diff options
context:
space:
mode:
Diffstat (limited to 'Tobii EyeX/samples/MinimalGazeDataStream/MinimalGazeDataStream.c')
-rwxr-xr-xTobii EyeX/samples/MinimalGazeDataStream/MinimalGazeDataStream.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/Tobii EyeX/samples/MinimalGazeDataStream/MinimalGazeDataStream.c b/Tobii EyeX/samples/MinimalGazeDataStream/MinimalGazeDataStream.c
new file mode 100755
index 0000000..20b3eab
--- /dev/null
+++ b/Tobii EyeX/samples/MinimalGazeDataStream/MinimalGazeDataStream.c
@@ -0,0 +1,171 @@
+/*
+ * This is an example that demonstrates how to connect to the EyeX Engine and subscribe to the lightly filtered gaze data stream.
+ *
+ * Copyright 2013-2014 Tobii Technology AB. All rights reserved.
+ */
+
+#include <Windows.h>
+#include <stdio.h>
+#include <conio.h>
+#include <assert.h>
+#include "eyex/EyeX.h"
+
+#pragma comment (lib, "Tobii.EyeX.Client.lib")
+
+// ID of the global interactor that provides our data stream; must be unique within the application.
+static const TX_STRING InteractorId = "Twilight Sparkle";
+
+// global variables
+static TX_HANDLE g_hGlobalInteractorSnapshot = TX_EMPTY_HANDLE;
+
+/*
+ * Initializes g_hGlobalInteractorSnapshot with an interactor that has the Gaze Point behavior.
+ */
+BOOL InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext)
+{
+ TX_HANDLE hInteractor = TX_EMPTY_HANDLE;
+ TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED };
+ BOOL success;
+
+ success = txCreateGlobalInteractorSnapshot(
+ hContext,
+ InteractorId,
+ &g_hGlobalInteractorSnapshot,
+ &hInteractor) == TX_RESULT_OK;
+ success &= txCreateGazePointDataBehavior(hInteractor, &params) == TX_RESULT_OK;
+
+ txReleaseObject(&hInteractor);
+
+ return success;
+}
+
+/*
+ * Callback function invoked when a snapshot has been committed.
+ */
+void TX_CALLCONVENTION OnSnapshotCommitted(TX_CONSTHANDLE hAsyncData, TX_USERPARAM param)
+{
+ // check the result code using an assertion.
+ // this will catch validation errors and runtime errors in debug builds. in release builds it won't do anything.
+
+ TX_RESULT result = TX_RESULT_UNKNOWN;
+ txGetAsyncDataResultCode(hAsyncData, &result);
+ assert(result == TX_RESULT_OK || result == TX_RESULT_CANCELLED);
+}
+
+/*
+ * Callback function invoked when the status of the connection to the EyeX Engine has changed.
+ */
+void TX_CALLCONVENTION OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState, TX_USERPARAM userParam)
+{
+ switch (connectionState) {
+ case TX_CONNECTIONSTATE_CONNECTED: {
+ BOOL success;
+ printf("The connection state is now CONNECTED (We are connected to the EyeX Engine)\n");
+ // commit the snapshot with the global interactor as soon as the connection to the engine is established.
+ // (it cannot be done earlier because committing means "send to the engine".)
+ success = txCommitSnapshotAsync(g_hGlobalInteractorSnapshot, OnSnapshotCommitted, NULL) == TX_RESULT_OK;
+ if (!success) {
+ printf("Failed to initialize the data stream.\n");
+ }
+ else {
+ printf("Waiting for gaze data to start streaming...\n");
+ }
+ }
+ break;
+
+ case TX_CONNECTIONSTATE_DISCONNECTED:
+ printf("The connection state is now DISCONNECTED (We are disconnected from the EyeX Engine)\n");
+ break;
+
+ case TX_CONNECTIONSTATE_TRYINGTOCONNECT:
+ printf("The connection state is now TRYINGTOCONNECT (We are trying to connect to the EyeX Engine)\n");
+ break;
+
+ case TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW:
+ printf("The connection state is now SERVER_VERSION_TOO_LOW: this application requires a more recent version of the EyeX Engine to run.\n");
+ break;
+
+ case TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH:
+ printf("The connection state is now SERVER_VERSION_TOO_HIGH: this application requires an older version of the EyeX Engine to run.\n");
+ break;
+ }
+}
+
+/*
+ * Handles an event from the Gaze Point data stream.
+ */
+void OnGazeDataEvent(TX_HANDLE hGazeDataBehavior)
+{
+ TX_GAZEPOINTDATAEVENTPARAMS eventParams;
+ if (txGetGazePointDataEventParams(hGazeDataBehavior, &eventParams) == TX_RESULT_OK) {
+ printf("Gaze Data: (%.1f, %.1f) timestamp %.0f ms\n", eventParams.X, eventParams.Y, eventParams.Timestamp);
+ } else {
+ printf("Failed to interpret gaze data event packet.\n");
+ }
+}
+
+/*
+ * Callback function invoked when an event has been received from the EyeX Engine.
+ */
+void TX_CALLCONVENTION HandleEvent(TX_CONSTHANDLE hAsyncData, TX_USERPARAM userParam)
+{
+ TX_HANDLE hEvent = TX_EMPTY_HANDLE;
+ TX_HANDLE hBehavior = TX_EMPTY_HANDLE;
+
+ txGetAsyncDataContent(hAsyncData, &hEvent);
+
+ // NOTE. Uncomment the following line of code to view the event object. The same function can be used with any interaction object.
+ //OutputDebugStringA(txDebugObject(hEvent));
+
+ if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK) {
+ OnGazeDataEvent(hBehavior);
+ txReleaseObject(&hBehavior);
+ }
+
+ // NOTE since this is a very simple application with a single interactor and a single data stream,
+ // our event handling code can be very simple too. A more complex application would typically have to
+ // check for multiple behaviors and route events based on interactor IDs.
+
+ txReleaseObject(&hEvent);
+}
+
+/*
+ * Application entry point.
+ */
+int main(int argc, char* argv[])
+{
+ TX_CONTEXTHANDLE hContext = TX_EMPTY_HANDLE;
+ TX_TICKET hConnectionStateChangedTicket = TX_INVALID_TICKET;
+ TX_TICKET hEventHandlerTicket = TX_INVALID_TICKET;
+ BOOL success;
+
+ // initialize and enable the context that is our link to the EyeX Engine.
+ success = txInitializeEyeX(TX_EYEXCOMPONENTOVERRIDEFLAG_NONE, NULL, NULL, NULL, NULL) == TX_RESULT_OK;
+ success &= txCreateContext(&hContext, TX_FALSE) == TX_RESULT_OK;
+ success &= InitializeGlobalInteractorSnapshot(hContext);
+ success &= txRegisterConnectionStateChangedHandler(hContext, &hConnectionStateChangedTicket, OnEngineConnectionStateChanged, NULL) == TX_RESULT_OK;
+ success &= txRegisterEventHandler(hContext, &hEventHandlerTicket, HandleEvent, NULL) == TX_RESULT_OK;
+ success &= txEnableConnection(hContext) == TX_RESULT_OK;
+
+ // let the events flow until a key is pressed.
+ if (success) {
+ printf("Initialization was successful.\n");
+ } else {
+ printf("Initialization failed.\n");
+ }
+ printf("Press any key to exit...\n");
+ _getch();
+ printf("Exiting.\n");
+
+ // disable and delete the context.
+ txDisableConnection(hContext);
+ txReleaseObject(&g_hGlobalInteractorSnapshot);
+ success = txShutdownContext(hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE) == TX_RESULT_OK;
+ success &= txReleaseContext(&hContext) == TX_RESULT_OK;
+ success &= txUninitializeEyeX() == TX_RESULT_OK;
+ if (!success) {
+ printf("EyeX could not be shut down cleanly. Did you remember to release all handles?\n");
+ }
+
+ return 0;
+}