summaryrefslogtreecommitdiffhomepage
path: root/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp')
-rw-r--r--ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp
new file mode 100644
index 0000000..7b347be
--- /dev/null
+++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp
@@ -0,0 +1,288 @@
+/************************************************************************************
+
+Filename : Util_SystemGUI.cpp
+Content : OS GUI access, usually for diagnostics.
+Created : October 20, 2014
+Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
+
+Licensed under the Oculus Master SDK License Version 1.0 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+https://developer.oculus.com/licenses/oculusmastersdk-1.0
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#include "Util_SystemGUI.h"
+
+#include "Kernel/OVR_UTF8Util.h"
+#if defined(OVR_OS_WIN32)
+#include "Kernel/OVR_Win32_IncludeWindows.h"
+#endif // OVR_OS_WIN32
+#include <stdarg.h>
+#include <stdio.h>
+#include <memory>
+#include "Kernel/OVR_Allocator.h"
+#include "Kernel/OVR_Std.h"
+
+namespace OVR {
+namespace Util {
+
+bool DisplayMessageBoxVaList(const char* pTitle, const char* pFormat, va_list argList) {
+ char buffer[512];
+ char* pBuffer = buffer;
+ std::unique_ptr<char[]> pAllocated;
+
+ va_list argListSaved;
+ OVR_VA_COPY(argListSaved, argList);
+
+ int result = vsnprintf(
+ buffer, OVR_ARRAY_COUNT(buffer), pFormat, argList); // Returns the required strlen of buffer.
+
+ if (result >= (int)OVR_ARRAY_COUNT(buffer)) // If there was insufficient capacity...
+ {
+ pAllocated = std::make_unique<char[]>(result + 1);
+ pBuffer = pAllocated.get();
+
+ va_end(argList); // The caller owns argList and will call va_end on it.
+ OVR_VA_COPY(argList, argListSaved);
+
+ vsnprintf(pBuffer, (size_t)result + 1, pFormat, argList);
+ }
+
+ bool returnValue = DisplayMessageBox(pTitle, pBuffer);
+
+ return returnValue;
+}
+
+bool DisplayMessageBoxF(const char* pTitle, const char* pFormat, ...) {
+ va_list argList;
+ va_start(argList, pFormat);
+ bool returnValue = DisplayMessageBoxVaList(pTitle, pFormat, argList);
+ va_end(argList);
+ return returnValue;
+}
+
+#if defined(OVR_OS_MS)
+
+// On Windows we implement a manual dialog message box. The reason for this is that there's no way
+// to
+// have a message box like this without either using MFC or WinForms or relying on Windows Vista+.
+
+bool DisplayMessageBox(const char* pTitle, const char* pText) {
+#define ID_EDIT 100
+
+ struct Dialog {
+ static size_t LineCount(const char* pText) {
+ size_t count = 0;
+ while (*pText) {
+ if (*pText++ == '\n')
+ count++;
+ }
+ return count;
+ }
+
+ static WORD* WordUp(WORD* pIn) {
+ return (WORD*)((((uintptr_t)pIn + 3) >> 2) << 2);
+ }
+
+ static INT_PTR CALLBACK Proc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) {
+ switch (iMsg) {
+ case WM_INITDIALOG: {
+ HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT);
+
+ const wchar_t* pText = (const wchar_t*)lParam;
+ SetWindowTextW(hWndEdit, pText);
+
+ HFONT hFont = CreateFontW(
+ -11,
+ 0,
+ 0,
+ 0,
+ FW_DONTCARE,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ DEFAULT_QUALITY,
+ DEFAULT_PITCH,
+ L"Courier New");
+ if (hFont)
+ SendMessageW(hWndEdit, WM_SETFONT, WPARAM(hFont), TRUE);
+
+ SendMessageW(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0);
+
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case ID_EDIT: {
+ // Handle messages from the edit control here.
+ HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT);
+ SendMessageW(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0);
+ return TRUE;
+ }
+
+ case IDOK:
+ EndDialog(hDlg, 0);
+ return TRUE;
+ case IDABORT:
+ _exit(0); // We don't call abort() because the visual studio runtime
+ // will capture the signal and throw up another dialog
+ }
+ break;
+ case WM_CLOSE:
+
+ EndDialog(hDlg, 0);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ };
+
+ char dialogTemplateMemory[1024];
+ memset(dialogTemplateMemory, 0, sizeof(dialogTemplateMemory));
+ LPDLGTEMPLATEW pDlg = (LPDLGTEMPLATEW)dialogTemplateMemory;
+
+ const size_t textLength = strlen(pText);
+ const size_t textLineCount = Dialog::LineCount(pText);
+
+ // Sizes are in Windows dialog units, which are relative to a character size. Depends on the font
+ // and environment settings. Often the pixel size will be ~3x the dialog unit x size. Often the
+ // pixel size will be ~3x the dialog unit y size.
+ const int kGutterSize = 6; // Empty border space around controls within the dialog
+ const int kButtonWidth = 30;
+ const int kButtonHeight = 10;
+ const int kDialogWidth =
+ ((textLength > 1000)
+ ? 600
+ : ((textLength > 400) ? 300 : 200)); // To do: Clip this against screen bounds.
+ const int kDialogHeight =
+ ((textLineCount > 100) ? 400
+ : ((textLineCount > 25) ? 300 : ((textLineCount > 10) ? 200 : 100)));
+
+ // Define a dialog box.
+ pDlg->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
+ pDlg->cdit = 3; // Control count
+ pDlg->x = 10; // X position To do: Center the dialog.
+ pDlg->y = 10;
+ pDlg->cx = (short)kDialogWidth;
+ pDlg->cy = (short)kDialogHeight;
+ WORD* pWord = (WORD*)(pDlg + 1);
+ *pWord++ = 0; // No menu
+ *pWord++ = 0; // Default dialog box class
+
+ WCHAR* pWchar = (WCHAR*)pWord;
+ const size_t titleLength = strlen(pTitle);
+ size_t wcharCount = OVR::UTF8Util::Strlcpy(pWchar, 128, pTitle, titleLength);
+
+ pWord += wcharCount + 1;
+
+ // Define an OK button.
+ pWord = Dialog::WordUp(pWord);
+
+ PDLGITEMTEMPLATEW pDlgItem = (PDLGITEMTEMPLATEW)pWord;
+ pDlgItem->x = pDlg->cx - (kGutterSize + kButtonWidth);
+ pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight);
+ pDlgItem->cx = kButtonWidth;
+ pDlgItem->cy = kButtonHeight;
+ pDlgItem->id = IDOK;
+ pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
+
+ pWord = (WORD*)(pDlgItem + 1);
+ *pWord++ = 0xFFFF;
+ *pWord++ = 0x0080; // button class
+
+ pWchar = (WCHAR*)pWord;
+ pWchar[0] = 'O';
+ pWchar[1] = 'K';
+ pWchar[2] = '\0'; // Not currently localized.
+ pWord += 3; // OK\0
+ *pWord++ = 0; // no creation data
+
+ // Define a QUIT button
+ pWord = Dialog::WordUp(pWord);
+
+ pDlgItem = (PDLGITEMTEMPLATEW)pWord;
+ pDlgItem->x = pDlg->cx - ((kGutterSize + kButtonWidth) * 2);
+ pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight);
+ pDlgItem->cx = kButtonWidth;
+ pDlgItem->cy = kButtonHeight;
+ pDlgItem->id = IDABORT;
+ pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
+
+ pWord = (WORD*)(pDlgItem + 1);
+ *pWord++ = 0xFFFF;
+ *pWord++ = 0x0080; // button class
+
+ pWchar = (WCHAR*)pWord;
+ pWchar[0] = 'Q';
+ pWchar[1] = 'U';
+ pWchar[2] = 'I';
+ pWchar[3] = 'T';
+ pWchar[4] = '\0'; // Not currently localized.
+ pWord += 5; // QUIT\0
+ *pWord++ = 0; // no creation data
+
+ // Define an EDIT contol.
+ pWord = Dialog::WordUp(pWord);
+
+ pDlgItem = (PDLGITEMTEMPLATEW)pWord;
+ pDlgItem->x = kGutterSize;
+ pDlgItem->y = kGutterSize;
+ pDlgItem->cx = pDlg->cx - (kGutterSize + kGutterSize);
+ pDlgItem->cy = pDlg->cy - (kGutterSize + kButtonHeight + kGutterSize + (kGutterSize / 2));
+ pDlgItem->id = ID_EDIT;
+ pDlgItem->style = ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
+ ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;
+
+ pWord = (WORD*)(pDlgItem + 1);
+ *pWord++ = 0xFFFF;
+ *pWord++ = 0x0081; // edit class atom
+ *pWord++ = 0; // no creation data
+
+ // We use SafeMMapAlloc instead of malloc/new because we may be in a situation with a broken heap,
+ // which triggered this message box.
+ LRESULT ret = 0;
+ size_t textBuffWCapacity = textLength + 1;
+ wchar_t* textBuffW = (wchar_t*)OVR::SafeMMapAlloc(textBuffWCapacity * sizeof(wchar_t));
+
+ if (textBuffW) {
+ OVR::UTF8Util::Strlcpy(textBuffW, textBuffWCapacity, pText, textLength);
+ ret =
+ DialogBoxIndirectParamW(NULL, (LPDLGTEMPLATEW)pDlg, NULL, Dialog::Proc, (LPARAM)textBuffW);
+ OVR::SafeMMapFree(textBuffW, textBuffWCapacity * sizeof(wchar_t));
+ }
+
+ return (ret != 0);
+}
+
+#elif defined(OVR_OS_MAC)
+
+// For Apple we use the Objective C implementation in Util_GUI.mm
+
+#else
+
+// To do.
+bool DisplayMessageBox(const char* pTitle, const char* pText) {
+ printf("\n\nMessageBox\n%s\n", pTitle);
+ printf("%s\n\n", pText);
+ return false;
+}
+
+#endif
+} // namespace Util
+} // namespace OVR