/* * 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_FIXATIONDATA) == TX_RESULT_OK) { OnFixationDataEvent(hBehavior); txReleaseObject(&hBehavior); } if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK) { OnGazeDataEvent(hBehavior); txReleaseObject(&hBehavior); } if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK) { OnPositionDataEvent(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); }
bool ofxTobiiEyeX::registerEyePositionEventHandler(const string& InteractorId) { auto& handle = mEyePositionHandle; handle.hConnectionStateChangedTicket = TX_INVALID_TICKET; handle.hEventHandlerTicket = TX_INVALID_TICKET; TX_CONSTSTRING ID = InteractorId.c_str(); TX_HANDLE params = TX_EMPTY_HANDLE; TX_HANDLE hInteractor = TX_EMPTY_HANDLE; bool success = true; success &= txCreateContext(&handle.hContext, TX_FALSE) == TX_RESULT_OK; success &= txCreateGlobalInteractorSnapshot(handle.hContext, ID, &handle.hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateInteractorBehavior(hInteractor, ¶ms, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; success &= txReleaseObject(&hInteractor) == TX_RESULT_OK; success &= txReleaseObject(¶ms) == TX_RESULT_OK; success &= txRegisterConnectionStateChangedHandler(handle.hContext, &handle.hConnectionStateChangedTicket, OnEngineConnectionStateChanged, handle.hGlobalInteractorSnapshot) == TX_RESULT_OK; success &= txRegisterEventHandler(handle.hContext, &handle.hEventHandlerTicket, HandleEvent, nullptr) == TX_RESULT_OK; success &= txEnableConnection(handle.hContext) == TX_RESULT_OK; if (!success) { ofLogError(smAddonName, "Registing eye position data event handler was failed."); } return success; }
void TX_CALLCONVENTION ofxTobiiEyeX::HandleEvent(TX_CONSTHANDLE hAsyncData, TX_USERPARAM param) { TX_HANDLE hEvent = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; txGetAsyncDataContent(hAsyncData, &hEvent); if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK) { if (txGetGazePointDataEventParams(hBehavior, &smGazePointDataEventParams) != TX_RESULT_OK) { ofLogError(smAddonName, "Failed to interpret gaze data event packet."); } } if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK) { if (txGetEyePositionDataEventParams(hBehavior, &smEyePositionEventParams) != TX_RESULT_OK) { ofLogError(smAddonName, "Failed to interpret eye position event packet."); } } if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_FIXATIONDATA) == TX_RESULT_OK) { if (txGetFixationDataEventParams(hBehavior, &smFixationEventParams) != TX_RESULT_OK) { ofLogError(smAddonName, "Failed to interpret fixation event packet."); } } txReleaseObject(&hBehavior); txReleaseObject(&hEvent); }
/* * Initializes g_hGlobalInteractorSnapshot with an interactor that has the Gaze Point behavior. */ BOOL InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; TX_HANDLE hBehaviorWithoutParameters = TX_EMPTY_HANDLE; TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; BOOL success; success = txCreateGlobalInteractorSnapshot( hContext, InteractorId, &g_hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_BEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK; success &= txSetGazePointDataBehaviorParams(hBehavior, ¶ms) == TX_RESULT_OK; // add a second behavior to the same interactor: eye position data. // this one is a bit different because it doesn't take any parameters. // therefore we use the generic txCreateInteractorBehavior function (and remember to release the handle!) success &= txCreateInteractorBehavior(hInteractor, &hBehaviorWithoutParameters, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; // release the handles txReleaseObject(&hBehavior); txReleaseObject(&hBehaviorWithoutParameters); txReleaseObject(&hInteractor); return success; }
void EyeXGaze::HandleQuery(TX_CONSTHANDLE hAsyncData) { std::lock_guard<std::mutex> lock(_mutex); TX_HANDLE hQuery(TX_EMPTY_HANDLE); // query를 받기위한 핸들 txGetAsyncDataContent(hAsyncData, &hQuery); // asyncdatacontent를 hquery에 저장 const int bufferSize = 20; TX_CHAR stringBuffer[bufferSize]; // query 를 가지고 rectangular bounds 생성 TX_HANDLE hBounds(TX_EMPTY_HANDLE); txGetQueryBounds(hQuery, &hBounds); // query의 bound 알아낸다 TX_REAL pX, pY, pWidth, pHeight; txGetRectangularBoundsData(hBounds, &pX, &pY, &pWidth, &pHeight);// bound에서 rectangular한 좌표 추출 txReleaseObject(&hBounds); Gdiplus::Rect queryBounds((INT)pX, (INT)pY, (INT)pWidth, (INT)pHeight); // query 를 가지고 Snapshot 생성 TX_HANDLE hSnapshot(TX_EMPTY_HANDLE); txCreateSnapshotForQuery(hQuery, &hSnapshot); TX_CHAR windowIdString[bufferSize]; sprintf_s(windowIdString, bufferSize, WINDOW_HANDLE_FORMAT, _hWnd); if (QueryIsForWindowId(hQuery, windowIdString)) { TX_ACTIVATABLEPARAMS params = { TX_FALSE }; for (auto region : _regions) { Gdiplus::Rect regionBounds((INT)region.bounds.left,(INT)region.bounds.top, (INT)(region.bounds.right - region.bounds.left), (INT)(region.bounds.bottom - region.bounds.top)); if (queryBounds.IntersectsWith(regionBounds)) { TX_HANDLE hInteractor(TX_EMPTY_HANDLE); sprintf_s(stringBuffer, bufferSize, "%d", region.id); TX_RECT bounds; bounds.X = region.bounds.left; bounds.Y = region.bounds.top; bounds.Width = region.bounds.right - region.bounds.left; bounds.Height = region.bounds.bottom - region.bounds.top; txCreateRectangularInteractor(hSnapshot, &hInteractor, stringBuffer, &bounds, TX_LITERAL_ROOTID, windowIdString); txCreateActivatableBehavior(hInteractor, ¶ms); txReleaseObject(&hInteractor); } } } txCommitSnapshotAsync(hSnapshot, OnSnapshotCommitted, nullptr); txReleaseObject(&hSnapshot); txReleaseObject(&hQuery); }
int stopEyeX(void) { printf("Exiting.\n"); // disable and delete the context. txDisableConnection(hContext); txReleaseObject(&g_hGlobalInteractor1Snapshot); txReleaseObject(&g_hGlobalInteractor2Snapshot); txShutdownContext(hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); txReleaseContext(&hContext); return 0; }
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); if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK) { OnGazeDataEvent(hBehavior); txReleaseObject(&hBehavior); } txReleaseObject(&hEvent); }
void EyeXHost::TriggerActivation() { TX_HANDLE command(TX_EMPTY_HANDLE); txCreateActionCommand(_context, &command, TX_ACTIONTYPE_ACTIVATE); txExecuteCommandAsync(command, NULL, NULL); txReleaseObject(&command); }
void TX_CALLCONVENTION eyeXHost::HandleEvent(TX_CONSTHANDLE hAsyncData) { TX_HANDLE hEvent = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; txGetAsyncDataContent(hAsyncData, &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); }
void TX_CALLCONVENTION EyeXGaze::FixHandleEvent(TX_CONSTHANDLE hAsyncData) { TX_HANDLE hEvent = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; // DataContent를 hEvent에 저장 txGetAsyncDataContent(hAsyncData, &hEvent); //event에서 behavior를 해당 타입대로 추출하여 hBehavior변수에 저장 if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_FIXATIONDATA) == TX_RESULT_OK) { OnFixationDataEvent(hBehavior); txReleaseObject(&hBehavior); } txReleaseObject(&hEvent); }
BOOL EyeXGaze::InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; // Gaze데이터 출력을 위한 변수 LIGHTLY FILTERED 모드 // TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; // Fix데이터 출력을 위한 변수 SENSITIVE 모드 TX_FIXATIONDATAPARAMS fparams = { TX_FIXATIONDATAMODE_SENSITIVE }; // SLOW 도 있음 BOOL success; // global interactor 생성 success = txCreateGlobalInteractorSnapshot( hContext, InteractorId, &g_hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; // behavior를 gaze point data로 설정 //success &= txCreateGazePointDataBehavior(hInteractor, ¶ms) == TX_RESULT_OK; // behavior를 fixation data로 설정 success &= txCreateFixationDataBehavior(hInteractor, &fparams) == TX_RESULT_OK; // interactor 사용후 release txReleaseObject(&hInteractor); return success; }
bool ofxTobiiEyeX::registerGazePointEventHandler(const string& InteractorId, TX_GAZEPOINTDATAMODE mode) { auto& handle = mGazePointHandle; handle.hConnectionStateChangedTicket = TX_INVALID_TICKET; handle.hEventHandlerTicket = TX_INVALID_TICKET; TX_CONSTSTRING ID = InteractorId.c_str(); TX_GAZEPOINTDATAPARAMS params = { mode }; TX_HANDLE hInteractor = TX_EMPTY_HANDLE; bool success = true; success &= txCreateContext(&handle.hContext, TX_FALSE) == TX_RESULT_OK; success &= txCreateGlobalInteractorSnapshot(handle.hContext, ID, &handle.hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateGazePointDataBehavior(hInteractor, ¶ms) == TX_RESULT_OK; success &= txReleaseObject(&hInteractor) == TX_RESULT_OK; success &= txRegisterConnectionStateChangedHandler(handle.hContext, &handle.hConnectionStateChangedTicket, OnEngineConnectionStateChanged, handle.hGlobalInteractorSnapshot) == TX_RESULT_OK; success &= txRegisterEventHandler(handle.hContext, &handle.hEventHandlerTicket, HandleEvent, nullptr) == TX_RESULT_OK; success &= txEnableConnection(handle.hContext) == TX_RESULT_OK; if (!success) { ofLogError(smAddonName, "Registing gaze point data event handler was failed."); } return success; }
bool Tobii::InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; bool success; success = txCreateGlobalInteractorSnapshot( hContext, InteractorId, &g_hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; TX_FIXATIONDATAPARAMS fixationParams = { TX_FIXATIONDATAMODE_SLOW }; success &= txCreateFixationDataBehavior(hInteractor, &fixationParams) == TX_RESULT_OK; TX_GAZEPOINTDATAPARAMS gazeParams = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; success &= txCreateGazePointDataBehavior(hInteractor, &gazeParams) == TX_RESULT_OK; TX_HANDLE hBehaviorWithoutParameters = TX_EMPTY_HANDLE; success &= txCreateInteractorBehavior(hInteractor, &hBehaviorWithoutParameters, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&hInteractor); return success; }
eyeXHost::~eyeXHost() { if (_context != TX_EMPTY_HANDLE) { txDisableConnection(_context); txReleaseObject(&g_hGlobalInteractorSnapshot); txShutdownContext(_context, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); txReleaseContext(&_context); } }
BOOL InitializeGlobalInteractorSnapshot2(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; BOOL success; success = txCreateGlobalInteractorSnapshot( hContext, Interactor2Id, &g_hGlobalInteractor2Snapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&hBehavior); txReleaseObject(&hInteractor); return success; }
void Disconnect(void) { // disable and delete the context. txDisableConnection(hContext); txReleaseObject(&g_hGlobalInteractorSnapshot); txShutdownContext(hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); txReleaseContext(&hContext); q_destroy(); }
void EyeXGaze::TriggerActivation() { TX_HANDLE command(TX_EMPTY_HANDLE); // set command in context as click activation button. txCreateActionCommand(_hContext, &command, TX_ACTIONTYPE_ACTIVATE); //execute command txExecuteCommandAsync(command, NULL, NULL); txReleaseObject(&command); }
void Tobii::DestroyTobii() { txDisableConnection(hContext); txReleaseObject(&g_hGlobalInteractorSnapshot); bool 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"); } }
/* * Initializes g_hGlobalInteractorSnapshot with an interactor that has the Gaze Point behavior. */ BOOL InitializeGlobalInteractorSnapshot1(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; BOOL success; success = txCreateGlobalInteractorSnapshot( hContext, Interactor1Id, &g_hGlobalInteractor1Snapshot, &hInteractor) == TX_RESULT_OK; // success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_INTERACTIONBEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK; // success &= txSetGazePointDataBehaviorParams(hBehavior, ¶ms) == TX_RESULT_OK; success &= txCreateGazePointDataBehavior(hInteractor, ¶ms) == TX_RESULT_OK; txReleaseObject(&hBehavior); txReleaseObject(&hInteractor); return success; }
BOOL ShutdownEyeX() { BOOL success; txDisableConnection(eyeXContext); txReleaseObject(&g_hGlobalInteractorSnapshot); success = txShutdownContext(eyeXContext, TX_CLEANUPTIMEOUT_FORCEIMMEDIATE, TX_FALSE) == TX_RESULT_OK; success &= txReleaseContext(&eyeXContext) == TX_RESULT_OK; success &= txUninitializeEyeX() == TX_RESULT_OK; return success; }
EyeXGaze::~EyeXGaze() { //connection disable 및 global interactor release txDisableConnection(_hContext); txReleaseObject(&g_hGlobalInteractorSnapshot); // context shutdown 및 release txShutdownContext(_hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); txReleaseContext(&_hContext); // client library 연결 해제 txUninitializeEyeX(); }
/* * Initializes g_hGlobalInteractorSnapshot with an interactor that has the Fixation, Gaze and Position Data behavior. */ BOOL InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; TX_HANDLE hBehavior = TX_EMPTY_HANDLE; TX_FIXATIONDATAPARAMS paramsF = { TX_FIXATIONDATAMODE_SENSITIVE }; TX_GAZEPOINTDATAPARAMS paramsG = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; BOOL success; success = txCreateGlobalInteractorSnapshot( hContext, InteractorId, &g_hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateFixationDataBehavior(hInteractor, ¶msF) == TX_RESULT_OK; success &= txCreateGazePointDataBehavior(hInteractor, ¶msG) == TX_RESULT_OK; success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&hBehavior); txReleaseObject(&hInteractor); return success; }
/* * Initializes g_hGlobalInteractorSnapshot with an interactor that has the Gaze Point behavior. */ bool eyeXHost::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, ¶ms) == TX_RESULT_OK; txReleaseObject(&hInteractor); return success; }
bool ofxTobiiEyeX::unregisterEventHandler(Handle& handle) { bool success = true; success &= txUnregisterConnectionStateChangedHandler(handle.hContext, handle.hConnectionStateChangedTicket) == TX_RESULT_OK; success &= txUnregisterEventHandler(handle.hContext, handle.hEventHandlerTicket) == TX_RESULT_OK; success &= txDisableConnection(handle.hContext) == TX_RESULT_OK; success &= txReleaseObject(&handle.hGlobalInteractorSnapshot) == TX_RESULT_OK; //success &= txShutdownContext(handle.hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE) == TX_RESULT_OK; TX_RESULT res = txShutdownContext(handle.hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); success &= txReleaseContext(&handle.hContext) == TX_RESULT_OK; if (!success) { ofLogError(smAddonName, "EyeX could not be shut down cleanly."); } return success; }
void EyeXGaze::HandleActivatableEvent(TX_HANDLE hEvent, int interactorId) { TX_HANDLE hActivatable(TX_EMPTY_HANDLE); if (txGetEventBehavior(hEvent, &hActivatable, TX_BEHAVIORTYPE_ACTIVATABLE) == TX_RESULT_OK) { TX_ACTIVATABLEEVENTTYPE eventType; if(txGetActivatableEventType(hActivatable,&eventType)==TX_RESULT_OK) { if (eventType == TX_ACTIVATABLEEVENTTYPE_ACTIVATED) { OnActivated(hActivatable, interactorId); } else if (eventType == TX_ACTIVATABLEEVENTTYPE_ACTIVATIONFOCUSCHANGED) { OnActivationFocusChanged(hActivatable, interactorId); } } } txReleaseObject(&hActivatable); }
void EyeXHost::HandleEvent(TX_CONSTHANDLE hAsyncData) { TX_HANDLE hEvent(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)); // read the interactor ID from the event. const int bufferSize = 20; TX_CHAR stringBuffer[bufferSize]; TX_SIZE idLength(bufferSize); if (txGetEventInteractorId(hEvent, stringBuffer, &idLength) == TX_RESULT_OK) { int interactorId = atoi(stringBuffer); HandleActivatableEvent(hEvent, interactorId); } 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; }
/* * Application entry point. */ int main(int argc, char* argv[]) { char *ip = NULL; char *port = NULL; int iResult = 0; system("cls"); // Check input arguments for IP and PORT and open client socket if required if (argc != 3) { printf("Usage: %s <IP> <PORT>\n", argv[0]); printf("EyeX data will not be streamed\n"); } else { ip = argv[1]; port = argv[2]; printf("Trying connection with %s : %s\n", ip, port); clientSocket = OpenClientSocket(ip, port); if (clientSocket == INVALID_SOCKET) { printf("Error at connection with %s : %s\n", ip, port); printf("EyeX data will not be streamed\n"); } else { streaming = TRUE; } } Sleep(2000); 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 X to exit...\n"); _getch(); printf("Exiting.\n"); // disable and delete the context. txDisableConnection(hContext); txReleaseObject(&g_hGlobalInteractorSnapshot); txShutdownContext(hContext, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); txReleaseContext(&hContext); if (streaming) { SendFloatClientSocket(clientSocket, -1); CloseClientSocket(clientSocket); } Beep(300, 750); return 0; }
void EyeXHost::HandleQuery(TX_CONSTHANDLE hAsyncData) { std::lock_guard<std::mutex> lock(_mutex); // NOTE. This method will fail silently if, for example, the connection is lost before the snapshot has been committed, // or if we run out of memory. This is by design, because there is nothing we can do to recover from these errors anyway. TX_HANDLE hQuery(TX_EMPTY_HANDLE); txGetAsyncDataContent(hAsyncData, &hQuery); const int bufferSize = 20; TX_CHAR stringBuffer[bufferSize]; // read the query bounds from the query, that is, the area on the screen that the query concerns. // the query region is always rectangular. TX_HANDLE hBounds(TX_EMPTY_HANDLE); txGetQueryBounds(hQuery, &hBounds); TX_REAL pX, pY, pWidth, pHeight; txGetRectangularBoundsData(hBounds, &pX, &pY, &pWidth, &pHeight); txReleaseObject(&hBounds); Gdiplus::Rect queryBounds((INT)pX, (INT)pY, (INT)pWidth, (INT)pHeight); // create a new snapshot with the same window id and bounds as the query. TX_HANDLE hSnapshot(TX_EMPTY_HANDLE); txCreateSnapshotForQuery(hQuery, &hSnapshot); TX_CHAR windowIdString[bufferSize]; sprintf_s(windowIdString, bufferSize, WINDOW_HANDLE_FORMAT, _hWnd); if (QueryIsForWindowId(hQuery, windowIdString)) { // define options for our activatable regions: no, we don't want tentative focus events. TX_ACTIVATABLEPARAMS params = { TX_FALSE }; // iterate through all regions and create interactors for those that overlap with the query bounds. for (auto region : _regions) { Gdiplus::Rect regionBounds((INT)region.bounds.left, (INT)region.bounds.top, (INT)(region.bounds.right - region.bounds.left), (INT)(region.bounds.bottom - region.bounds.top)); if (queryBounds.IntersectsWith(regionBounds)) { TX_HANDLE hInteractor(TX_EMPTY_HANDLE); sprintf_s(stringBuffer, bufferSize, "%d", region.id); TX_RECT bounds; bounds.X = region.bounds.left; bounds.Y = region.bounds.top; bounds.Width = region.bounds.right - region.bounds.left; bounds.Height = region.bounds.bottom - region.bounds.top; txCreateRectangularInteractor(hSnapshot, &hInteractor, stringBuffer, &bounds, TX_LITERAL_ROOTID, windowIdString); txCreateActivatableBehavior(hInteractor, ¶ms); txReleaseObject(&hInteractor); } } } txCommitSnapshotAsync(hSnapshot, OnSnapshotCommitted, nullptr); txReleaseObject(&hSnapshot); txReleaseObject(&hQuery); }