From 72c46bdd7f5d430ab1ad1d420ed77c7f22df857a Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 30 Sep 2017 15:01:35 +0200 Subject: rename --- .../ActivatableButtons/ActivatableButtons.cpp | 357 +++++++++++++++++++++ .../ActivatableButtons/ActivatableButtons.ico | Bin 0 -> 2998 bytes .../ActivatableButtons/ActivatableButtons.rc | Bin 0 -> 5276 bytes .../ActivatableButtons/ActivatableButtons.vcxproj | 188 +++++++++++ .../ActivatableButtons.vcxproj.filters | 55 ++++ .../ActivatableButtons.lastbuildstate | 2 + .../Debug/Activata.3E2A1867.tlog/CL.command.1.tlog | Bin 0 -> 2374 bytes .../Debug/Activata.3E2A1867.tlog/CL.read.1.tlog | Bin 0 -> 62318 bytes .../Debug/Activata.3E2A1867.tlog/CL.write.1.tlog | Bin 0 -> 1784 bytes .../Activata.3E2A1867.tlog/link.command.1.tlog | Bin 0 -> 1924 bytes .../Debug/Activata.3E2A1867.tlog/link.read.1.tlog | Bin 0 -> 4432 bytes .../Debug/Activata.3E2A1867.tlog/link.write.1.tlog | Bin 0 -> 820 bytes .../Debug/Activata.3E2A1867.tlog/rc.command.1.tlog | Bin 0 -> 412 bytes .../Debug/Activata.3E2A1867.tlog/rc.read.1.tlog | Bin 0 -> 2686 bytes .../Debug/Activata.3E2A1867.tlog/rc.write.1.tlog | Bin 0 -> 270 bytes .../Debug/ActivatableButtons.log | 6 + .../Debug/ActivatableButtons.obj | Bin 0 -> 286795 bytes .../Debug/ActivatableButtons.pch | Bin 0 -> 8323072 bytes .../Debug/ActivatableButtons.res | Bin 0 -> 6584 bytes .../samples/ActivatableButtons/Debug/EyeXHost.obj | Bin 0 -> 344750 bytes .../samples/ActivatableButtons/Debug/stdafx.obj | Bin 0 -> 142737 bytes .../samples/ActivatableButtons/Debug/vc140.idb | Bin 0 -> 1289216 bytes .../samples/ActivatableButtons/Debug/vc140.pdb | Bin 0 -> 1486848 bytes Tobii-EyeX/samples/ActivatableButtons/EyeXHost.cpp | 294 +++++++++++++++++ Tobii-EyeX/samples/ActivatableButtons/EyeXHost.h | 79 +++++ Tobii-EyeX/samples/ActivatableButtons/Resource.h | Bin 0 -> 1814 bytes Tobii-EyeX/samples/ActivatableButtons/small.ico | Bin 0 -> 2998 bytes Tobii-EyeX/samples/ActivatableButtons/stdafx.cpp | 3 + Tobii-EyeX/samples/ActivatableButtons/stdafx.h | 17 + Tobii-EyeX/samples/ActivatableButtons/targetver.h | 8 + 30 files changed, 1009 insertions(+) create mode 100755 Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.cpp create mode 100755 Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.ico create mode 100755 Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.rc create mode 100755 Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj create mode 100755 Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj.filters create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/ActivatableButtons.lastbuildstate create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.command.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.read.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.write.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.command.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.read.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.write.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.command.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.read.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.write.1.tlog create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.log create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.obj create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.pch create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.res create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/EyeXHost.obj create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/stdafx.obj create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.idb create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.pdb create mode 100755 Tobii-EyeX/samples/ActivatableButtons/EyeXHost.cpp create mode 100755 Tobii-EyeX/samples/ActivatableButtons/EyeXHost.h create mode 100755 Tobii-EyeX/samples/ActivatableButtons/Resource.h create mode 100755 Tobii-EyeX/samples/ActivatableButtons/small.ico create mode 100755 Tobii-EyeX/samples/ActivatableButtons/stdafx.cpp create mode 100755 Tobii-EyeX/samples/ActivatableButtons/stdafx.h create mode 100755 Tobii-EyeX/samples/ActivatableButtons/targetver.h (limited to 'Tobii-EyeX/samples/ActivatableButtons') diff --git a/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.cpp b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.cpp new file mode 100755 index 0000000..8cee1c3 --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.cpp @@ -0,0 +1,357 @@ +/* + * ActivatableButtons sample: + * This is an example that demonstrates the Activatable behavior. + * It features two buttons that can be clicked by looking at the button and pressing the space bar. + * + * Copyright 2013 Tobii Technology AB. All rights reserved. + */ + +#include "stdafx.h" +#include +#include +#include +#include "resource.h" +#include "EyeXHost.h" + +#pragma comment (lib, "Gdiplus.lib") + +// window messages used for notifications from the EyeXHost. +#define WM_EYEX_HOST_STATUS_CHANGED WM_USER + 0 +#define WM_REGION_GOT_ACTIVATION_FOCUS WM_USER + 1 +#define WM_REGION_ACTIVATED WM_USER + 2 + +// constants. +static const Gdiplus::Color OriginalBackgroundColor(66, 173, 209); +static const Gdiplus::Color OtherBackgroundColor(89, 169, 108); +static const int ChangeButtonLeft = 50; +static const int ResetButtonLeft = 260; +static const int ButtonTop = 100; +static const int ButtonWidth = 160; +static const int ButtonHeight = 100; +static const TCHAR* g_szWindowClass = _T("ActivatableButtons"); + +// global variables. +static EyeXHost g_eyeXHost; +static HWND g_hWnd; +static HWND g_hChangeButton; +static HWND g_hResetButton; +static bool g_useOriginalColor = true; + +// gets the bounds of a button in screen coordinates. +RECT GetScreenBounds(HWND hButton) +{ + POINT point = { 0, 0 }; + ClientToScreen(hButton, &point); + + RECT bounds; + bounds.left = point.x; + bounds.top = point.y; + bounds.right = bounds.left + ButtonWidth; + bounds.bottom = bounds.top + ButtonHeight; + + return bounds; +} + +// reports the buttons as activatable regions to the EyeX host. +void UpdateActivatableRegions() +{ + std::vector regions; + + regions.push_back(EyeXHost::ActivatableRegion(IDC_CHANGE_COLOR_BUTTON, GetScreenBounds(g_hChangeButton))); + regions.push_back(EyeXHost::ActivatableRegion(IDC_RESET_COLOR_BUTTON, GetScreenBounds(g_hResetButton))); + + g_eyeXHost.SetActivatableRegions(regions); +} + +// event handler invoked when a "status changed" event has been received from the EyeX host. +void OnStatusChanged(bool engineConnectionIsFunctional) +{ + // update the window title to reflect the engine connection state. + if (engineConnectionIsFunctional) + { + SetWindowText(g_hWnd, _T("ActivatableButtons - Use Ur Eyez! :)")); + } + else + { + SetWindowText(g_hWnd, _T("ActivatableButtons - Mouse Only :(")); + } +} + +// event handler invoked when a region has received the activation focus. +void OnRegionGotActivationFocus(UINT regionId) +{ + // set the keyboard focus to the corresponding button. + switch(regionId) + { + case IDC_CHANGE_COLOR_BUTTON: + SetFocus(g_hChangeButton); + break; + + case IDC_RESET_COLOR_BUTTON: + SetFocus(g_hResetButton); + break; + } +} + +// event handler invoked when the "change color" button has been activated. +void OnChangeColorActivated() +{ + g_useOriginalColor = false; + InvalidateRect(g_hWnd, 0, FALSE); +} + +// event handler invoked when the "reset color" button has been activated. +void OnResetColorActivated() +{ + g_useOriginalColor = true; + InvalidateRect(g_hWnd, 0, FALSE); +} + +// event handler invoked when a region has received an activation event. +void OnRegionActivated(UINT regionId) +{ + // route the event to the corresponding button. + switch(regionId) + { + case IDC_CHANGE_COLOR_BUTTON: + OnChangeColorActivated(); + break; + + case IDC_RESET_COLOR_BUTTON: + OnResetColorActivated(); + break; + } +} + +void OnDraw(HDC hdc) +{ + Gdiplus::Graphics graphics(hdc); + + RECT rect; + GetClientRect(g_hWnd, &rect); + + Gdiplus::Color backgroundColor(OriginalBackgroundColor); + if (!g_useOriginalColor) + { + backgroundColor = OtherBackgroundColor; + } + + Gdiplus::SolidBrush backgroundBrush(backgroundColor); + graphics.FillRectangle(&backgroundBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); + + const TCHAR* message = _T("Click the buttons with your eyes! Look at a button and press the space bar to click. ") + _T("(Make sure the window has input focus.)"); + Gdiplus::Font font(_T("Arial"), 10); + Gdiplus::SolidBrush textBrush(Gdiplus::Color::Black); + Gdiplus::RectF textRect((Gdiplus::REAL)10, + (Gdiplus::REAL)(ButtonTop + ButtonHeight + 20), + (Gdiplus::REAL)(rect.right - 20), + (Gdiplus::REAL)(rect.bottom - rect.top)); + Gdiplus::StringFormat textFormat; + graphics.DrawString(message, (INT)_tcslen(message), &font, textRect, &textFormat, &textBrush); +} + +// +// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + PAINTSTRUCT ps; + HDC hdc; + + switch (message) + { + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + switch (wmId) + { + case IDC_CHANGE_COLOR_BUTTON: + OnChangeColorActivated(); + break; + + case IDC_RESET_COLOR_BUTTON: + OnResetColorActivated(); + break; + + case IDM_EXIT: + DestroyWindow(hWnd); + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + break; + + case WM_CREATE: + { + g_hChangeButton = CreateWindow( + _T("BUTTON"), + _T("Change color"), + WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, + ChangeButtonLeft, ButtonTop, ButtonWidth, ButtonHeight, + hWnd, + (HMENU)IDC_CHANGE_COLOR_BUTTON, + GetModuleHandle(NULL), + NULL); + g_hResetButton = CreateWindow( + _T("BUTTON"), + _T("Reset color"), + WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, + ResetButtonLeft, ButtonTop, ButtonWidth, ButtonHeight, + hWnd, + (HMENU)IDC_RESET_COLOR_BUTTON, + GetModuleHandle(NULL), + NULL); + } + break; + + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + OnDraw(hdc); + EndPaint(hWnd, &ps); + break; + + case WM_ERASEBKGND: + // no background erasing needed since our OnDraw method draws the entire window. + return TRUE; + + case WM_EYEX_HOST_STATUS_CHANGED: + OnStatusChanged(wParam != FALSE); + break; + + case WM_REGION_GOT_ACTIVATION_FOCUS: + OnRegionGotActivationFocus((UINT)wParam); + break; + + case WM_REGION_ACTIVATED: + OnRegionActivated((UINT)wParam); + break; + + case WM_WINDOWPOSCHANGED: + UpdateActivatableRegions(); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_KEYDOWN: + // trigger an activation command when space is pressed. + if (VK_SPACE == wParam) + { + g_eyeXHost.TriggerActivation(); + } + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ACTIVATABLEBUTTONS)); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = 0; + wcex.lpszMenuName = MAKEINTRESOURCE(IDC_ACTIVATABLEBUTTONS); + wcex.lpszClassName = g_szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); + + return RegisterClassEx(&wcex); +} + +// +// FUNCTION: InitInstance(HINSTANCE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + g_hWnd = CreateWindow(g_szWindowClass, _T(""), WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, 490, 380, NULL, NULL, hInstance, NULL); + + if (!g_hWnd) + { + return FALSE; + } + + ShowWindow(g_hWnd, nCmdShow); + UpdateWindow(g_hWnd); + + // initialize the EyeX host and the activatable regions. + g_eyeXHost.Init(g_hWnd, WM_EYEX_HOST_STATUS_CHANGED, WM_REGION_GOT_ACTIVATION_FOCUS, WM_REGION_ACTIVATED); + UpdateActivatableRegions(); + + return TRUE; +} + +// Application entry point. +int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPTSTR lpCmdLine, + _In_ int nCmdShow) +{ + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + + // Initialize gdiplus + ULONG_PTR gdiplusToken; + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); + + MyRegisterClass(hInstance); + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + HACCEL hAccelTable; + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_ACTIVATABLEBUTTONS)); + + // Main message loop: + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + // Shutdown: + Gdiplus::GdiplusShutdown(gdiplusToken); + + return (int) msg.wParam; +} diff --git a/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.ico b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.ico new file mode 100755 index 0000000..449296f Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.ico differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.rc b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.rc new file mode 100755 index 0000000..8f97f8c Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.rc differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj new file mode 100755 index 0000000..9bc381e --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {3E2A1867-D554-4655-8F03-B6A4C06D4967} + Win32Proj + ActivatableButtons + + + + Application + true + v140 + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\..\include;%(AdditionalIncludeDirectories) + + + Windows + true + ..\..\lib\x86 + + + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\..\include;%(AdditionalIncludeDirectories) + + + Windows + true + ..\..\lib\x64 + + + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\..\include;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + ..\..\lib\x86 + + + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\..\include;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + ..\..\lib\x64 + + + true + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj.filters b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj.filters new file mode 100755 index 0000000..dd3cdd3 --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/ActivatableButtons.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/ActivatableButtons.lastbuildstate b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/ActivatableButtons.lastbuildstate new file mode 100755 index 0000000..5cd4c3b --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/ActivatableButtons.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v140:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=8.1 +Debug|Win32|D:\dev\tobii\samples\| diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.command.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.command.1.tlog new file mode 100755 index 0000000..8c2918b Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.command.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.read.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.read.1.tlog new file mode 100755 index 0000000..64925ad Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.read.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.write.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.write.1.tlog new file mode 100755 index 0000000..54a1b52 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/CL.write.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.command.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.command.1.tlog new file mode 100755 index 0000000..5c8ec49 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.command.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.read.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.read.1.tlog new file mode 100755 index 0000000..5822f11 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.read.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.write.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.write.1.tlog new file mode 100755 index 0000000..2f69de6 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/link.write.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.command.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.command.1.tlog new file mode 100755 index 0000000..4506a2b Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.command.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.read.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.read.1.tlog new file mode 100755 index 0000000..a3ad644 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.read.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.write.1.tlog b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.write.1.tlog new file mode 100755 index 0000000..952d17c Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/Activata.3E2A1867.tlog/rc.write.1.tlog differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.log b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.log new file mode 100755 index 0000000..87b519f --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.log @@ -0,0 +1,6 @@ + stdafx.cpp + EyeXHost.cpp +d:\dev\tobii\samples\activatablebuttons\eyexhost.cpp(158): warning C4477: 'sprintf_s' : format string '%d' requires an argument of type 'int', but variadic argument 1 has type 'HWND' + ActivatableButtons.cpp + Generating Code... + ActivatableButtons.vcxproj -> D:\dev\tobii\samples\Debug\ActivatableButtons.exe diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.obj b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.obj new file mode 100755 index 0000000..d058330 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.obj differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.pch b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.pch new file mode 100755 index 0000000..cee1ac5 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.pch differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.res b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.res new file mode 100755 index 0000000..9cfd8cd Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/ActivatableButtons.res differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/EyeXHost.obj b/Tobii-EyeX/samples/ActivatableButtons/Debug/EyeXHost.obj new file mode 100755 index 0000000..b7e4d31 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/EyeXHost.obj differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/stdafx.obj b/Tobii-EyeX/samples/ActivatableButtons/Debug/stdafx.obj new file mode 100755 index 0000000..b3c70a5 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/stdafx.obj differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.idb b/Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.idb new file mode 100755 index 0000000..ec0d0d4 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.idb differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.pdb b/Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.pdb new file mode 100755 index 0000000..8f0aa96 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Debug/vc140.pdb differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/EyeXHost.cpp b/Tobii-EyeX/samples/ActivatableButtons/EyeXHost.cpp new file mode 100755 index 0000000..3291e54 --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/EyeXHost.cpp @@ -0,0 +1,294 @@ +/* + * ActivatableButtons sample: + * This is an example that demonstrates the Activatable behavior. + * It features two buttons that can be clicked by looking at the button and pressing the space bar. + * + * Copyright 2013 Tobii Technology AB. All rights reserved. + */ + +#include "stdafx.h" +#include "EyeXHost.h" +#include +#include +#include +#include + +#pragma comment (lib, "Tobii.EyeX.Client.lib") + +#if INTPTR_MAX == INT64_MAX +#define WINDOW_HANDLE_FORMAT "%lld" +#else +#define WINDOW_HANDLE_FORMAT "%d" +#endif + +EyeXHost::EyeXHost() + : _hWnd(nullptr), _statusChangedMessage(0), _focusedRegionChangedMessage(0), _regionActivatedMessage(0) +{ + // initialize the EyeX Engine client library. + txInitializeEyeX(TX_EYEXCOMPONENTOVERRIDEFLAG_NONE, nullptr, nullptr, nullptr, nullptr); + + // create a context and register event handlers. + txCreateContext(&_context, TX_FALSE); + RegisterConnectionStateChangedHandler(); + RegisterQueryHandler(); + RegisterEventHandler(); +} + +EyeXHost::~EyeXHost() +{ + if (_context != TX_EMPTY_HANDLE) + { + // shut down, then release the context. + txShutdownContext(_context, TX_CLEANUPTIMEOUT_DEFAULT, TX_FALSE); + txReleaseContext(&_context); + } +} + +void EyeXHost::Init(HWND hWnd, UINT statusChangedMessage, UINT focusedRegionChangedMessage, UINT regionActivatedMessage) +{ + _hWnd = hWnd; + _statusChangedMessage = statusChangedMessage; + _focusedRegionChangedMessage = focusedRegionChangedMessage; + _regionActivatedMessage = regionActivatedMessage; + + // connect to the engine. + if (txEnableConnection(_context) != TX_RESULT_OK) + { + PostMessage(_hWnd, _statusChangedMessage, false, 0); + } +} + +void EyeXHost::SetActivatableRegions(const std::vector& regions) +{ + std::lock_guard lock(_mutex); + + _regions.assign(regions.begin(), regions.end()); +} + +void EyeXHost::TriggerActivation() +{ + TX_HANDLE command(TX_EMPTY_HANDLE); + txCreateActionCommand(_context, &command, TX_ACTIONTYPE_ACTIVATE); + txExecuteCommandAsync(command, NULL, NULL); + txReleaseObject(&command); +} + +void EyeXHost::OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState) +{ + // note the use of the asynchronous PostMessage function to marshal the event to the main thread. + // (this callback function is typically invoked on a worker thread.) + switch (connectionState) + { + case TX_CONNECTIONSTATE::TX_CONNECTIONSTATE_CONNECTED: + PostMessage(_hWnd, _statusChangedMessage, true, 0); + break; + + case TX_CONNECTIONSTATE::TX_CONNECTIONSTATE_DISCONNECTED: + case TX_CONNECTIONSTATE::TX_CONNECTIONSTATE_TRYINGTOCONNECT: + case TX_CONNECTIONSTATE::TX_CONNECTIONSTATE_SERVERVERSIONTOOLOW: + case TX_CONNECTIONSTATE::TX_CONNECTIONSTATE_SERVERVERSIONTOOHIGH: + PostMessage(_hWnd, _statusChangedMessage, false, 0); + break; + + default: + break; + } +} + +bool EyeXHost::RegisterConnectionStateChangedHandler() +{ + auto connectionStateChangedTrampoline = [](TX_CONNECTIONSTATE connectionState, TX_USERPARAM userParam) + { + static_cast(userParam)->OnEngineConnectionStateChanged(connectionState); + }; + + bool success = txRegisterConnectionStateChangedHandler(_context, &_connectionStateChangedTicket, connectionStateChangedTrampoline, this) == TX_RESULT_OK; + return success; +} + +bool EyeXHost::RegisterQueryHandler() +{ + auto queryHandlerTrampoline = [](TX_CONSTHANDLE hObject, TX_USERPARAM userParam) + { + static_cast(userParam)->HandleQuery(hObject); + }; + + bool success = txRegisterQueryHandler(_context, &_queryHandlerTicket, queryHandlerTrampoline, this) == TX_RESULT_OK; + return success; +} + +bool EyeXHost::RegisterEventHandler() +{ + auto eventHandlerTrampoline = [](TX_CONSTHANDLE hObject, TX_USERPARAM userParam) + { + static_cast(userParam)->HandleEvent(hObject); + }; + + bool success = txRegisterEventHandler(_context, &_eventHandlerTicket, eventHandlerTrampoline, this) == TX_RESULT_OK; + return success; +} + +void EyeXHost::HandleQuery(TX_CONSTHANDLE hAsyncData) +{ + std::lock_guard 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); +} + +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); +} + +void EyeXHost::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::OnActivationFocusChanged(TX_HANDLE hBehavior, int interactorId) +{ + TX_ACTIVATIONFOCUSCHANGEDEVENTPARAMS eventData; + if (txGetActivationFocusChangedEventParams(hBehavior, &eventData) == TX_RESULT_OK) + { + if (eventData.HasActivationFocus) + { + PostMessage(_hWnd, _focusedRegionChangedMessage, interactorId, 0); + } + else + { + PostMessage(_hWnd, _focusedRegionChangedMessage, -1, 0); + } + + } +} + +void EyeXHost::OnActivated(TX_HANDLE hBehavior, int interactorId) +{ + PostMessage(_hWnd, _regionActivatedMessage, interactorId, 0); +} + +void TX_CALLCONVENTION EyeXHost::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); +} + +bool EyeXHost::QueryIsForWindowId(TX_HANDLE hQuery, const TX_CHAR* windowId) +{ + const int bufferSize = 20; + TX_CHAR buffer[bufferSize]; + + TX_SIZE count; + if (TX_RESULT_OK == txGetQueryWindowIdCount(hQuery, &count)) + { + for (int i = 0; i < count; i++) + { + TX_SIZE size = bufferSize; + if (TX_RESULT_OK == txGetQueryWindowId(hQuery, i, buffer, &size)) + { + if (0 == strcmp(windowId, buffer)) + { + return true; + } + } + } + } + + return false; +} diff --git a/Tobii-EyeX/samples/ActivatableButtons/EyeXHost.h b/Tobii-EyeX/samples/ActivatableButtons/EyeXHost.h new file mode 100755 index 0000000..6ee7493 --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/EyeXHost.h @@ -0,0 +1,79 @@ +/* + * EyeXHost class: Responsible for the gaze interaction within a window. + * Holds the current set of activatable regions and acts as a simple interactor repository. + * Sends notifications as Windows messages so that they are received on the main thread and can be handled there. + * + * Copyright 2013 Tobii Technology AB. All rights reserved. + */ + +#pragma once + +#include +#include +#include +#include "eyex/EyeX.h" + +class EyeXHost +{ +public: + // Represents an activatable region, that is, one particular kind of interactor. + struct ActivatableRegion + { + int id; + RECT bounds; + + ActivatableRegion(int paramId, RECT paramBounds) : id(paramId), bounds(paramBounds) { } + }; + + EyeXHost(); + virtual ~EyeXHost(); + + // attaches to the window with the given handle. + // the message parameters are custom windows messages sent to the window when an event has occurred. + void Init(HWND hWnd, UINT statusChangedMessage, UINT focusedRegionChangedMessage, UINT regionActivatedMessage); + + // updates the collection (repository) of activatable regions. + void SetActivatableRegions(const std::vector& regions); + + // triggers an activation ("direct click"). + void TriggerActivation(); + +private: + // registers handlers for notifications from the engine. + bool RegisterConnectionStateChangedHandler(); + bool RegisterQueryHandler(); + bool RegisterEventHandler(); + + // event handlers. + void OnEngineConnectionStateChanged(TX_CONNECTIONSTATE connectionState); + void HandleQuery(TX_CONSTHANDLE hAsyncData); + void HandleEvent(TX_CONSTHANDLE hAsyncData); + void HandleActivatableEvent(TX_HANDLE hEvent, int interactorId); + void OnActivationFocusChanged(TX_HANDLE hBehavior, int interactorId); + void OnActivated(TX_HANDLE hBehavior, int interactorId); + + // callback function invoked when a snapshot has been committed. + static void TX_CALLCONVENTION OnSnapshotCommitted(TX_CONSTHANDLE hAsyncData, TX_USERPARAM param); + + static bool QueryIsForWindowId(TX_HANDLE hQuery, const TX_CHAR* windowId); + + // mutex protecting the state of the object from race conditions caused by multiple threads. + // (for example, a call to SetActivatableRegions from the main thread while the HandleQuery + // method is iterating through the regions on a worker thread.) + std::mutex _mutex; + std::vector _regions; + TX_CONTEXTHANDLE _context; + TX_TICKET _connectionStateChangedTicket; + TX_TICKET _queryHandlerTicket; + TX_TICKET _eventHandlerTicket; + + // attached window and custom messages. + HWND _hWnd; + UINT _statusChangedMessage; + UINT _focusedRegionChangedMessage; + UINT _regionActivatedMessage; + + // private copy constructor and operator making the class non-copyable (declared but not implemented). + EyeXHost(const EyeXHost&); + EyeXHost& operator = (const EyeXHost&); +}; diff --git a/Tobii-EyeX/samples/ActivatableButtons/Resource.h b/Tobii-EyeX/samples/ActivatableButtons/Resource.h new file mode 100755 index 0000000..0d9e811 Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/Resource.h differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/small.ico b/Tobii-EyeX/samples/ActivatableButtons/small.ico new file mode 100755 index 0000000..449296f Binary files /dev/null and b/Tobii-EyeX/samples/ActivatableButtons/small.ico differ diff --git a/Tobii-EyeX/samples/ActivatableButtons/stdafx.cpp b/Tobii-EyeX/samples/ActivatableButtons/stdafx.cpp new file mode 100755 index 0000000..92e931f --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/stdafx.cpp @@ -0,0 +1,3 @@ +// stdafx.cpp : source file that includes just the standard includes + +#include "stdafx.h" diff --git a/Tobii-EyeX/samples/ActivatableButtons/stdafx.h b/Tobii-EyeX/samples/ActivatableButtons/stdafx.h new file mode 100755 index 0000000..705c92c --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + +// C RunTime Header Files +#include +#include +#include +#include diff --git a/Tobii-EyeX/samples/ActivatableButtons/targetver.h b/Tobii-EyeX/samples/ActivatableButtons/targetver.h new file mode 100755 index 0000000..90e767b --- /dev/null +++ b/Tobii-EyeX/samples/ActivatableButtons/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include -- cgit v1.2.3