void TX_CALLCONVENTION ofxTobiiEyeX::OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState, TX_USERPARAM param)
{
	switch (connectionState) {
	case TX_CONNECTIONSTATE_CONNECTED: {
		bool success;
		ofLogNotice(smAddonName, "The connection state is now CONNECTED (We are connected to the EyeX Engine)");

		success = txCommitSnapshotAsync((TX_HANDLE)param, OnSnapshotCommitted, nullptr) == TX_RESULT_OK;
		if (!success) {
			ofLogError(smAddonName, "Failed to initialize the data stream.");
		}
		else {
			ofLogNotice(smAddonName, "Waiting for eye position data to start streaming...");
		}
	}
		 break;

	case TX_CONNECTIONSTATE_DISCONNECTED:
		ofLogNotice(smAddonName, "The connection state is now DISCONNECTED (We are disconnected from the EyeX Engine)");
		break;

	case TX_CONNECTIONSTATE_TRYINGTOCONNECT:
		ofLogNotice(smAddonName, "The connection state is now TRYINGTOCONNECT (We are trying to connect to the EyeX Engine)");
		break;

	case TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW:
		ofLogWarning(smAddonName, "The connection state is now SERVER_VERSION_TOO_LOW: this application requires a more recent version of the EyeX Engine to run.");
		break;

	case TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH:
		ofLogWarning(smAddonName, "The connection state is now SERVER_VERSION_TOO_HIGH: this application requires an older version of the EyeX Engine to run.");
		break;
	}
}
/*
 * 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;
	}
}
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, &params);

				txReleaseObject(&hInteractor);
			}
		}
	}
	txCommitSnapshotAsync(hSnapshot, OnSnapshotCommitted, nullptr);
	txReleaseObject(&hSnapshot);
	txReleaseObject(&hQuery);
}
void EyeXGaze::OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState)
{
	switch (connectionState)
	{
	case TX_CONNECTIONSTATE_CONNECTED: 
		{
			// commit snapshot to EyeX Engine
			txCommitSnapshotAsync(g_hGlobalInteractorSnapshot, OnSnapshotCommitted, NULL);
			
			
		}
		PostMessage(_hWnd, _statusChangedMessage, true, 0);
		break;

	case TX_CONNECTIONSTATE_DISCONNECTED:
	case TX_CONNECTIONSTATE_TRYINGTOCONNECT:
	case TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW:
	case TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH:
		PostMessage(_hWnd, _statusChangedMessage, false, 0);
		break;
	}
};
Beispiel #5
0
/*
 * Callback function invoked when the status of the connection to the EyeX Engine has changed.
 */
void TX_CALLCONVENTION eyeXHost::OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState) {
	string connectionStateMessage;
	auto snapshotCommittedTrampoline = [](TX_CONSTHANDLE hAsyncData, TX_USERPARAM userParam) {
		static_cast<eyeXHost*>(userParam)->OnSnapshotCommitted(hAsyncData);
	};
	
	switch (connectionState) {
	case TX_CONNECTIONSTATE_CONNECTED: {
			bool success;
			cout << "The connection state is now CONNECTED (We are connected to the EyeX Engine)" << "\n";
			success = txCommitSnapshotAsync(g_hGlobalInteractorSnapshot, snapshotCommittedTrampoline, NULL) == TX_RESULT_OK;
			if (!success) {
				cout << "Failed to initialize the data stream." << "\n";
			}
			else {
				cout << "Waiting for gaze data to start streaming..." << "\n";
			}
		}
		break;

	case TX_CONNECTIONSTATE_DISCONNECTED:
		cout << "TX_CONNECTIONSTATE_DISCONNECTED" << "\n";
		break;

	case TX_CONNECTIONSTATE_TRYINGTOCONNECT:
		cout << "TX_CONNECTIONSTATE_TRYINGTOCONNECT" << "\n";
		break;

	case TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW:
		cout << "TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW" << "\n";
		break;

	case TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH:
		cout << "TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH" << "\n";
		break;
	}
}
Beispiel #6
0
void TX_CALLCONVENTION OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState, TX_USERPARAM userParam)
{
	switch (connectionState)
	{
		case TX_CONNECTIONSTATE_CONNECTED: {
			BOOL success;
			success = txCommitSnapshotAsync(g_hGlobalInteractorSnapshot, OnSnapshotCommitted, NULL) == TX_RESULT_OK;

			break;
		}

		case TX_CONNECTIONSTATE_DISCONNECTED:
			break;

		case TX_CONNECTIONSTATE_TRYINGTOCONNECT:
			break;

		case TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW:
			break;

		case TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH:
			break;
	}
}
Beispiel #7
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, &params);

				txReleaseObject(&hInteractor);
			}
		}
	}

	txCommitSnapshotAsync(hSnapshot, OnSnapshotCommitted, nullptr);
	txReleaseObject(&hSnapshot);
	txReleaseObject(&hQuery);
}