1 /************************************************************************************
\r
3 Filename : OVR_CAPIShim.c
\r
4 Content : CAPI DLL user library
\r
5 Created : November 20, 2014
\r
6 Copyright : Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
\r
8 Licensed under the Oculus VR Rift SDK License Version 3.3 (the "License");
\r
9 you may not use the Oculus VR Rift SDK except in compliance with the License,
\r
10 which is provided at the time of installation or download, or which
\r
11 otherwise accompanies this software in either electronic or hard copy form.
\r
13 You may obtain a copy of the License at
\r
15 http://www.oculusvr.com/licenses/LICENSE-3.3
\r
17 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
\r
18 distributed under the License is distributed on an "AS IS" BASIS,
\r
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
20 See the License for the specific language governing permissions and
\r
21 limitations under the License.
\r
23 ************************************************************************************/
\r
25 #include "OVR_CAPI.h"
\r
26 #include "OVR_Version.h"
\r
27 #include "OVR_ErrorCode.h"
\r
28 #include "OVR_CAPI_Prototypes.h"
\r
38 #if defined(_MSC_VER)
\r
39 #pragma warning(push, 0)
\r
41 #include <windows.h>
\r
42 #if defined(_MSC_VER)
\r
43 #pragma warning(pop)
\r
46 #include "../Include/OVR_CAPI_D3D.h"
\r
48 #if defined(__APPLE__)
\r
49 #include <mach-o/dyld.h>
\r
50 #include <sys/syslimits.h>
\r
56 #include <sys/stat.h>
\r
59 #include "../Include/OVR_CAPI_GL.h"
\r
60 #include "../Include/OVR_CAPI_Vk.h"
\r
63 #if defined(_MSC_VER)
\r
64 #pragma warning(push)
\r
65 #pragma warning(disable : 4996) // 'getenv': This function or variable may be unsafe.
\r
69 static const uint8_t OculusSDKUniqueIdentifier[] = {
\r
70 0x9E, 0xB2, 0x0B, 0x1A, 0xB7, 0x97, 0x09, 0x20, 0xE0, 0xFB, 0x83, 0xED, 0xF8, 0x33, 0x5A, 0xEB,
\r
71 0x80, 0x4D, 0x8E, 0x92, 0x20, 0x69, 0x13, 0x56, 0xB4, 0xBB, 0xC4, 0x85, 0xA7, 0x9E, 0xA4, 0xFE,
\r
72 OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_PATCH_VERSION
\r
77 static const uint8_t OculusSDKUniqueIdentifierXORResult = 0xcb;
\r
79 // -----------------------------------------------------------------------------------
\r
80 // ***** OVR_ENABLE_DEVELOPER_SEARCH
\r
82 // If defined then our shared library loading code searches for developer build
\r
85 #if !defined(OVR_ENABLE_DEVELOPER_SEARCH)
\r
88 // -----------------------------------------------------------------------------------
\r
89 // ***** OVR_BUILD_DEBUG
\r
91 // Defines OVR_BUILD_DEBUG when the compiler default debug preprocessor is set.
\r
93 // If you want to control the behavior of these flags, then explicitly define
\r
94 // either -DOVR_BUILD_RELEASE or -DOVR_BUILD_DEBUG in the compiler arguments.
\r
96 #if !defined(OVR_BUILD_DEBUG) && !defined(OVR_BUILD_RELEASE)
\r
97 #if defined(_MSC_VER)
\r
99 #define OVR_BUILD_DEBUG
\r
103 #define OVR_BUILD_DEBUG
\r
108 //-----------------------------------------------------------------------------------
\r
109 // ***** FilePathCharType, ModuleHandleType, ModuleFunctionType
\r
111 #if defined(_WIN32) // We need to use wchar_t on Microsoft platforms, as that's the native file
\r
112 // system character type.
\r
113 #define FilePathCharType \
\r
114 wchar_t // #define instead of typedef because debuggers (VC++, XCode) don't recognize typedef'd
\r
115 // types as a string type.
\r
116 typedef HMODULE ModuleHandleType;
\r
117 typedef FARPROC ModuleFunctionType;
\r
119 #define FilePathCharType char
\r
120 typedef void* ModuleHandleType;
\r
121 typedef void* ModuleFunctionType;
\r
124 #define ModuleHandleTypeNull ((ModuleHandleType)NULL)
\r
125 #define ModuleFunctionTypeNull ((ModuleFunctionType)NULL)
\r
127 //-----------------------------------------------------------------------------------
\r
128 // ***** OVR_MAX_PATH
\r
130 #if !defined(OVR_MAX_PATH)
\r
131 #if defined(_WIN32)
\r
132 #define OVR_MAX_PATH _MAX_PATH
\r
133 #elif defined(__APPLE__)
\r
134 #define OVR_MAX_PATH PATH_MAX
\r
136 #define OVR_MAX_PATH 1024
\r
140 #if !defined(OVR_DLSYM)
\r
141 #if defined(_WIN32)
\r
142 #define OVR_DLSYM(dlImage, name) GetProcAddress(dlImage, name)
\r
144 #define OVR_DLSYM(dlImage, name) dlsym(dlImage, name)
\r
148 static size_t OVR_strlcpy(char* dest, const char* src, size_t destsize) {
\r
149 const char* s = src;
\r
150 size_t n = destsize;
\r
154 if ((*dest++ = *s++) == 0)
\r
166 return (size_t)((s - src) - 1);
\r
169 static size_t OVR_strlcat(char* dest, const char* src, size_t destsize) {
\r
170 const size_t d = destsize ? strlen(dest) : 0;
\r
171 const size_t s = strlen(src);
\r
172 const size_t t = s + d;
\r
175 memcpy(dest + d, src, (s + 1) * sizeof(*src));
\r
178 memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src));
\r
179 dest[destsize - 1] = 0;
\r
186 #if defined(__APPLE__)
\r
188 OVR_strend(const char* pStr, const char* pFind, size_t strLength, size_t findLength) {
\r
189 if (strLength == (size_t)-1)
\r
190 strLength = strlen(pStr);
\r
191 if (findLength == (size_t)-1)
\r
192 findLength = strlen(pFind);
\r
193 if (strLength >= findLength)
\r
194 return (strcmp(pStr + strLength - findLength, pFind) == 0);
\r
198 static ovrBool OVR_isBundleFolder(const char* filePath) {
\r
199 static const char* extensionArray[] = {".app", ".bundle", ".framework", ".plugin", ".kext"};
\r
202 for (i = 0; i < sizeof(extensionArray) / sizeof(extensionArray[0]); i++) {
\r
203 if (OVR_strend(filePath, extensionArray[i], (size_t)-1, (size_t)-1))
\r
211 #if defined(OVR_ENABLE_DEVELOPER_SEARCH)
\r
213 // Returns true if the path begins with the given prefix.
\r
214 // Doesn't support non-ASCII paths, else the return value may be incorrect.
\r
215 static int OVR_PathStartsWith(const FilePathCharType* path, const char* prefix) {
\r
217 if (tolower((unsigned char)*path++) != tolower((unsigned char)*prefix++))
\r
226 static ovrBool OVR_GetCurrentWorkingDirectory(
\r
227 FilePathCharType* directoryPath,
\r
228 size_t directoryPathCapacity) {
\r
229 #if defined(_WIN32)
\r
230 DWORD dwSize = GetCurrentDirectoryW((DWORD)directoryPathCapacity, directoryPath);
\r
232 if ((dwSize > 0) &&
\r
233 (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a \ char.
\r
235 size_t length = wcslen(directoryPath);
\r
237 if ((length == 0) ||
\r
238 ((directoryPath[length - 1] != L'\\') && (directoryPath[length - 1] != L'/'))) {
\r
239 directoryPath[length++] = L'\\';
\r
240 directoryPath[length] = L'\0';
\r
247 char* cwd = getcwd(directoryPath, directoryPathCapacity);
\r
249 if (cwd && directoryPath[0] &&
\r
250 (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a / char.
\r
252 size_t length = strlen(directoryPath);
\r
254 if ((length == 0) || (directoryPath[length - 1] != '/')) {
\r
255 directoryPath[length++] = '/';
\r
256 directoryPath[length] = '\0';
\r
263 if (directoryPathCapacity > 0)
\r
264 directoryPath[0] = '\0';
\r
269 // The appContainer argument is specific currently to only Macintosh. If true and the application is
\r
270 // a .app bundle then it returns the
\r
271 // location of the bundle and not the path to the executable within the bundle. Else return the path
\r
272 // to the executable binary itself.
\r
273 // The moduleHandle refers to the relevant dynamic (a.k.a. shared) library. The main executable is
\r
274 // the main module, and each of the shared
\r
275 // libraries is a module. This way you can specify that you want to know the directory of the given
\r
276 // shared library, which may be different
\r
277 // from the main executable. If the moduleHandle is NULL then the current application module is
\r
279 static ovrBool OVR_GetCurrentApplicationDirectory(
\r
280 FilePathCharType* directoryPath,
\r
281 size_t directoryPathCapacity,
\r
282 ovrBool appContainer,
\r
283 ModuleHandleType moduleHandle) {
\r
284 #if defined(_WIN32)
\r
285 DWORD length = GetModuleFileNameW(moduleHandle, directoryPath, (DWORD)directoryPathCapacity);
\r
288 if ((length != 0) &&
\r
290 (DWORD)directoryPathCapacity)) // If there wasn't an error and there was enough capacity...
\r
292 for (pos = length; (pos > 0) && (directoryPath[pos] != '\\') && (directoryPath[pos] != '/');
\r
294 if ((directoryPath[pos - 1] != '\\') && (directoryPath[pos - 1] != '/'))
\r
295 directoryPath[pos - 1] = 0;
\r
301 (void)appContainer; // Not used on this platform.
\r
303 #elif defined(__APPLE__)
\r
304 uint32_t directoryPathCapacity32 = (uint32_t)directoryPathCapacity;
\r
305 int result = _NSGetExecutablePath(directoryPath, &directoryPathCapacity32);
\r
307 if (result == 0) // If success...
\r
309 char realPath[OVR_MAX_PATH];
\r
311 if (realpath(directoryPath, realPath)) // realpath returns the canonicalized absolute file path.
\r
315 if (appContainer) // If the caller wants the path to the containing bundle...
\r
317 char containerPath[OVR_MAX_PATH];
\r
318 ovrBool pathIsContainer;
\r
320 OVR_strlcpy(containerPath, realPath, sizeof(containerPath));
\r
321 pathIsContainer = OVR_isBundleFolder(containerPath);
\r
323 while (!pathIsContainer && strncmp(containerPath, ".", OVR_MAX_PATH) &&
\r
324 strncmp(containerPath, "/", OVR_MAX_PATH)) // While the container we're looking for
\r
325 // is not found and while the path doesn't
\r
326 // start with a . or /
\r
328 OVR_strlcpy(containerPath, dirname(containerPath), sizeof(containerPath));
\r
329 pathIsContainer = OVR_isBundleFolder(containerPath);
\r
332 if (pathIsContainer)
\r
333 length = OVR_strlcpy(directoryPath, containerPath, directoryPathCapacity);
\r
336 if (length == 0) // If not set above in the appContainer block...
\r
337 length = OVR_strlcpy(directoryPath, realPath, directoryPathCapacity);
\r
339 while (length-- && (directoryPath[length] != '/'))
\r
340 directoryPath[length] =
\r
341 '\0'; // Strip the file name from the file path, leaving a trailing / char.
\r
347 (void)moduleHandle; // Not used on this platform.
\r
350 ssize_t length = readlink("/proc/self/exe", directoryPath, directoryPathCapacity);
\r
354 for (pos = length; (pos > 0) && (directoryPath[pos] != '/'); --pos) {
\r
355 if (directoryPath[pos - 1] != '/')
\r
356 directoryPath[pos - 1] = '\0';
\r
362 (void)appContainer; // Not used on this platform.
\r
363 (void)moduleHandle;
\r
366 if (directoryPathCapacity > 0)
\r
367 directoryPath[0] = '\0';
\r
372 #if defined(_WIN32) || defined(OVR_ENABLE_DEVELOPER_SEARCH) // Used only in these cases
\r
374 // Get the file path to the current module's (DLL or EXE) directory within the current process.
\r
375 // Will be different from the process module handle if the current module is a DLL and is in a
\r
376 // different directory than the EXE module.
\r
377 // If successful then directoryPath will be valid and ovrTrue is returned, else directoryPath will
\r
378 // be empty and ovrFalse is returned.
\r
379 static ovrBool OVR_GetCurrentModuleDirectory(
\r
380 FilePathCharType* directoryPath,
\r
381 size_t directoryPathCapacity,
\r
382 ovrBool appContainer) {
\r
383 #if defined(_WIN32)
\r
385 BOOL result = GetModuleHandleExW(
\r
386 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
\r
387 (LPCWSTR)(uintptr_t)OVR_GetCurrentModuleDirectory,
\r
390 OVR_GetCurrentApplicationDirectory(directoryPath, directoryPathCapacity, ovrTrue, hModule);
\r
392 directoryPath[0] = 0;
\r
394 (void)appContainer;
\r
396 return directoryPath[0] ? ovrTrue : ovrFalse;
\r
398 return OVR_GetCurrentApplicationDirectory(
\r
399 directoryPath, directoryPathCapacity, appContainer, NULL);
\r
405 #if defined(_WIN32)
\r
408 #pragma warning(push)
\r
409 #pragma warning(disable : 4201)
\r
412 #include <softpub.h>
\r
413 #include <wincrypt.h>
\r
416 #pragma warning(pop)
\r
419 // Expected certificates:
\r
420 #define ExpectedNumCertificates 3
\r
421 typedef struct CertificateEntry_t {
\r
422 const wchar_t* Issuer;
\r
423 const wchar_t* Subject;
\r
424 } CertificateEntry;
\r
426 CertificateEntry NewCertificateChain[ExpectedNumCertificates] = {
\r
427 {L"DigiCert SHA2 Assured ID Code Signing CA", L"Oculus VR, LLC"},
\r
428 {L"DigiCert Assured ID Root CA", L"DigiCert SHA2 Assured ID Code Signing CA"},
\r
429 {L"DigiCert Assured ID Root CA", L"DigiCert Assured ID Root CA"},
\r
432 #define CertificateChainCount 1
\r
433 CertificateEntry* AllowedCertificateChains[CertificateChainCount] = {NewCertificateChain};
\r
435 typedef WINCRYPT32API DWORD(WINAPI* PtrCertGetNameStringW)(
\r
436 PCCERT_CONTEXT pCertContext,
\r
440 LPWSTR pszNameString,
\r
441 DWORD cchNameString);
\r
442 typedef LONG(WINAPI* PtrWinVerifyTrust)(HWND hwnd, GUID* pgActionID, LPVOID pWVTData);
\r
443 typedef CRYPT_PROVIDER_DATA*(WINAPI* PtrWTHelperProvDataFromStateData)(HANDLE hStateData);
\r
444 typedef CRYPT_PROVIDER_SGNR*(WINAPI* PtrWTHelperGetProvSignerFromChain)(
\r
445 CRYPT_PROVIDER_DATA* pProvData,
\r
447 BOOL fCounterSigner,
\r
448 DWORD idxCounterSigner);
\r
450 PtrCertGetNameStringW m_PtrCertGetNameStringW = 0;
\r
451 PtrWinVerifyTrust m_PtrWinVerifyTrust = 0;
\r
452 PtrWTHelperProvDataFromStateData m_PtrWTHelperProvDataFromStateData = 0;
\r
453 PtrWTHelperGetProvSignerFromChain m_PtrWTHelperGetProvSignerFromChain = 0;
\r
455 typedef enum ValidateCertificateContentsResult_ {
\r
457 VCCRErrorCertCount = -1,
\r
458 VCCRErrorTrust = -2,
\r
459 VCCRErrorValidation = -3
\r
460 } ValidateCertificateContentsResult;
\r
462 static ValidateCertificateContentsResult ValidateCertificateContents(
\r
463 CertificateEntry* chain,
\r
464 CRYPT_PROVIDER_SGNR* cps) {
\r
467 if (!cps || !cps->pasCertChain || cps->csCertChain != ExpectedNumCertificates) {
\r
468 return VCCRErrorCertCount;
\r
471 for (certIndex = 0; certIndex < ExpectedNumCertificates; ++certIndex) {
\r
472 CRYPT_PROVIDER_CERT* pCertData = &cps->pasCertChain[certIndex];
\r
473 wchar_t subjectStr[400] = {0};
\r
474 wchar_t issuerStr[400] = {0};
\r
476 if ((pCertData->fSelfSigned && !pCertData->fTrustedRoot) || pCertData->fTestCert) {
\r
477 return VCCRErrorTrust;
\r
480 m_PtrCertGetNameStringW(
\r
482 CERT_NAME_ATTR_TYPE,
\r
486 ARRAYSIZE(subjectStr));
\r
488 m_PtrCertGetNameStringW(
\r
490 CERT_NAME_ATTR_TYPE,
\r
491 CERT_NAME_ISSUER_FLAG,
\r
494 ARRAYSIZE(issuerStr));
\r
496 if (wcscmp(subjectStr, chain[certIndex].Subject) != 0 ||
\r
497 wcscmp(issuerStr, chain[certIndex].Issuer) != 0) {
\r
498 return VCCRErrorValidation;
\r
502 return VCCRSuccess;
\r
505 #define OVR_SIGNING_CONVERT_PTR(ftype, fptr, procaddr) \
\r
509 ModuleFunctionType p2; \
\r
515 static BOOL OVR_Win32_SignCheck(FilePathCharType* fullPath, HANDLE hFile) {
\r
516 WINTRUST_FILE_INFO fileData;
\r
517 WINTRUST_DATA wintrustData;
\r
518 GUID actionGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
\r
520 BOOL verified = FALSE;
\r
521 HMODULE libWinTrust = LoadLibraryW(L"wintrust");
\r
522 HMODULE libCrypt32 = LoadLibraryW(L"crypt32");
\r
523 if (libWinTrust == NULL || libCrypt32 == NULL) {
\r
527 OVR_SIGNING_CONVERT_PTR(
\r
528 PtrCertGetNameStringW,
\r
529 m_PtrCertGetNameStringW,
\r
530 GetProcAddress(libCrypt32, "CertGetNameStringW"));
\r
531 OVR_SIGNING_CONVERT_PTR(
\r
532 PtrWinVerifyTrust, m_PtrWinVerifyTrust, GetProcAddress(libWinTrust, "WinVerifyTrust"));
\r
533 OVR_SIGNING_CONVERT_PTR(
\r
534 PtrWTHelperProvDataFromStateData,
\r
535 m_PtrWTHelperProvDataFromStateData,
\r
536 GetProcAddress(libWinTrust, "WTHelperProvDataFromStateData"));
\r
537 OVR_SIGNING_CONVERT_PTR(
\r
538 PtrWTHelperGetProvSignerFromChain,
\r
539 m_PtrWTHelperGetProvSignerFromChain,
\r
540 GetProcAddress(libWinTrust, "WTHelperGetProvSignerFromChain"));
\r
542 if (m_PtrCertGetNameStringW == NULL || m_PtrWinVerifyTrust == NULL ||
\r
543 m_PtrWTHelperProvDataFromStateData == NULL || m_PtrWTHelperGetProvSignerFromChain == NULL) {
\r
547 if (hFile == INVALID_HANDLE_VALUE || fullPath == NULL) {
\r
551 ZeroMemory(&fileData, sizeof(fileData));
\r
552 fileData.cbStruct = sizeof(fileData);
\r
553 fileData.pcwszFilePath = fullPath;
\r
554 fileData.hFile = hFile;
\r
556 ZeroMemory(&wintrustData, sizeof(wintrustData));
\r
557 wintrustData.cbStruct = sizeof(wintrustData);
\r
558 wintrustData.pFile = &fileData;
\r
559 wintrustData.dwUnionChoice = WTD_CHOICE_FILE; // Specify WINTRUST_FILE_INFO.
\r
560 wintrustData.dwUIChoice = WTD_UI_NONE; // Do not display any UI.
\r
561 wintrustData.dwUIContext = WTD_UICONTEXT_EXECUTE; // Hint that this is about app execution.
\r
562 wintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
\r
563 wintrustData.dwProvFlags = WTD_REVOCATION_CHECK_NONE;
\r
564 wintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
\r
565 wintrustData.hWVTStateData = 0;
\r
567 resultStatus = m_PtrWinVerifyTrust(
\r
568 (HWND)INVALID_HANDLE_VALUE, // Do not display any UI.
\r
569 &actionGUID, // V2 verification
\r
572 if (resultStatus == ERROR_SUCCESS && wintrustData.hWVTStateData != 0 &&
\r
573 wintrustData.hWVTStateData != INVALID_HANDLE_VALUE) {
\r
574 CRYPT_PROVIDER_DATA* cpd = m_PtrWTHelperProvDataFromStateData(wintrustData.hWVTStateData);
\r
575 if (cpd && cpd->csSigners == 1) {
\r
576 CRYPT_PROVIDER_SGNR* cps = m_PtrWTHelperGetProvSignerFromChain(cpd, 0, FALSE, 0);
\r
578 for (chainIndex = 0; chainIndex < CertificateChainCount; ++chainIndex) {
\r
579 CertificateEntry* chain = AllowedCertificateChains[chainIndex];
\r
580 if (VCCRSuccess == ValidateCertificateContents(chain, cps)) {
\r
588 wintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
\r
590 m_PtrWinVerifyTrust(
\r
591 (HWND)INVALID_HANDLE_VALUE, // Do not display any UI.
\r
592 &actionGUID, // V2 verification
\r
598 #endif // #if defined(_WIN32)
\r
600 static ModuleHandleType OVR_OpenLibrary(const FilePathCharType* libraryPath, ovrResult* result) {
\r
601 #if defined(_WIN32)
\r
602 DWORD fullPathNameLen = 0;
\r
603 FilePathCharType fullPath[MAX_PATH] = {0};
\r
604 HANDLE hFilePinned = INVALID_HANDLE_VALUE;
\r
605 ModuleHandleType hModule = 0;
\r
607 *result = ovrSuccess;
\r
609 fullPathNameLen = GetFullPathNameW(libraryPath, MAX_PATH, fullPath, 0);
\r
610 if (fullPathNameLen <= 0 || fullPathNameLen >= MAX_PATH) {
\r
611 *result = ovrError_LibPath;
\r
615 hFilePinned = CreateFileW(
\r
616 fullPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 0);
\r
618 if (hFilePinned == INVALID_HANDLE_VALUE) {
\r
619 *result = ovrError_LibPath;
\r
623 if (!OVR_Win32_SignCheck(fullPath, hFilePinned)) {
\r
624 *result = ovrError_LibSignCheck;
\r
625 CloseHandle(hFilePinned);
\r
629 hModule = LoadLibraryW(fullPath);
\r
631 CloseHandle(hFilePinned);
\r
633 if (hModule == NULL) {
\r
634 *result = ovrError_LibLoad;
\r
639 *result = ovrSuccess;
\r
641 // Don't bother trying to dlopen() a file that is not even there.
\r
642 if (access(libraryPath, X_OK | R_OK) != 0) {
\r
643 *result = ovrError_LibPath;
\r
647 dlerror(); // Clear any previous dlopen() errors
\r
649 // Use RTLD_NOW because we don't want unexpected stalls at runtime, and the library isn't very
\r
651 // Use RTLD_LOCAL to avoid unilaterally exporting resolved symbols to the rest of this process.
\r
652 void* lib = dlopen(libraryPath, RTLD_NOW | RTLD_LOCAL);
\r
655 fprintf(stderr, "ERROR: Can't load '%s':\n%s\n", libraryPath, dlerror());
\r
662 static void OVR_CloseLibrary(ModuleHandleType hLibrary) {
\r
664 #if defined(_WIN32)
\r
665 // We may need to consider what to do in the case that the library is in an exception state.
\r
666 // In a Windows C++ DLL, all global objects (including static members of classes) will be
\r
667 // constructed just
\r
668 // before the calling of the DllMain with DLL_PROCESS_ATTACH and they will be destroyed just
\r
670 // the call of the DllMain with DLL_PROCESS_DETACH. We may need to intercept DLL_PROCESS_DETACH
\r
672 // have special handling for the case that the DLL is broken.
\r
673 FreeLibrary(hLibrary);
\r
680 // Returns a valid ModuleHandleType (e.g. Windows HMODULE) or returns ModuleHandleTypeNull (e.g.
\r
682 // The caller is required to eventually call OVR_CloseLibrary on a valid return handle.
\r
684 static ModuleHandleType OVR_FindLibraryPath(
\r
685 int requestedProductVersion,
\r
686 int requestedMajorVersion,
\r
687 FilePathCharType* libraryPath,
\r
688 size_t libraryPathCapacity,
\r
689 ovrResult* result) {
\r
690 ModuleHandleType moduleHandle;
\r
692 FilePathCharType developerDir[OVR_MAX_PATH] = {'\0'};
\r
694 #if defined(_MSC_VER)
\r
695 #if defined(_WIN64)
\r
696 const char* pBitDepth = "64";
\r
698 const char* pBitDepth = "32";
\r
700 #elif defined(__APPLE__)
\r
701 // For Apple platforms we are using a Universal Binary LibOVRRT dylib which has both 32 and 64 in
\r
703 #else // Other Unix.
\r
704 #if defined(__x86_64__)
\r
705 const char* pBitDepth = "64";
\r
707 const char* pBitDepth = "32";
\r
711 (void)requestedProductVersion;
\r
713 *result = ovrError_LibLoad;
\r
714 moduleHandle = ModuleHandleTypeNull;
\r
715 if (libraryPathCapacity)
\r
716 libraryPath[0] = '\0';
\r
718 // Note: OVR_ENABLE_DEVELOPER_SEARCH is deprecated in favor of the simpler LIBOVR_DLL_DIR, as the
\r
720 // case uses of the former created some complications that may be best solved by simply using a
\r
722 // environment variable which the user can set in their debugger or system environment variables.
\r
723 #if (defined(_MSC_VER) || defined(_WIN32)) && !defined(OVR_FILE_PATH_SEPARATOR)
\r
724 #define OVR_FILE_PATH_SEPARATOR "\\"
\r
726 #define OVR_FILE_PATH_SEPARATOR "/"
\r
730 const char* pLibOvrDllDir =
\r
731 getenv("LIBOVR_DLL_DIR"); // Example value: /dev/OculusSDK/Main/LibOVR/Mac/Debug/
\r
733 if (pLibOvrDllDir) {
\r
734 char developerDir8[OVR_MAX_PATH];
\r
735 size_t length = OVR_strlcpy(
\r
738 sizeof(developerDir8)); // If missing a trailing path separator then append one.
\r
740 if ((length > 0) && (length < sizeof(developerDir8)) &&
\r
741 (developerDir8[length - 1] != OVR_FILE_PATH_SEPARATOR[0])) {
\r
742 length = OVR_strlcat(developerDir8, OVR_FILE_PATH_SEPARATOR, sizeof(developerDir8));
\r
744 if (length < sizeof(developerDir8)) {
\r
745 #if defined(_WIN32)
\r
747 for (i = 0; i <= length; ++i) // ASCII conversion of 8 to 16 bit text.
\r
748 developerDir[i] = (FilePathCharType)(uint8_t)developerDir8[i];
\r
750 OVR_strlcpy(developerDir, developerDir8, sizeof(developerDir));
\r
757 // Support checking for a developer library location override via the OVR_SDK_ROOT environment
\r
759 // This pathway is deprecated in favor of using LIBOVR_DLL_DIR instead.
\r
760 #if defined(OVR_ENABLE_DEVELOPER_SEARCH)
\r
761 if (!developerDir[0]) // If not already set by LIBOVR_DLL_PATH...
\r
763 // __FILE__ maps to <sdkRoot>/LibOVR/Src/OVR_CAPIShim.c
\r
764 char sdkRoot[OVR_MAX_PATH];
\r
768 // We assume that __FILE__ returns a full path, which isn't the case for some compilers.
\r
769 // Need to compile with /FC under VC++ for __FILE__ to expand to the full file path.
\r
770 // NOTE: This needs to be fixed on Mac. __FILE__ is not expanded to full path under clang.
\r
771 OVR_strlcpy(sdkRoot, __FILE__, sizeof(sdkRoot));
\r
772 for (i = 0; sdkRoot[i]; ++i)
\r
773 sdkRoot[i] = (char)tolower(sdkRoot[i]); // Microsoft doesn't maintain case.
\r
774 pLibOVR = strstr(sdkRoot, "libovr");
\r
775 if (pLibOVR && (pLibOVR > sdkRoot))
\r
776 pLibOVR[-1] = '\0';
\r
781 // We want to use a developer version of the library only if the application is also being
\r
783 // a developer location. Ideally we would do this by checking that the relative path from the
\r
785 // the shared library is the same at runtime as it was when the executable was first built,
\r
786 // but we don't have
\r
787 // an easy way to do that from here and it would require some runtime help from the
\r
788 // application code.
\r
789 // Instead we verify that the application is simply in the same developer tree that was was
\r
791 // We could put in some additional logic to make it very likely to know if the EXE is in its
\r
792 // original location.
\r
793 FilePathCharType modulePath[OVR_MAX_PATH];
\r
794 const ovrBool pathMatch = OVR_GetCurrentModuleDirectory(modulePath, OVR_MAX_PATH, ovrTrue) &&
\r
795 (OVR_PathStartsWith(modulePath, sdkRoot) == ovrTrue);
\r
796 if (pathMatch == ovrFalse) {
\r
797 sdkRoot[0] = '\0'; // The application module is not in the developer tree, so don't try to
\r
798 // use the developer shared library.
\r
804 #ifndef CONFIG_VARIANT
\r
805 #define CONFIG_VARIANT
\r
808 #if defined(OVR_BUILD_DEBUG)
\r
809 const char* pConfigDirName = "Debug" CONFIG_VARIANT;
\r
811 const char* pConfigDirName = "Release" CONFIG_VARIANT;
\r
814 #undef CONFIG_VARIANT
\r
816 #if defined(_MSC_VER)
\r
817 #if defined(_WIN64)
\r
818 const char* pArchDirName = "x64";
\r
820 const char* pArchDirName = "Win32";
\r
823 #if defined(__x86_64__)
\r
824 const char* pArchDirName = "x86_64";
\r
826 const char* pArchDirName = "i386";
\r
830 #if defined(_MSC_VER) && (_MSC_VER == 1600)
\r
831 const char* pCompilerVersion = "VS2010";
\r
832 #elif defined(_MSC_VER) && (_MSC_VER == 1700)
\r
833 const char* pCompilerVersion = "VS2012";
\r
834 #elif defined(_MSC_VER) && (_MSC_VER == 1800)
\r
835 const char* pCompilerVersion = "VS2013";
\r
836 #elif defined(_MSC_VER) && (_MSC_VER >= 1900)
\r
837 const char* pCompilerVersion = "VS2015";
\r
840 #if defined(_WIN32)
\r
841 int count = swprintf_s(
\r
844 L"%hs\\LibOVR\\Lib\\Windows\\%hs\\%hs\\%hs\\",
\r
849 #elif defined(__APPLE__)
\r
850 // Apple/XCode doesn't let you specify an arch in build paths, which is OK if we build a
\r
851 // universal binary.
\r
852 (void)pArchDirName;
\r
854 snprintf(developerDir, OVR_MAX_PATH, "%s/LibOVR/Lib/Mac/%s/", sdkRoot, pConfigDirName);
\r
856 int count = snprintf(
\r
859 "%s/LibOVR/Lib/Linux/%s/%s/",
\r
867 (int)OVR_MAX_PATH)) // If there was an error or capacity overflow... clear the string.
\r
869 developerDir[0] = '\0';
\r
873 #endif // OVR_ENABLE_DEVELOPER_SEARCH
\r
876 #if !defined(_WIN32)
\r
877 FilePathCharType cwDir[OVR_MAX_PATH]; // Will be filled in below.
\r
878 FilePathCharType appDir[OVR_MAX_PATH];
\r
882 #if defined(_WIN32)
\r
883 // On Windows, only search the developer directory and the usual path
\r
884 const FilePathCharType* directoryArray[2];
\r
885 directoryArray[0] = developerDir; // Developer directory.
\r
886 directoryArray[1] = L""; // No directory, which causes Windows to use the standard search
\r
887 // strategy to find the DLL.
\r
889 #elif defined(__APPLE__)
\r
890 // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dyld.1.html
\r
892 FilePathCharType homeDir[OVR_MAX_PATH];
\r
893 FilePathCharType homeFrameworkDir[OVR_MAX_PATH];
\r
894 const FilePathCharType* directoryArray[5];
\r
895 size_t homeDirLength = 0;
\r
897 const char* pHome = getenv("HOME"); // Try getting the HOME environment variable.
\r
900 homeDirLength = OVR_strlcpy(homeDir, pHome, sizeof(homeDir));
\r
902 // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getpwuid_r.3.html
\r
903 const long pwBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX);
\r
905 if (pwBufferSize != -1) {
\r
906 char pwBuffer[pwBufferSize];
\r
908 struct passwd* pwResult = NULL;
\r
910 if ((getpwuid_r(getuid(), &pw, pwBuffer, pwBufferSize, &pwResult) == 0) && pwResult)
\r
911 homeDirLength = OVR_strlcpy(homeDir, pw.pw_dir, sizeof(homeDir));
\r
915 if (homeDirLength) {
\r
916 if (homeDir[homeDirLength - 1] == '/')
\r
917 homeDir[homeDirLength - 1] = '\0';
\r
918 OVR_strlcpy(homeFrameworkDir, homeDir, sizeof(homeFrameworkDir));
\r
919 OVR_strlcat(homeFrameworkDir, "/Library/Frameworks/", sizeof(homeFrameworkDir));
\r
921 homeFrameworkDir[0] = '\0';
\r
924 directoryArray[0] = cwDir;
\r
925 directoryArray[1] = appDir;
\r
926 directoryArray[2] = homeFrameworkDir; // ~/Library/Frameworks/
\r
927 directoryArray[3] = "/Library/Frameworks/"; // DYLD_FALLBACK_FRAMEWORK_PATH
\r
928 directoryArray[4] = developerDir; // Developer directory.
\r
932 #define STR(x) STR1(x)
\r
934 #define TEST_LIB_DIR STR(LIBDIR) "/"
\r
936 #define TEST_LIB_DIR appDir
\r
939 const FilePathCharType* directoryArray[5];
\r
940 directoryArray[0] = cwDir;
\r
941 directoryArray[1] = TEST_LIB_DIR; // Directory specified by LIBDIR if defined.
\r
942 directoryArray[2] = developerDir; // Developer directory.
\r
943 directoryArray[3] = "/usr/local/lib/";
\r
944 directoryArray[4] = "/usr/lib/";
\r
947 #if !defined(_WIN32)
\r
948 OVR_GetCurrentWorkingDirectory(cwDir, sizeof(cwDir) / sizeof(cwDir[0]));
\r
949 OVR_GetCurrentApplicationDirectory(appDir, sizeof(appDir) / sizeof(appDir[0]), ovrTrue, NULL);
\r
952 // Versioned file expectations.
\r
953 // Windows: LibOVRRT<BIT_DEPTH>_<PRODUCT_VERSION>_<MAJOR_VERSION>.dll
\r
954 // // Example: LibOVRRT64_1_1.dll -- LibOVRRT 64 bit, product 1, major version 1,
\r
955 // minor/patch/build numbers unspecified in the name.
\r
957 // LibOVRRT_<PRODUCT_VERSION>.framework/Versions/<MAJOR_VERSION>/LibOVRRT_<PRODUCT_VERSION>
\r
958 // // We are not presently using the .framework bundle's Current directory to hold the
\r
959 // version number. This may change.
\r
960 // Linux: libOVRRT<BIT_DEPTH>_<PRODUCT_VERSION>.so.<MAJOR_VERSION>
\r
961 // // The file on disk may contain a minor version number, but a symlink is used to map this
\r
962 // major-only version to it.
\r
964 // Since we are manually loading the LibOVR dynamic library, we need to look in various
\r
965 // locations for a file
\r
966 // that matches our requirements. The functionality required is somewhat similar to the
\r
967 // operating system's
\r
968 // dynamic loader functionality. Each OS has some differences in how this is handled.
\r
969 // Future versions of this may iterate over all libOVRRT.so.* files in the directory and use the
\r
970 // one that matches our requirements.
\r
972 // We need to look for a library that matches the product version and major version of the
\r
973 // caller's request,
\r
974 // and that library needs to support a minor version that is >= the requested minor version.
\r
976 // don't test the minor version here, as the library is named based only on the product and
\r
978 // Currently the minor version test is handled via the initialization of the library and the
\r
980 // fails if minor version cannot be supported by the library. The reason this is done during
\r
982 // is that the library can at runtime support multiple minor versions based on the user's
\r
984 // external user, all that matters it that they call ovr_Initialize with a requested version and
\r
988 // The product version is something that is at a higher level than the major version, and is not
\r
989 // something that's
\r
990 // always seen in libraries (an example is the well-known LibXml2 library, in which the 2 is
\r
991 // essentially the product version).
\r
993 for (i = 0; i < sizeof(directoryArray) / sizeof(directoryArray[0]); ++i) {
\r
994 #if defined(_WIN32)
\r
995 printfResult = swprintf(
\r
997 libraryPathCapacity,
\r
998 L"%lsLibOVRRT%hs_%d.dll",
\r
1001 requestedMajorVersion);
\r
1003 if (*directoryArray[i] == 0) {
\r
1005 FilePathCharType foundPath[MAX_PATH] = {0};
\r
1006 DWORD searchResult = SearchPathW(NULL, libraryPath, NULL, MAX_PATH, foundPath, NULL);
\r
1007 if (searchResult <= 0 || searchResult >= libraryPathCapacity) {
\r
1010 foundPath[MAX_PATH - 1] = 0;
\r
1011 for (k = 0; k < MAX_PATH; ++k) {
\r
1012 libraryPath[k] = foundPath[k];
\r
1016 #elif defined(__APPLE__)
\r
1017 // https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/VersionInformation.html
\r
1018 // Macintosh application bundles have the option of embedding dependent frameworks within the
\r
1020 // bundle itself. A problem with that is that it doesn't support vendor-supplied updates to
\r
1023 snprintf(libraryPath, libraryPathCapacity, "%sLibOVRRT.dylib", directoryArray[i]);
\r
1026 // Applications that depend on the OS (e.g. ld-linux / ldd) can rely on the library being in a
\r
1027 // common location
\r
1028 // such as /usr/lib or can rely on the -rpath linker option to embed a path for the OS to
\r
1029 // check for the library,
\r
1030 // or can rely on the LD_LIBRARY_PATH environment variable being set. It's generally not
\r
1031 // recommended that applications
\r
1032 // depend on LD_LIBRARY_PATH be globally modified, partly due to potentialy security issues.
\r
1033 // Currently we check the current application directory, current working directory, and then
\r
1034 // /usr/lib and possibly others.
\r
1035 printfResult = snprintf(
\r
1037 libraryPathCapacity,
\r
1038 "%slibOVRRT%s.so.%d",
\r
1039 directoryArray[i],
\r
1041 requestedMajorVersion);
\r
1044 if ((printfResult >= 0) && (printfResult < (int)libraryPathCapacity)) {
\r
1045 moduleHandle = OVR_OpenLibrary(libraryPath, result);
\r
1046 if (moduleHandle != ModuleHandleTypeNull)
\r
1047 return moduleHandle;
\r
1052 return moduleHandle;
\r
1055 //-----------------------------------------------------------------------------------
\r
1058 // global handle to the LivOVR shared library.
\r
1060 static ModuleHandleType hLibOVR = NULL;
\r
1062 // This function is currently unsupported.
\r
1063 ModuleHandleType ovr_GetLibOVRRTHandle() {
\r
1067 //-----------------------------------------------------------------------------------
\r
1068 // ***** Function declarations
\r
1071 //-----------------------------------------------------------------------------------
\r
1072 // ***** OVR_DECLARE_IMPORT
\r
1074 // Creates a pointer and loader value union for each entry in OVR_LIST_APIS()
\r
1077 #define OVR_DECLARE_IMPORT(ReturnValue, FunctionName, OptionalVersion, Arguments) \
\r
1079 ReturnValue(OVR_CDECL* Ptr) Arguments; \
\r
1080 ModuleFunctionType Symbol; \
\r
1083 #define OVR_IGNORE_IMPORT(ReturnValue, FunctionName, OptionalVersion, Arguments)
\r
1085 //-----------------------------------------------------------------------------------
\r
1086 // ***** API - a structure with each API entrypoint as a FunctionName.Ptr and FunctionName.Symbol
\r
1090 static struct { OVR_LIST_APIS(OVR_DECLARE_IMPORT, OVR_IGNORE_IMPORT) } API = {{NULL}};
\r
1092 static void OVR_UnloadSharedLibrary() {
\r
1093 memset(&API, 0, sizeof(API));
\r
1095 OVR_CloseLibrary(hLibOVR);
\r
1099 static ovrResult OVR_LoadSharedLibrary(int requestedProductVersion, int requestedMajorVersion) {
\r
1100 FilePathCharType filePath[OVR_MAX_PATH];
\r
1101 const char* SymbolName = NULL;
\r
1102 ovrResult result = ovrSuccess;
\r
1107 hLibOVR = OVR_FindLibraryPath(
\r
1108 requestedProductVersion,
\r
1109 requestedMajorVersion,
\r
1111 sizeof(filePath) / sizeof(filePath[0]),
\r
1117 // Zero the API table just to be paranoid
\r
1118 memset(&API, 0, sizeof(API));
\r
1120 // Load the current API entrypoint using the catenated FunctionName and OptionalVersion
\r
1121 #define OVR_GETFUNCTION(ReturnValue, FunctionName, OptionalVersion, Arguments) \
\r
1122 SymbolName = #FunctionName #OptionalVersion; \
\r
1123 API.FunctionName.Symbol = OVR_DLSYM(hLibOVR, SymbolName); \
\r
1124 if (!API.FunctionName.Symbol) { \
\r
1125 fprintf(stderr, "Unable to locate symbol: %s\n", SymbolName); \
\r
1126 result = ovrError_LibSymbols; \
\r
1127 goto FailedToLoadSymbol; \
\r
1130 OVR_LIST_APIS(OVR_GETFUNCTION, OVR_IGNORE_IMPORT)
\r
1132 #undef OVR_GETFUNCTION
\r
1136 FailedToLoadSymbol:
\r
1137 // Check SymbolName for the name of the API which failed to load
\r
1138 OVR_UnloadSharedLibrary();
\r
1142 // These defaults are also in CAPI.cpp
\r
1143 static const ovrInitParams DefaultParams = {
\r
1144 ovrInit_RequestVersion, // Flags
\r
1145 OVR_MINOR_VERSION, // RequestedMinorVersion
\r
1148 0, // ConnectionTimeoutSeconds
\r
1149 OVR_ON64("") // pad0
\r
1152 // Don't put this on the heap
\r
1153 static ovrErrorInfo LastInitializeErrorInfo = {ovrError_NotInitialized,
\r
1154 "ovr_Initialize never called"};
\r
1156 OVR_PUBLIC_FUNCTION(ovrResult) ovr_Initialize(const ovrInitParams* inputParams) {
\r
1158 ovrInitParams params;
\r
1160 typedef void(OVR_CDECL * ovr_ReportClientInfoType)(
\r
1161 unsigned int compilerVersion,
\r
1162 int productVersion,
\r
1167 ovr_ReportClientInfoType reportClientInfo;
\r
1169 // Do something with our version signature hash to prevent
\r
1170 // it from being optimized out. In this case, compute
\r
1175 for (i = 0; i < (sizeof(OculusSDKUniqueIdentifier) - 3);
\r
1176 ++i) // Minus 3 because we have trailing OVR_MAJOR_VERSION, OVR_MINOR_VERSION,
\r
1177 // OVR_PATCH_VERSION which vary per version.
\r
1179 crc ^= OculusSDKUniqueIdentifier[i];
\r
1182 assert(crc == OculusSDKUniqueIdentifierXORResult);
\r
1183 if (crc != OculusSDKUniqueIdentifierXORResult) {
\r
1184 return ovrError_Initialize;
\r
1187 if (!inputParams) {
\r
1188 params = DefaultParams;
\r
1190 params = *inputParams;
\r
1192 // If not requesting a particular minor version,
\r
1193 if (!(params.Flags & ovrInit_RequestVersion)) {
\r
1194 // Enable requesting the default minor version.
\r
1195 params.Flags |= ovrInit_RequestVersion;
\r
1196 params.RequestedMinorVersion = OVR_MINOR_VERSION;
\r
1200 // Clear non-writable bits provided by client code.
\r
1201 params.Flags &= ovrinit_WritableBits;
\r
1205 // Error out if the requested minor version is less than our lowest deemed compatible version
\r
1206 // denoted by OVR_MIN_REQUESTABLE_MINOR_VERSION.
\r
1207 // Note: This code has to be in the shim as we want to enforce usage of the new API versions for
\r
1208 // applications being recompiled while maintaining backwards compatibility with older apps
\r
1209 if (params.RequestedMinorVersion < OVR_MIN_REQUESTABLE_MINOR_VERSION) {
\r
1210 // Requested LibOVRRT version too low
\r
1211 result = ovrError_LibVersion;
\r
1215 // By design we ignore the build version in the library search.
\r
1216 result = OVR_LoadSharedLibrary(OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION);
\r
1217 if (result != ovrSuccess)
\r
1220 result = API.ovr_Initialize.Ptr(¶ms);
\r
1222 if (result != ovrSuccess) {
\r
1223 // Stash the last initialization error for the shim to return if
\r
1224 // ovr_GetLastErrorInfo is called after we unload the dll below
\r
1225 if (API.ovr_GetLastErrorInfo.Ptr) {
\r
1226 API.ovr_GetLastErrorInfo.Ptr(&LastInitializeErrorInfo);
\r
1228 OVR_UnloadSharedLibrary();
\r
1231 reportClientInfo =
\r
1232 (ovr_ReportClientInfoType)(uintptr_t)OVR_DLSYM(hLibOVR, "ovr_ReportClientInfo");
\r
1234 if (reportClientInfo) {
\r
1235 unsigned int mscFullVer = 0;
\r
1236 #if defined(_MSC_FULL_VER)
\r
1237 mscFullVer = _MSC_FULL_VER;
\r
1238 #endif // _MSC_FULL_VER
\r
1242 OVR_PRODUCT_VERSION,
\r
1243 OVR_MAJOR_VERSION,
\r
1244 OVR_MINOR_VERSION,
\r
1245 OVR_PATCH_VERSION,
\r
1246 OVR_BUILD_NUMBER);
\r
1252 OVR_PUBLIC_FUNCTION(void) ovr_Shutdown() {
\r
1253 if (!API.ovr_Shutdown.Ptr)
\r
1255 API.ovr_Shutdown.Ptr();
\r
1256 OVR_UnloadSharedLibrary();
\r
1259 OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString() {
\r
1260 // We don't directly return the value of the DLL API.ovr_GetVersionString.Ptr call,
\r
1261 // because that call returns a pointer to memory within the DLL. If the DLL goes
\r
1262 // away then that pointer becomes invalid while the process may still be holding
\r
1263 // onto it. So we save a local copy of it which is always valid.
\r
1264 static char dllVersionStringLocal[32];
\r
1265 const char* dllVersionString;
\r
1267 if (!API.ovr_GetVersionString.Ptr)
\r
1268 return "(Unable to load LibOVR)";
\r
1270 dllVersionString = API.ovr_GetVersionString.Ptr(); // Guaranteed to always be valid.
\r
1271 assert(dllVersionString != NULL);
\r
1272 OVR_strlcpy(dllVersionStringLocal, dllVersionString, sizeof(dllVersionStringLocal));
\r
1274 return dllVersionStringLocal;
\r
1277 OVR_PUBLIC_FUNCTION(void) ovr_GetLastErrorInfo(ovrErrorInfo* errorInfo) {
\r
1278 if (!API.ovr_GetLastErrorInfo.Ptr) {
\r
1279 *errorInfo = LastInitializeErrorInfo;
\r
1281 API.ovr_GetLastErrorInfo.Ptr(errorInfo);
\r
1284 OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session) {
\r
1285 if (!API.ovr_GetHmdDesc.Ptr) {
\r
1286 ovrHmdDesc hmdDesc;
\r
1287 memset(&hmdDesc, 0, sizeof(hmdDesc));
\r
1288 hmdDesc.Type = ovrHmd_None;
\r
1292 return API.ovr_GetHmdDesc.Ptr(session);
\r
1295 OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetTrackerCount(ovrSession session) {
\r
1296 if (!API.ovr_GetTrackerCount.Ptr) {
\r
1300 return API.ovr_GetTrackerCount.Ptr(session);
\r
1303 OVR_PUBLIC_FUNCTION(ovrTrackerDesc)
\r
1304 ovr_GetTrackerDesc(ovrSession session, unsigned int trackerDescIndex) {
\r
1305 if (!API.ovr_GetTrackerDesc.Ptr) {
\r
1306 ovrTrackerDesc trackerDesc;
\r
1307 memset(&trackerDesc, 0, sizeof(trackerDesc));
\r
1308 return trackerDesc;
\r
1311 return API.ovr_GetTrackerDesc.Ptr(session, trackerDescIndex);
\r
1314 OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid) {
\r
1315 if (!API.ovr_Create.Ptr)
\r
1316 return ovrError_NotInitialized;
\r
1317 return API.ovr_Create.Ptr(pSession, pLuid);
\r
1320 OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session) {
\r
1321 if (!API.ovr_Destroy.Ptr)
\r
1323 API.ovr_Destroy.Ptr(session);
\r
1326 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1327 ovr_GetSessionStatus(ovrSession session, ovrSessionStatus* sessionStatus) {
\r
1328 if (!API.ovr_GetSessionStatus.Ptr) {
\r
1329 if (sessionStatus) {
\r
1330 sessionStatus->IsVisible = ovrFalse;
\r
1331 sessionStatus->HmdPresent = ovrFalse;
\r
1332 sessionStatus->HmdMounted = ovrFalse;
\r
1333 sessionStatus->ShouldQuit = ovrFalse;
\r
1334 sessionStatus->DisplayLost = ovrFalse;
\r
1335 sessionStatus->ShouldRecenter = ovrFalse;
\r
1336 sessionStatus->HasInputFocus = ovrFalse;
\r
1337 sessionStatus->OverlayPresent = ovrFalse;
\r
1338 sessionStatus->DepthRequested = ovrFalse;
\r
1341 return ovrError_NotInitialized;
\r
1344 return API.ovr_GetSessionStatus.Ptr(session, sessionStatus);
\r
1348 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1349 ovr_IsExtensionSupported(ovrSession session, ovrExtensions extension, ovrBool* extensionSupported) {
\r
1350 if (!API.ovr_IsExtensionSupported.Ptr)
\r
1351 return ovrError_NotInitialized;
\r
1352 return API.ovr_IsExtensionSupported.Ptr(session, extension, extensionSupported);
\r
1355 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1356 ovr_EnableExtension(ovrSession session, ovrExtensions extension) {
\r
1357 if (!API.ovr_EnableExtension.Ptr)
\r
1358 return ovrError_NotInitialized;
\r
1359 return API.ovr_EnableExtension.Ptr(session, extension);
\r
1362 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1363 ovr_SetTrackingOriginType(ovrSession session, ovrTrackingOrigin origin) {
\r
1364 if (!API.ovr_SetTrackingOriginType.Ptr)
\r
1365 return ovrError_NotInitialized;
\r
1366 return API.ovr_SetTrackingOriginType.Ptr(session, origin);
\r
1369 OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession session) {
\r
1370 if (!API.ovr_GetTrackingOriginType.Ptr)
\r
1371 return ovrTrackingOrigin_EyeLevel;
\r
1372 return API.ovr_GetTrackingOriginType.Ptr(session);
\r
1375 OVR_PUBLIC_FUNCTION(ovrResult) ovr_RecenterTrackingOrigin(ovrSession session) {
\r
1376 if (!API.ovr_RecenterTrackingOrigin.Ptr)
\r
1377 return ovrError_NotInitialized;
\r
1378 return API.ovr_RecenterTrackingOrigin.Ptr(session);
\r
1381 OVR_PUBLIC_FUNCTION(ovrResult) ovr_SpecifyTrackingOrigin(ovrSession session, ovrPosef originPose) {
\r
1382 if (!API.ovr_SpecifyTrackingOrigin.Ptr)
\r
1383 return ovrError_NotInitialized;
\r
1384 return API.ovr_SpecifyTrackingOrigin.Ptr(session, originPose);
\r
1387 OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session) {
\r
1388 if (!API.ovr_ClearShouldRecenterFlag.Ptr)
\r
1390 API.ovr_ClearShouldRecenterFlag.Ptr(session);
\r
1393 OVR_PUBLIC_FUNCTION(ovrTrackingState)
\r
1394 ovr_GetTrackingState(ovrSession session, double absTime, ovrBool latencyMarker) {
\r
1395 if (!API.ovr_GetTrackingState.Ptr) {
\r
1396 ovrTrackingState nullTrackingState;
\r
1397 memset(&nullTrackingState, 0, sizeof(nullTrackingState));
\r
1398 return nullTrackingState;
\r
1401 return API.ovr_GetTrackingState.Ptr(session, absTime, latencyMarker);
\r
1404 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1405 ovr_GetDevicePoses(
\r
1406 ovrSession session,
\r
1407 ovrTrackedDeviceType* deviceTypes,
\r
1410 ovrPoseStatef* outDevicePoses) {
\r
1411 if (!API.ovr_GetDevicePoses.Ptr)
\r
1412 return ovrError_NotInitialized;
\r
1413 return API.ovr_GetDevicePoses.Ptr(session, deviceTypes, deviceCount, absTime, outDevicePoses);
\r
1416 OVR_PUBLIC_FUNCTION(ovrTrackingState)
\r
1417 ovr_GetTrackingStateWithSensorData(
\r
1418 ovrSession session,
\r
1420 ovrBool latencyMarker,
\r
1421 ovrSensorData* sensorData) {
\r
1422 if (!API.ovr_GetTrackingStateWithSensorData.Ptr) {
\r
1423 ovrTrackingState nullTrackingState;
\r
1424 memset(&nullTrackingState, 0, sizeof(nullTrackingState));
\r
1426 memset(&sensorData, 0, sizeof(sensorData));
\r
1427 return nullTrackingState;
\r
1430 return API.ovr_GetTrackingStateWithSensorData.Ptr(session, absTime, latencyMarker, sensorData);
\r
1433 OVR_PUBLIC_FUNCTION(ovrTrackerPose)
\r
1434 ovr_GetTrackerPose(ovrSession session, unsigned int trackerPoseIndex) {
\r
1435 if (!API.ovr_GetTrackerPose.Ptr) {
\r
1436 ovrTrackerPose nullTrackerPose;
\r
1437 memset(&nullTrackerPose, 0, sizeof(nullTrackerPose));
\r
1438 return nullTrackerPose;
\r
1441 return API.ovr_GetTrackerPose.Ptr(session, trackerPoseIndex);
\r
1444 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1445 ovr_GetInputState(ovrSession session, ovrControllerType controllerType, ovrInputState* inputState) {
\r
1446 if (!API.ovr_GetInputState.Ptr) {
\r
1448 memset(inputState, 0, sizeof(ovrInputState));
\r
1449 return ovrError_NotInitialized;
\r
1451 return API.ovr_GetInputState.Ptr(session, controllerType, inputState);
\r
1454 OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession session) {
\r
1455 if (!API.ovr_GetConnectedControllerTypes.Ptr) {
\r
1458 return API.ovr_GetConnectedControllerTypes.Ptr(session);
\r
1461 OVR_PUBLIC_FUNCTION(ovrTouchHapticsDesc)
\r
1462 ovr_GetTouchHapticsDesc(ovrSession session, ovrControllerType controllerType) {
\r
1463 if (!API.ovr_GetTouchHapticsDesc.Ptr) {
\r
1464 ovrTouchHapticsDesc nullDesc;
\r
1465 memset(&nullDesc, 0, sizeof(nullDesc));
\r
1469 return API.ovr_GetTouchHapticsDesc.Ptr(session, controllerType);
\r
1472 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1473 ovr_SetControllerVibration(
\r
1474 ovrSession session,
\r
1475 ovrControllerType controllerType,
\r
1477 float amplitude) {
\r
1478 if (!API.ovr_SetControllerVibration.Ptr)
\r
1479 return ovrError_NotInitialized;
\r
1481 return API.ovr_SetControllerVibration.Ptr(session, controllerType, frequency, amplitude);
\r
1484 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1485 ovr_SubmitControllerVibration(
\r
1486 ovrSession session,
\r
1487 ovrControllerType controllerType,
\r
1488 const ovrHapticsBuffer* buffer) {
\r
1489 if (!API.ovr_SubmitControllerVibration.Ptr)
\r
1490 return ovrError_NotInitialized;
\r
1492 return API.ovr_SubmitControllerVibration.Ptr(session, controllerType, buffer);
\r
1495 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1496 ovr_GetControllerVibrationState(
\r
1497 ovrSession session,
\r
1498 ovrControllerType controllerType,
\r
1499 ovrHapticsPlaybackState* outState) {
\r
1500 if (!API.ovr_GetControllerVibrationState.Ptr)
\r
1501 return ovrError_NotInitialized;
\r
1503 return API.ovr_GetControllerVibrationState.Ptr(session, controllerType, outState);
\r
1506 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1508 ovrSession session,
\r
1509 ovrTrackedDeviceType deviceBitmask,
\r
1510 ovrBoundaryType singleBoundaryType,
\r
1511 ovrBoundaryTestResult* outTestResult) {
\r
1512 if (!API.ovr_TestBoundary.Ptr)
\r
1513 return ovrError_NotInitialized;
\r
1515 return API.ovr_TestBoundary.Ptr(session, deviceBitmask, singleBoundaryType, outTestResult);
\r
1518 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1519 ovr_TestBoundaryPoint(
\r
1520 ovrSession session,
\r
1521 const ovrVector3f* point,
\r
1522 ovrBoundaryType singleBoundaryType,
\r
1523 ovrBoundaryTestResult* outTestResult) {
\r
1524 if (!API.ovr_TestBoundaryPoint.Ptr)
\r
1525 return ovrError_NotInitialized;
\r
1527 return API.ovr_TestBoundaryPoint.Ptr(session, point, singleBoundaryType, outTestResult);
\r
1530 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1531 ovr_SetBoundaryLookAndFeel(ovrSession session, const ovrBoundaryLookAndFeel* lookAndFeel) {
\r
1532 if (!API.ovr_SetBoundaryLookAndFeel.Ptr)
\r
1533 return ovrError_NotInitialized;
\r
1535 return API.ovr_SetBoundaryLookAndFeel.Ptr(session, lookAndFeel);
\r
1538 OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetBoundaryLookAndFeel(ovrSession session) {
\r
1539 if (!API.ovr_ResetBoundaryLookAndFeel.Ptr)
\r
1540 return ovrError_NotInitialized;
\r
1542 return API.ovr_ResetBoundaryLookAndFeel.Ptr(session);
\r
1545 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1546 ovr_GetBoundaryGeometry(
\r
1547 ovrSession session,
\r
1548 ovrBoundaryType singleBoundaryType,
\r
1549 ovrVector3f* outFloorPoints,
\r
1550 int* outFloorPointsCount) {
\r
1551 if (!API.ovr_GetBoundaryGeometry.Ptr)
\r
1552 return ovrError_NotInitialized;
\r
1554 return API.ovr_GetBoundaryGeometry.Ptr(
\r
1555 session, singleBoundaryType, outFloorPoints, outFloorPointsCount);
\r
1558 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1559 ovr_GetBoundaryDimensions(
\r
1560 ovrSession session,
\r
1561 ovrBoundaryType singleBoundaryType,
\r
1562 ovrVector3f* outDimensions) {
\r
1563 if (!API.ovr_GetBoundaryDimensions.Ptr)
\r
1564 return ovrError_NotInitialized;
\r
1566 return API.ovr_GetBoundaryDimensions.Ptr(session, singleBoundaryType, outDimensions);
\r
1569 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetBoundaryVisible(ovrSession session, ovrBool* outIsVisible) {
\r
1570 if (!API.ovr_GetBoundaryVisible.Ptr)
\r
1571 return ovrError_NotInitialized;
\r
1573 return API.ovr_GetBoundaryVisible.Ptr(session, outIsVisible);
\r
1576 OVR_PUBLIC_FUNCTION(ovrResult) ovr_RequestBoundaryVisible(ovrSession session, ovrBool visible) {
\r
1577 if (!API.ovr_RequestBoundaryVisible.Ptr)
\r
1578 return ovrError_NotInitialized;
\r
1580 return API.ovr_RequestBoundaryVisible.Ptr(session, visible);
\r
1583 OVR_PUBLIC_FUNCTION(ovrSizei)
\r
1584 ovr_GetFovTextureSize(
\r
1585 ovrSession session,
\r
1588 float pixelsPerDisplayPixel) {
\r
1589 if (!API.ovr_GetFovTextureSize.Ptr) {
\r
1590 ovrSizei nullSize;
\r
1591 memset(&nullSize, 0, sizeof(nullSize));
\r
1595 return API.ovr_GetFovTextureSize.Ptr(session, eye, fov, pixelsPerDisplayPixel);
\r
1598 #if defined(_WIN32)
\r
1599 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1600 ovr_CreateTextureSwapChainDX(
\r
1601 ovrSession session,
\r
1603 const ovrTextureSwapChainDesc* desc,
\r
1604 ovrTextureSwapChain* outTextureSet) {
\r
1605 if (!API.ovr_CreateTextureSwapChainDX.Ptr)
\r
1606 return ovrError_NotInitialized;
\r
1608 return API.ovr_CreateTextureSwapChainDX.Ptr(session, d3dPtr, desc, outTextureSet);
\r
1611 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1612 ovr_CreateMirrorTextureDX(
\r
1613 ovrSession session,
\r
1615 const ovrMirrorTextureDesc* desc,
\r
1616 ovrMirrorTexture* outMirrorTexture) {
\r
1617 if (!API.ovr_CreateMirrorTextureDX.Ptr)
\r
1618 return ovrError_NotInitialized;
\r
1620 return API.ovr_CreateMirrorTextureDX.Ptr(session, d3dPtr, desc, outMirrorTexture);
\r
1623 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1624 ovr_CreateMirrorTextureWithOptionsDX(
\r
1625 ovrSession session,
\r
1627 const ovrMirrorTextureDesc* desc,
\r
1628 ovrMirrorTexture* outMirrorTexture) {
\r
1629 if (!API.ovr_CreateMirrorTextureWithOptionsDX.Ptr)
\r
1630 return ovrError_NotInitialized;
\r
1632 return API.ovr_CreateMirrorTextureWithOptionsDX.Ptr(session, d3dPtr, desc, outMirrorTexture);
\r
1635 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1636 ovr_GetTextureSwapChainBufferDX(
\r
1637 ovrSession session,
\r
1638 ovrTextureSwapChain chain,
\r
1641 void** ppObject) {
\r
1642 if (!API.ovr_GetTextureSwapChainBufferDX.Ptr)
\r
1643 return ovrError_NotInitialized;
\r
1645 return API.ovr_GetTextureSwapChainBufferDX.Ptr(session, chain, index, iid, ppObject);
\r
1648 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1649 ovr_GetMirrorTextureBufferDX(
\r
1650 ovrSession session,
\r
1651 ovrMirrorTexture mirror,
\r
1653 void** ppObject) {
\r
1654 if (!API.ovr_GetMirrorTextureBufferDX.Ptr)
\r
1655 return ovrError_NotInitialized;
\r
1657 return API.ovr_GetMirrorTextureBufferDX.Ptr(session, mirror, iid, ppObject);
\r
1660 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(unsigned int* deviceOutId) {
\r
1661 if (!API.ovr_GetAudioDeviceOutWaveId.Ptr)
\r
1662 return ovrError_NotInitialized;
\r
1664 return API.ovr_GetAudioDeviceOutWaveId.Ptr(deviceOutId);
\r
1667 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(unsigned int* deviceInId) {
\r
1668 if (!API.ovr_GetAudioDeviceInWaveId.Ptr)
\r
1669 return ovrError_NotInitialized;
\r
1671 return API.ovr_GetAudioDeviceInWaveId.Ptr(deviceInId);
\r
1674 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR* deviceOutStrBuffer) {
\r
1675 if (!API.ovr_GetAudioDeviceOutGuidStr.Ptr)
\r
1676 return ovrError_NotInitialized;
\r
1678 return API.ovr_GetAudioDeviceOutGuidStr.Ptr(deviceOutStrBuffer);
\r
1681 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid) {
\r
1682 if (!API.ovr_GetAudioDeviceOutGuid.Ptr)
\r
1683 return ovrError_NotInitialized;
\r
1685 return API.ovr_GetAudioDeviceOutGuid.Ptr(deviceOutGuid);
\r
1688 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR* deviceInStrBuffer) {
\r
1689 if (!API.ovr_GetAudioDeviceInGuidStr.Ptr)
\r
1690 return ovrError_NotInitialized;
\r
1692 return API.ovr_GetAudioDeviceInGuidStr.Ptr(deviceInStrBuffer);
\r
1695 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid) {
\r
1696 if (!API.ovr_GetAudioDeviceInGuid.Ptr)
\r
1697 return ovrError_NotInitialized;
\r
1699 return API.ovr_GetAudioDeviceInGuid.Ptr(deviceInGuid);
\r
1704 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1705 ovr_CreateTextureSwapChainGL(
\r
1706 ovrSession session,
\r
1707 const ovrTextureSwapChainDesc* desc,
\r
1708 ovrTextureSwapChain* outTextureSet) {
\r
1709 if (!API.ovr_CreateTextureSwapChainGL.Ptr)
\r
1710 return ovrError_NotInitialized;
\r
1712 return API.ovr_CreateTextureSwapChainGL.Ptr(session, desc, outTextureSet);
\r
1715 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1716 ovr_CreateMirrorTextureGL(
\r
1717 ovrSession session,
\r
1718 const ovrMirrorTextureDesc* desc,
\r
1719 ovrMirrorTexture* outMirrorTexture) {
\r
1720 if (!API.ovr_CreateMirrorTextureGL.Ptr)
\r
1721 return ovrError_NotInitialized;
\r
1723 return API.ovr_CreateMirrorTextureGL.Ptr(session, desc, outMirrorTexture);
\r
1726 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1727 ovr_CreateMirrorTextureWithOptionsGL(
\r
1728 ovrSession session,
\r
1729 const ovrMirrorTextureDesc* desc,
\r
1730 ovrMirrorTexture* outMirrorTexture) {
\r
1731 if (!API.ovr_CreateMirrorTextureWithOptionsGL.Ptr)
\r
1732 return ovrError_NotInitialized;
\r
1734 return API.ovr_CreateMirrorTextureWithOptionsGL.Ptr(session, desc, outMirrorTexture);
\r
1737 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1738 ovr_GetTextureSwapChainBufferGL(
\r
1739 ovrSession session,
\r
1740 ovrTextureSwapChain chain,
\r
1742 unsigned int* texId) {
\r
1743 if (!API.ovr_GetTextureSwapChainBufferGL.Ptr)
\r
1744 return ovrError_NotInitialized;
\r
1746 return API.ovr_GetTextureSwapChainBufferGL.Ptr(session, chain, index, texId);
\r
1749 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1750 ovr_GetMirrorTextureBufferGL(ovrSession session, ovrMirrorTexture mirror, unsigned int* texId) {
\r
1751 if (!API.ovr_GetMirrorTextureBufferGL.Ptr)
\r
1752 return ovrError_NotInitialized;
\r
1754 return API.ovr_GetMirrorTextureBufferGL.Ptr(session, mirror, texId);
\r
1757 #if !defined(OSX_UNIMPLEMENTED)
\r
1758 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1759 ovr_GetInstanceExtensionsVk(
\r
1760 ovrGraphicsLuid luid,
\r
1761 char* extensionNames,
\r
1762 uint32_t* inoutExtensionNamesSize) {
\r
1763 if (!API.ovr_GetInstanceExtensionsVk.Ptr)
\r
1764 return ovrError_NotInitialized;
\r
1766 return API.ovr_GetInstanceExtensionsVk.Ptr(luid, extensionNames, inoutExtensionNamesSize);
\r
1769 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1770 ovr_GetDeviceExtensionsVk(
\r
1771 ovrGraphicsLuid luid,
\r
1772 char* extensionNames,
\r
1773 uint32_t* inoutExtensionNamesSize) {
\r
1774 if (!API.ovr_GetDeviceExtensionsVk.Ptr)
\r
1775 return ovrError_NotInitialized;
\r
1777 return API.ovr_GetDeviceExtensionsVk.Ptr(luid, extensionNames, inoutExtensionNamesSize);
\r
1780 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1781 ovr_GetSessionPhysicalDeviceVk(
\r
1782 ovrSession session,
\r
1783 ovrGraphicsLuid luid,
\r
1784 VkInstance instance,
\r
1785 VkPhysicalDevice* out_physicalDevice) {
\r
1786 if (!API.ovr_GetSessionPhysicalDeviceVk.Ptr)
\r
1787 return ovrError_NotInitialized;
\r
1789 return API.ovr_GetSessionPhysicalDeviceVk.Ptr(session, luid, instance, out_physicalDevice);
\r
1792 OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetSynchronizationQueueVk(ovrSession session, VkQueue queue) {
\r
1793 if (!API.ovr_SetSynchronizationQueueVk.Ptr)
\r
1794 return ovrError_NotInitialized;
\r
1796 return API.ovr_SetSynchronizationQueueVk.Ptr(session, queue);
\r
1799 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1800 ovr_CreateTextureSwapChainVk(
\r
1801 ovrSession session,
\r
1803 const ovrTextureSwapChainDesc* desc,
\r
1804 ovrTextureSwapChain* out_TextureSwapChain) {
\r
1805 if (!API.ovr_CreateTextureSwapChainVk.Ptr)
\r
1806 return ovrError_NotInitialized;
\r
1808 return API.ovr_CreateTextureSwapChainVk.Ptr(session, device, desc, out_TextureSwapChain);
\r
1811 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1812 ovr_GetTextureSwapChainBufferVk(
\r
1813 ovrSession session,
\r
1814 ovrTextureSwapChain chain,
\r
1816 VkImage* out_Image) {
\r
1817 if (!API.ovr_GetTextureSwapChainBufferVk.Ptr)
\r
1818 return ovrError_NotInitialized;
\r
1820 return API.ovr_GetTextureSwapChainBufferVk.Ptr(session, chain, index, out_Image);
\r
1823 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1824 ovr_CreateMirrorTextureWithOptionsVk(
\r
1825 ovrSession session,
\r
1827 const ovrMirrorTextureDesc* desc,
\r
1828 ovrMirrorTexture* out_MirrorTexture) {
\r
1829 if (!API.ovr_CreateMirrorTextureWithOptionsVk.Ptr)
\r
1830 return ovrError_NotInitialized;
\r
1832 return API.ovr_CreateMirrorTextureWithOptionsVk.Ptr(session, device, desc, out_MirrorTexture);
\r
1835 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1836 ovr_GetMirrorTextureBufferVk(
\r
1837 ovrSession session,
\r
1838 ovrMirrorTexture mirrorTexture,
\r
1839 VkImage* out_Image) {
\r
1840 if (!API.ovr_GetMirrorTextureBufferVk.Ptr)
\r
1841 return ovrError_NotInitialized;
\r
1843 return API.ovr_GetMirrorTextureBufferVk.Ptr(session, mirrorTexture, out_Image);
\r
1845 #endif // OSX_UNIMPLEMENTED
\r
1847 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1848 ovr_GetTextureSwapChainLength(ovrSession session, ovrTextureSwapChain chain, int* length) {
\r
1849 if (!API.ovr_GetTextureSwapChainLength.Ptr)
\r
1850 return ovrError_NotInitialized;
\r
1852 return API.ovr_GetTextureSwapChainLength.Ptr(session, chain, length);
\r
1855 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1856 ovr_GetTextureSwapChainCurrentIndex(
\r
1857 ovrSession session,
\r
1858 ovrTextureSwapChain chain,
\r
1859 int* currentIndex) {
\r
1860 if (!API.ovr_GetTextureSwapChainCurrentIndex.Ptr)
\r
1861 return ovrError_NotInitialized;
\r
1863 return API.ovr_GetTextureSwapChainCurrentIndex.Ptr(session, chain, currentIndex);
\r
1866 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1867 ovr_GetTextureSwapChainDesc(
\r
1868 ovrSession session,
\r
1869 ovrTextureSwapChain chain,
\r
1870 ovrTextureSwapChainDesc* desc) {
\r
1871 if (!API.ovr_GetTextureSwapChainDesc.Ptr)
\r
1872 return ovrError_NotInitialized;
\r
1874 return API.ovr_GetTextureSwapChainDesc.Ptr(session, chain, desc);
\r
1877 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1878 ovr_CommitTextureSwapChain(ovrSession session, ovrTextureSwapChain chain) {
\r
1879 if (!API.ovr_CommitTextureSwapChain.Ptr)
\r
1880 return ovrError_NotInitialized;
\r
1882 return API.ovr_CommitTextureSwapChain.Ptr(session, chain);
\r
1885 OVR_PUBLIC_FUNCTION(void)
\r
1886 ovr_DestroyTextureSwapChain(ovrSession session, ovrTextureSwapChain chain) {
\r
1887 if (!API.ovr_DestroyTextureSwapChain.Ptr)
\r
1890 API.ovr_DestroyTextureSwapChain.Ptr(session, chain);
\r
1893 OVR_PUBLIC_FUNCTION(void)
\r
1894 ovr_DestroyMirrorTexture(ovrSession session, ovrMirrorTexture mirrorTexture) {
\r
1895 if (!API.ovr_DestroyMirrorTexture.Ptr)
\r
1898 API.ovr_DestroyMirrorTexture.Ptr(session, mirrorTexture);
\r
1901 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1902 ovr_WaitToBeginFrame(ovrSession session, long long frameIndex) {
\r
1903 if (!API.ovr_WaitToBeginFrame.Ptr)
\r
1904 return ovrError_NotInitialized;
\r
1906 return API.ovr_WaitToBeginFrame.Ptr(session, frameIndex);
\r
1909 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1910 ovr_BeginFrame(ovrSession session, long long frameIndex) {
\r
1911 if (!API.ovr_BeginFrame.Ptr)
\r
1912 return ovrError_NotInitialized;
\r
1914 return API.ovr_BeginFrame.Ptr(session, frameIndex);
\r
1917 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1919 ovrSession session,
\r
1920 long long frameIndex,
\r
1921 const ovrViewScaleDesc* viewScaleDesc,
\r
1922 ovrLayerHeader const* const* layerPtrList,
\r
1923 unsigned int layerCount) {
\r
1924 if (!API.ovr_EndFrame.Ptr)
\r
1925 return ovrError_NotInitialized;
\r
1927 return API.ovr_EndFrame.Ptr(session, frameIndex, viewScaleDesc, layerPtrList, layerCount);
\r
1930 OVR_PUBLIC_FUNCTION(ovrResult)
\r
1932 ovrSession session,
\r
1933 long long frameIndex,
\r
1934 const ovrViewScaleDesc* viewScaleDesc,
\r
1935 ovrLayerHeader const* const* layerPtrList,
\r
1936 unsigned int layerCount) {
\r
1937 if (!API.ovr_SubmitFrame.Ptr)
\r
1938 return ovrError_NotInitialized;
\r
1940 return API.ovr_SubmitFrame.Ptr(session, frameIndex, viewScaleDesc, layerPtrList, layerCount);
\r
1943 OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc)
\r
1944 ovr_GetRenderDesc(ovrSession session, ovrEyeType eyeType, ovrFovPort fov) {
\r
1945 if (!API.ovr_GetRenderDesc.Ptr) {
\r
1946 ovrEyeRenderDesc nullEyeRenderDesc;
\r
1947 memset(&nullEyeRenderDesc, 0, sizeof(nullEyeRenderDesc));
\r
1948 return nullEyeRenderDesc;
\r
1950 return API.ovr_GetRenderDesc.Ptr(session, eyeType, fov);
\r
1953 OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetPerfStats(ovrSession session, ovrPerfStats* outPerfStats) {
\r
1954 if (!API.ovr_GetPerfStats.Ptr)
\r
1955 return ovrError_NotInitialized;
\r
1957 return API.ovr_GetPerfStats.Ptr(session, outPerfStats);
\r
1960 OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetPerfStats(ovrSession session) {
\r
1961 if (!API.ovr_ResetPerfStats.Ptr)
\r
1962 return ovrError_NotInitialized;
\r
1964 return API.ovr_ResetPerfStats.Ptr(session);
\r
1967 OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex) {
\r
1968 if (!API.ovr_GetPredictedDisplayTime.Ptr)
\r
1971 return API.ovr_GetPredictedDisplayTime.Ptr(session, frameIndex);
\r
1974 OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds() {
\r
1975 if (!API.ovr_GetTimeInSeconds.Ptr)
\r
1977 return API.ovr_GetTimeInSeconds.Ptr();
\r
1980 OVR_PUBLIC_FUNCTION(ovrBool)
\r
1981 ovr_GetBool(ovrSession session, const char* propertyName, ovrBool defaultVal) {
\r
1982 if (!API.ovr_GetBool.Ptr)
\r
1984 return API.ovr_GetBool.Ptr(session, propertyName, defaultVal);
\r
1987 OVR_PUBLIC_FUNCTION(ovrBool)
\r
1988 ovr_SetBool(ovrSession session, const char* propertyName, ovrBool value) {
\r
1989 if (!API.ovr_SetBool.Ptr)
\r
1991 return API.ovr_SetBool.Ptr(session, propertyName, value);
\r
1994 OVR_PUBLIC_FUNCTION(int) ovr_GetInt(ovrSession session, const char* propertyName, int defaultVal) {
\r
1995 if (!API.ovr_GetInt.Ptr)
\r
1997 return API.ovr_GetInt.Ptr(session, propertyName, defaultVal);
\r
2000 OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetInt(ovrSession session, const char* propertyName, int value) {
\r
2001 if (!API.ovr_SetInt.Ptr)
\r
2003 return API.ovr_SetInt.Ptr(session, propertyName, value);
\r
2006 OVR_PUBLIC_FUNCTION(float)
\r
2007 ovr_GetFloat(ovrSession session, const char* propertyName, float defaultVal) {
\r
2008 if (!API.ovr_GetFloat.Ptr)
\r
2010 return API.ovr_GetFloat.Ptr(session, propertyName, defaultVal);
\r
2013 OVR_PUBLIC_FUNCTION(ovrBool)
\r
2014 ovr_SetFloat(ovrSession session, const char* propertyName, float value) {
\r
2015 if (!API.ovr_SetFloat.Ptr)
\r
2017 return API.ovr_SetFloat.Ptr(session, propertyName, value);
\r
2020 OVR_PUBLIC_FUNCTION(unsigned int)
\r
2021 ovr_GetFloatArray(
\r
2022 ovrSession session,
\r
2023 const char* propertyName,
\r
2025 unsigned int arraySize) {
\r
2026 if (!API.ovr_GetFloatArray.Ptr)
\r
2028 return API.ovr_GetFloatArray.Ptr(session, propertyName, values, arraySize);
\r
2031 OVR_PUBLIC_FUNCTION(ovrBool)
\r
2032 ovr_SetFloatArray(
\r
2033 ovrSession session,
\r
2034 const char* propertyName,
\r
2035 const float values[],
\r
2036 unsigned int arraySize) {
\r
2037 if (!API.ovr_SetFloatArray.Ptr)
\r
2039 return API.ovr_SetFloatArray.Ptr(session, propertyName, values, arraySize);
\r
2042 OVR_PUBLIC_FUNCTION(const char*)
\r
2043 ovr_GetString(ovrSession session, const char* propertyName, const char* defaultVal) {
\r
2044 if (!API.ovr_GetString.Ptr)
\r
2045 return "(Unable to load LibOVR)";
\r
2046 return API.ovr_GetString.Ptr(session, propertyName, defaultVal);
\r
2049 OVR_PUBLIC_FUNCTION(ovrBool)
\r
2050 ovr_SetString(ovrSession session, const char* propertyName, const char* value) {
\r
2051 if (!API.ovr_SetString.Ptr)
\r
2053 return API.ovr_SetString.Ptr(session, propertyName, value);
\r
2056 OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message) {
\r
2057 if (!API.ovr_TraceMessage.Ptr)
\r
2060 return API.ovr_TraceMessage.Ptr(level, message);
\r
2063 OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity) {
\r
2064 if (!API.ovr_IdentifyClient.Ptr)
\r
2065 return ovrError_NotInitialized;
\r
2067 return API.ovr_IdentifyClient.Ptr(identity);
\r
2070 OVR_PUBLIC_FUNCTION(ovrResult) ovr_Lookup(const char* name, void** data) {
\r
2071 if (!API.ovr_Lookup.Ptr)
\r
2072 return ovrError_NotInitialized;
\r
2073 return API.ovr_Lookup.Ptr(name, data);
\r
2076 OVR_PUBLIC_FUNCTION(ovrResult)
\r
2077 ovr_GetExternalCameras(
\r
2078 ovrSession session,
\r
2079 ovrExternalCamera* outCameras,
\r
2080 unsigned int* outCameraCount) {
\r
2081 if (!API.ovr_GetExternalCameras.Ptr)
\r
2082 return ovrError_NotInitialized;
\r
2083 if (!outCameras || !outCameraCount)
\r
2084 return ovrError_InvalidParameter;
\r
2086 return API.ovr_GetExternalCameras.Ptr(session, outCameras, outCameraCount);
\r
2089 OVR_PUBLIC_FUNCTION(ovrResult)
\r
2090 ovr_SetExternalCameraProperties(
\r
2091 ovrSession session,
\r
2093 const ovrCameraIntrinsics* const intrinsics,
\r
2094 const ovrCameraExtrinsics* const extrinsics) {
\r
2095 if (!API.ovr_SetExternalCameraProperties.Ptr)
\r
2096 return ovrError_NotInitialized;
\r
2097 if (!name || (!intrinsics && !extrinsics))
\r
2098 return ovrError_InvalidParameter;
\r
2100 return API.ovr_SetExternalCameraProperties.Ptr(session, name, intrinsics, extrinsics);
\r
2102 #if defined(_MSC_VER)
\r
2103 #pragma warning(pop)
\r