static void msgBox(QString title, QString text) { std::string ttl = title.toStdString(); std::string msg = text.toStdString(); SDL_MessageBoxData mbox; SDL_MessageBoxButtonData mboxButton; const SDL_MessageBoxColorScheme colorScheme = { { /* .colors (.r, .g, .b) */ /* [SDL_MESSAGEBOX_COLOR_BACKGROUND] */ { 200, 200, 200 }, /* [SDL_MESSAGEBOX_COLOR_TEXT] */ { 0, 0, 0 }, /* [SDL_MESSAGEBOX_COLOR_BUTTON_BORDER] */ { 255, 255, 255 }, /* [SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND] */ { 150, 150, 150 }, /* [SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] */ { 255, 255, 255 } } }; mboxButton.buttonid = 0; mboxButton.flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT | SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; mboxButton.text = "Ok"; mbox.flags = SDL_MESSAGEBOX_ERROR; mbox.window = PGE_Window::window; mbox.title = ttl.c_str(); mbox.message = msg.c_str(); mbox.numbuttons = 1; mbox.buttons = &mboxButton; mbox.colorScheme = &colorScheme; SDL_ShowMessageBox(&mbox, NULL); }
GameState::QUITRESPONSE GameState::TwoOptionQuitDialog() { int buttonid = -1; const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "No" }, }; const SDL_MessageBoxData messageboxdata = { SDL_MESSAGEBOX_INFORMATION, /* .flags */ NULL, /* .window */ "Quit", /* .title */ "Would you like to Quit?", /* .message */ SDL_arraysize(buttons), /* .numbuttons */ buttons, /* .buttons */ NULL /* .colorScheme */ }; int ret = SDL_ShowMessageBox(&messageboxdata, &buttonid); if (buttonid == 1) return GameState::QUIT; return GameState::CANCEL; }
GameState::QUITRESPONSE GameState::ThreeOptionQuitDialog(std::string new_state) { int buttonid = -1; const SDL_MessageBoxButtonData buttons[] = { { 0, 0, "Cancel" }, { 0, 1, "Menu" }, { 0, 2, "Quit" }, }; const SDL_MessageBoxData messageboxdata = { SDL_MESSAGEBOX_INFORMATION, /* .flags */ NULL, /* .window */ "Quit", /* .title */ "Would you like to Return to Menu or Quit to Desktop?", /* .message */ SDL_arraysize(buttons), /* .numbuttons */ buttons, /* .buttons */ NULL /* .colorScheme */ }; int ret = SDL_ShowMessageBox(&messageboxdata, &buttonid); if (buttonid == 1) { // Return to main menu m_newState = new_state; return GameState::NEWSTATE; } if (buttonid == 2) return GameState::QUIT; return GameState::CANCEL; }
extern "C" int assert_handler(const char* cond, const char* file, int line) { const SDL_MessageBoxButtonData buttons[] = { { 0, 0, "Ignore" }, { 0, 1, "Abort" }, { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Break" }, }; cstr1024 msg; sprintf_s(msg, "Assertion:(%s) failed in %s:%d", cond, file, line); SDL_MessageBoxData data = { SDL_MESSAGEBOX_INFORMATION, NULL, // no parent window "ASSERTION", msg, 3, buttons, NULL // Default color scheme }; int button = -1; int success = SDL_ShowMessageBox(&data, &button); switch (button) { case 0: return false; case 1: core::abort(); } return true; }
int Runtime::ask(const char *title, const char *prompt, bool cancel) { SDL_MessageBoxButtonData buttons[cancel ? 3: 2]; memset(&buttons[0], 0, sizeof(SDL_MessageBoxButtonData)); memset(&buttons[1], 0, sizeof(SDL_MessageBoxButtonData)); buttons[0].text = "Yes"; buttons[0].buttonid = 0; buttons[1].text = "No"; buttons[1].buttonid = 1; if (cancel) { memset(&buttons[2], 0, sizeof(SDL_MessageBoxButtonData)); buttons[2].text = "Cancel"; buttons[2].buttonid = 2; } SDL_MessageBoxData data; memset(&data, 0, sizeof(SDL_MessageBoxData)); data.window = _window; data.title = title; data.message = prompt; data.flags = SDL_MESSAGEBOX_INFORMATION; data.numbuttons = cancel ? 3 : 2; data.buttons = buttons; int buttonId; SDL_ShowMessageBox(&data, &buttonId); return buttonId; }
REALIGN STDCALL int MessageBoxA_wrap(void *hWnd, const char *text, const char *caption, uint32_t type) { SDL_MessageBoxButtonData buttons[] = {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "OK"}, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "Cancel"}}; SDL_MessageBoxData msgb = {SDL_MESSAGEBOX_WARNING, NULL, caption, text, (int32_t)(type & 0x1) + 1, buttons, NULL}; int buttonID; if (!SDL_ShowMessageBox(&msgb, &buttonID)) return buttonID; return 1; }
static int SDLCALL button_messagebox(void *eventNumber) { const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" },{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Cancel" }, }; SDL_MessageBoxData data = { SDL_MESSAGEBOX_INFORMATION, NULL, /* no parent window */ "Custom MessageBox", "This is a custom messagebox", 2, NULL,/* buttons */ NULL /* Default color scheme */ }; int button = -1; int success = 0; data.buttons = buttons; if (eventNumber) { data.message = "This is a custom messagebox from a background thread."; } success = SDL_ShowMessageBox(&data, &button); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); if (eventNumber) { SDL_UserEvent event; event.type = (intptr_t)eventNumber; SDL_PushEvent((SDL_Event*)&event); return 1; } else { quit(2); } } SDL_Log("Pressed button: %d, %s\n", button, button == -1 ? "[closed]" : button == 1 ? "Cancel" : "OK"); if (eventNumber) { SDL_UserEvent event; event.type = (intptr_t)eventNumber; SDL_PushEvent((SDL_Event*)&event); } return 0; }
static int sdlGameEnd(GameState* gameState, SDL_Window *win) { char message[1000]; switch (gameState->endStatus) { case DRAW_END: { sprintf(message, "The game ended in DRAW\nDo you want to play again?"); } break; case PLAYER_WINS_END: { sprintf(message, "The game ended with PLAYER winning\nDo you want to play again?"); } break; case COMPUTER_WINS_END: { sprintf(message, "The game ended with COMPUTER winning\nDo you want to play again?"); } break; default: assert(false); } SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "no" }, { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "yes" } }; SDL_MessageBoxData messageboxdata = { SDL_MESSAGEBOX_INFORMATION, win, "GAME OVER", message, SDL_arraysize(buttons), buttons }; int buttonid = -1; if (SDL_ShowMessageBox(&messageboxdata, &buttonid) < 0) { fprintf(stderr, "SDL_ShowMessageBox Error: %s\n", SDL_GetError()); return 1; } if (buttonid == 1) { *gameState = {}; gameState->freeTilesCount = 9; gameState->running = true; gameState->endStatus = NO_END; } else { gameState->running = false; } return 0; }
int PLEXT_Window_MessageBoxYesNo( const DXCHAR *title, const DXCHAR *text, const DXCHAR *yes, const DXCHAR *no ) { SDL_MessageBoxButtonData buttons[2]; SDL_MessageBoxData data; int resultButton; char titleBuf[1024]; char textBuf[1024]; char yesBuf[512]; char noBuf[512]; PL_Text_DxStringToString(title, titleBuf, 1024, DX_CHARSET_EXT_UTF8); PL_Text_DxStringToString(text, textBuf, 1024, DX_CHARSET_EXT_UTF8); PL_Text_DxStringToString(yes, yesBuf, 1024, DX_CHARSET_EXT_UTF8); PL_Text_DxStringToString(no, noBuf, 1024, DX_CHARSET_EXT_UTF8); buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; buttons[0].buttonid = 1; buttons[0].text = yesBuf; buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; buttons[1].buttonid = 0; buttons[1].text = noBuf; data.flags = SDL_MESSAGEBOX_INFORMATION; data.window = s_window; data.title = titleBuf; data.message = textBuf; data.numbuttons = 2; data.buttons = buttons; data.colorScheme = NULL; if (SDL_ShowMessageBox(&data, &resultButton) < 0) { return -1; } return resultButton; }
void kexSystem::Error(const char* string, ...) { va_list va; va_start(va, string); vsprintf(buffer, string, va); va_end(va); fprintf(stderr, "Error - %s\n", buffer); fflush(stderr); Log(buffer); #ifdef _WIN32 Sys_Error(buffer); #else const SDL_MessageBoxButtonData buttons[1] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" } }; SDL_MessageBoxData data = { SDL_MESSAGEBOX_ERROR, NULL, "Error", buffer, 2, buttons, NULL }; int button = -1; SDL_ShowMessageBox(&data, &button); #endif exit(0); // just in case... }
void Com_BreakIntoDebugger (void) { #ifdef DEBUG #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_MessageBoxData data; SDL_MessageBoxButtonData okButton; SDL_MessageBoxButtonData cancelButton; OBJZERO(data); OBJZERO(okButton); OBJZERO(cancelButton); okButton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; okButton.text = "Yes"; okButton.buttonid = 1; cancelButton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; cancelButton.text = "No"; cancelButton.buttonid = 2; const SDL_MessageBoxButtonData buttons[] = {okButton, cancelButton}; data.flags = SDL_MESSAGEBOX_ERROR; data.title = "Error"; data.message = "Break into the debugger?"; data.numbuttons = lengthof(buttons); data.buttons = buttons; data.window = nullptr; int buttonid = -1; SDL_ShowMessageBox(&data, &buttonid); if (buttonid == 1) { Sys_Breakpoint(); } #endif #endif }
int show_message(std::string str, std::string button1, std::string button2, std::string button3) { SDL_MessageBoxButtonData buttons[3]; int numbuttons = 0; if (button3.empty()) { if (button2.empty()) { buttons[0] = {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, button1.c_str()}; numbuttons = 1; } else { buttons[0] = {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, button1.c_str()}; buttons[1] = {0, 1, button2.c_str()}; numbuttons = 2; } } else { buttons[0] = {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, button1.c_str()}; buttons[1] = {0, 1, button2.c_str()}; buttons[2] = {0, 2, button3.c_str()}; numbuttons = 3; } SDL_MessageBoxData data = { SDL_MESSAGEBOX_INFORMATION, // Message type NULL, // Window "Message", // Title str.c_str(), // Message numbuttons, // Number of buttons buttons, // List of buttons NULL // Color scheme }; int brid = 0; if (SDL_ShowMessageBox(&data, &brid) < 0) { std::cerr << "Failed to display message box: " << SDL_GetError() << "\n"; return -2; } return brid; }
int Window::showMessageBox(const MessageBoxData &data) { SDL_MessageBoxData sdldata = {}; sdldata.flags = convertMessageBoxType(data.type); sdldata.title = data.title.c_str(); sdldata.message = data.message.c_str(); sdldata.window = data.attachToWindow ? window : nullptr; sdldata.numbuttons = (int) data.buttons.size(); std::vector<SDL_MessageBoxButtonData> sdlbuttons; for (int i = 0; i < (int) data.buttons.size(); i++) { SDL_MessageBoxButtonData sdlbutton = {}; sdlbutton.buttonid = i; sdlbutton.text = data.buttons[i].c_str(); if (i == data.enterButtonIndex) sdlbutton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; if (i == data.escapeButtonIndex) sdlbutton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; sdlbuttons.push_back(sdlbutton); } sdldata.buttons = &sdlbuttons[0]; int pressedbutton = -2; SDL_ShowMessageBox(&sdldata, &pressedbutton); return pressedbutton; }
static int sdlDialogCommand(DialogType type, const std::string & message, const std::string & title) { bool wasInitialized = (SDL_WasInit(SDL_INIT_VIDEO) != 0); if(!wasInitialized && SDL_Init(SDL_INIT_VIDEO) != 0) { return -2; } int ret = -2; SDL_MessageBoxData box = { SDL_MESSAGEBOX_INFORMATION, NULL, title.c_str(), message.c_str(), 0, NULL, NULL }; switch(type) { case DialogInfo: box.flags = SDL_MESSAGEBOX_INFORMATION; break; case DialogWarning: box.flags = SDL_MESSAGEBOX_WARNING; break; case DialogError: box.flags = SDL_MESSAGEBOX_ERROR; break; case DialogYesNo: box.flags = SDL_MESSAGEBOX_INFORMATION; break; case DialogWarnYesNo: box.flags = SDL_MESSAGEBOX_WARNING; break; case DialogOkCancel: box.flags = SDL_MESSAGEBOX_INFORMATION; break; } const SDL_MessageBoxButtonData buttonsOK[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" }, }; const SDL_MessageBoxButtonData buttonsYesNo[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "No" }, }; const SDL_MessageBoxButtonData buttonsOKCancel[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Cancel" }, }; switch(type) { case DialogInfo: case DialogWarning: case DialogError: { box.buttons = buttonsOK, box.numbuttons = ARRAY_SIZE(buttonsOK); break; } case DialogYesNo: case DialogWarnYesNo: { box.buttons = buttonsYesNo, box.numbuttons = ARRAY_SIZE(buttonsYesNo); break; } case DialogOkCancel: { box.buttons = buttonsOKCancel, box.numbuttons = ARRAY_SIZE(buttonsOKCancel); break; } } int buttonid; if(SDL_ShowMessageBox(&box, &buttonid) >= 0) { ret = (buttonid == -1) ? 2 : buttonid; } if(!wasInitialized) { SDL_QuitSubSystem(SDL_INIT_VIDEO); } return ret; }
S32 Platform::messageBox(const UTF8 *title, const UTF8 *message, MBButtons buttons, MBIcons icon) { if(needInitMsgBox) initMsgBox_ButtonData(); SDL_Window *window = WindowManager->getFirstWindow() ? SDL_GetWindowFromID( WindowManager->getFirstWindow()->getWindowId() ) : NULL; if (window) //release the mouse from the window constaints SDL_SetWindowGrab(window, SDL_FALSE); if(buttons == MBOk) return SDL_ShowSimpleMessageBox(0, title, message, window ); SDL_MessageBoxData boxData; boxData.title = title; boxData.message = message; boxData.window = window; boxData.flags = 0; boxData.colorScheme = NULL; boxData.buttons = NULL; boxData.numbuttons = 0; int res = MBOk; switch(buttons) { case MBOkCancel: { boxData.buttons = &MBOkCancelData[0]; boxData.numbuttons = 2; break; } case MBRetryCancel: { boxData.buttons = &MBRetryCancelData[0]; boxData.numbuttons = 2; break; } case MBSaveDontSave: { boxData.buttons = &MBSaveDontSaveData[0]; boxData.numbuttons = 2; break; } case MBSaveDontSaveCancel: { boxData.buttons = &MBSaveDontSaveCancelData[0]; boxData.numbuttons = 3; break; } case MBAlertAssert: { boxData.buttons = &MBAlertAssetData[0]; boxData.numbuttons = 4; break; } default: { return MBOk; } } SDL_ShowMessageBox(&boxData, &res); return res; }
void ReleaseWarning(const char* filename, int line, const char* format, ...) { Global_warning_count++; filename = clean_filename(filename); // output to the debug log before anything else (so that we have a complete record) SCP_string formatMessage; va_list args; va_start(args, format); vsprintf(formatMessage, format, args); va_end(args); SCP_string printfString = formatMessage; std::transform(printfString.begin(), printfString.end(), printfString.begin(), replaceNewline); mprintf(("WARNING: \"%s\" at %s:%d\n", printfString.c_str(), filename, line)); // now go for the additional popup window, if we want it ... if (Cmdline_noninteractive) { return; } if (running_unittests) { throw AssertException(printfString); } SCP_stringstream boxMsgStream; boxMsgStream << "Warning: " << formatMessage << "\n"; boxMsgStream << "File: " << filename << "\n"; boxMsgStream << "Line: " << line << "\n"; boxMsgStream << "\n"; boxMsgStream << dump_stacktrace(); set_clipboard_text(boxMsgStream.str().c_str()); SCP_string boxMessage = truncateLines(boxMsgStream, Messagebox_lines); boxMessage += "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; boxMessage += "\n\nUse Debug to break into Debugger\n"; const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Exit" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Continue" }, { /* .flags, .buttonid, .text */ 0, 0, "Debug" }, }; SDL_MessageBoxData boxData; memset(&boxData, 0, sizeof(boxData)); boxData.buttons = buttons; boxData.numbuttons = 3; boxData.colorScheme = nullptr; boxData.flags = SDL_MESSAGEBOX_WARNING; boxData.message = boxMessage.c_str(); boxData.title = "Warning!"; boxData.window = os::getSDLMainWindow(); gr_activate(0); int buttonId; if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed exit(1); } switch (buttonId) { case 2: exit(1); case 0: Int3(); break; default: break; } gr_activate(1); }
void Error(const char* text) { mprintf(("\n%s\n", text)); if (Cmdline_noninteractive) { abort(); return; } if (running_unittests) { throw ErrorException(text); } SCP_stringstream messageStream; messageStream << text << "\n"; messageStream << dump_stacktrace(); SCP_string fullText = messageStream.str(); set_clipboard_text(fullText.c_str()); fullText = truncateLines(messageStream, Messagebox_lines); fullText += "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; fullText += "\n\nUse Debug to break into Debugger, Exit will close the application.\n"; const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Exit" }, { /* .flags, .buttonid, .text */ 0, 0, "Debug" }, }; SDL_MessageBoxData boxData; memset(&boxData, 0, sizeof(boxData)); boxData.buttons = buttons; boxData.numbuttons = 2; boxData.colorScheme = nullptr; boxData.flags = SDL_MESSAGEBOX_ERROR; boxData.message = text; boxData.title = "Error!"; boxData.window = os::getSDLMainWindow(); gr_activate(0); int buttonId; if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed exit(1); } switch (buttonId) { case 1: exit(1); default: Int3(); break; } gr_activate(1); }
void LuaError(lua_State * L, const char * format, ...) { SCP_stringstream msgStream; //WMC - if format is set to NULL, assume this is acting as an //error handler for Lua. if (format == NULL) { msgStream << "LUA ERROR: " << lua_tostring(L, -1); lua_pop(L, -1); } else { SCP_string formatText; va_list args; va_start(args, format); vsprintf(formatText, format, args); va_end(args); msgStream << formatText; } msgStream << "\n"; msgStream << "\n"; msgStream << Separator; msgStream << "ADE Debug:"; msgStream << "\n"; msgStream << Separator; LuaDebugPrint(msgStream, Ade_debug_info); msgStream << Separator; msgStream << "\n"; msgStream << "\n"; msgStream << Separator; // Get the stack via the debug.traceback() function lua_getglobal(L, LUA_DBLIBNAME); if (!lua_isnil(L, -1)) { msgStream << "\n"; lua_getfield(L, -1, "traceback"); lua_remove(L, -2); if (lua_pcall(L, 0, 1, 0) != 0) msgStream << "Error while retrieving stack: " << lua_tostring(L, -1); else msgStream << lua_tostring(L, -1); lua_pop(L, 1); } msgStream << "\n"; msgStream << Separator; char stackText[1024]; stackText[0] = '\0'; scripting::ade_stackdump(L, stackText); msgStream << stackText; msgStream << "\n"; msgStream << Separator; mprintf(("Lua Error: %s\n", msgStream.str().c_str())); if (Cmdline_noninteractive) { exit(1); return; } if (running_unittests) { throw LuaErrorException(msgStream.str()); } set_clipboard_text(msgStream.str().c_str()); // truncate text auto truncatedText = truncateLines(msgStream, Messagebox_lines); SCP_stringstream boxTextStream; boxTextStream << truncatedText << "\n"; boxTextStream << "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; auto boxText = boxTextStream.str(); const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Exit" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Continue" }, { /* .flags, .buttonid, .text */ 0, 0, "Debug" }, }; SDL_MessageBoxData boxData; memset(&boxData, 0, sizeof(boxData)); boxData.buttons = buttons; boxData.numbuttons = 3; boxData.colorScheme = nullptr; boxData.flags = SDL_MESSAGEBOX_ERROR; boxData.message = boxText.c_str(); boxData.title = "Error!"; boxData.window = os::getSDLMainWindow(); gr_activate(0); int buttonId; if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed buttonId = 1; // No action } switch (buttonId) { case 2: exit(1); case 0: Int3(); break; default: break; } gr_activate(1); }
static SDL_assert_state SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) { #ifdef __WIN32__ #define ENDLINE "\r\n" #else #define ENDLINE "\n" #endif const char *envr; SDL_assert_state state = SDL_ASSERTION_ABORT; SDL_Window *window; SDL_MessageBoxData messagebox; SDL_MessageBoxButtonData buttons[] = { { 0, SDL_ASSERTION_RETRY, "Retry" }, { 0, SDL_ASSERTION_BREAK, "Break" }, { 0, SDL_ASSERTION_ABORT, "Abort" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, SDL_ASSERTION_IGNORE, "Ignore" }, { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" } }; char *message; int selected; (void) userdata; /* unused in default handler. */ message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); if (!message) { /* Uh oh, we're in real trouble now... */ return SDL_ASSERTION_ABORT; } SDL_snprintf(message, SDL_MAX_LOG_MESSAGE, "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE " '%s'", data->function, data->filename, data->linenum, data->trigger_count, (data->trigger_count == 1) ? "time" : "times", data->condition); debug_print("\n\n%s\n\n", message); /* let env. variable override, so unit tests won't block in a GUI. */ envr = SDL_getenv("SDL_ASSERT"); if (envr != NULL) { SDL_stack_free(message); if (SDL_strcmp(envr, "abort") == 0) { return SDL_ASSERTION_ABORT; } else if (SDL_strcmp(envr, "break") == 0) { return SDL_ASSERTION_BREAK; } else if (SDL_strcmp(envr, "retry") == 0) { return SDL_ASSERTION_RETRY; } else if (SDL_strcmp(envr, "ignore") == 0) { return SDL_ASSERTION_IGNORE; } else if (SDL_strcmp(envr, "always_ignore") == 0) { return SDL_ASSERTION_ALWAYS_IGNORE; } else { return SDL_ASSERTION_ABORT; /* oh well. */ } } /* Leave fullscreen mode, if possible (scary!) */ window = SDL_GetFocusWindow(); if (window) { if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) { SDL_MinimizeWindow(window); } else { /* !!! FIXME: ungrab the input if we're not fullscreen? */ /* No need to mess with the window */ window = NULL; } } /* Show a messagebox if we can, otherwise fall back to stdio */ SDL_zero(messagebox); messagebox.flags = SDL_MESSAGEBOX_WARNING; messagebox.window = window; messagebox.title = "Assertion Failed"; messagebox.message = message; messagebox.numbuttons = SDL_arraysize(buttons); messagebox.buttons = buttons; if (SDL_ShowMessageBox(&messagebox, &selected) == 0) { if (selected == -1) { state = SDL_ASSERTION_IGNORE; } else { state = (SDL_assert_state)selected; } } #ifdef HAVE_STDIO_H else { /* this is a little hacky. */ for ( ; ; ) { char buf[32]; fprintf(stderr, "Abort/Break/Retry/Ignore/AlwaysIgnore? [abriA] : "); fflush(stderr); if (fgets(buf, sizeof (buf), stdin) == NULL) { break; } if (SDL_strcmp(buf, "a") == 0) { state = SDL_ASSERTION_ABORT; break; } else if (SDL_strcmp(buf, "b") == 0) { state = SDL_ASSERTION_BREAK; break; } else if (SDL_strcmp(buf, "r") == 0) { state = SDL_ASSERTION_RETRY; break; } else if (SDL_strcmp(buf, "i") == 0) { state = SDL_ASSERTION_IGNORE; break; } else if (SDL_strcmp(buf, "A") == 0) { state = SDL_ASSERTION_ALWAYS_IGNORE; break; } } } #endif /* HAVE_STDIO_H */ /* Re-enter fullscreen mode */ if (window) { SDL_RestoreWindow(window); } SDL_stack_free(message); return state; }
void Log(LogLevel level, UString prefix, const UString &text) { bool exit_app = false; const char *level_prefix; logMutex.lock(); if (!loggerInited) { initLogger(); } bool writeToFile = (level <= fileLogLevel); bool writeToStderr = (level <= stderrLogLevel); if (!writeToFile && !writeToStderr) { // Nothing to do return; } auto timeNow = std::chrono::high_resolution_clock::now(); unsigned long long clockns = std::chrono::duration<unsigned long long, std::nano>(timeNow - timeInit).count(); switch (level) { case LogLevel::Info: level_prefix = "I"; break; case LogLevel::Warning: level_prefix = "W"; break; default: level_prefix = "E"; exit_app = true; break; } if (writeToFile) { fprintf(outFile, "%s %llu %s: %s\n", level_prefix, clockns, prefix.cStr(), text.cStr()); // On error print a backtrace to the log file if (level <= backtraceLogLevel) print_backtrace(outFile); fflush(outFile); } if (writeToStderr) { fprintf(stderr, "%s %llu %s: %s\n", level_prefix, clockns, prefix.cStr(), text.cStr()); if (level <= backtraceLogLevel) print_backtrace(stderr); fflush(stderr); } #if defined(ERROR_DIALOG) if (showDialogOnError && level == LogLevel::Error) { if (!Framework::tryGetInstance()) { // No framework to have created a window, so don't try to show a dialog } else if (!fw().displayHasWindow()) { // Framework created but without window, so don't try to show a dialog } else { SDL_MessageBoxData mBoxData; mBoxData.flags = SDL_MESSAGEBOX_ERROR; mBoxData.window = NULL; // Might happen before we get our window? mBoxData.title = "OpenApoc ERROR"; mBoxData.message = text.cStr(); mBoxData.numbuttons = 2; SDL_MessageBoxButtonData buttons[2]; buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; buttons[0].buttonid = 1; buttons[0].text = "Exit"; buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; buttons[1].buttonid = 2; buttons[1].text = "try to limp along"; mBoxData.buttons = buttons; mBoxData.colorScheme = NULL; // Use system settings int but; SDL_ShowMessageBox(&mBoxData, &but); /* button 1 = "exit", button 2 = "try to limp along" */ if (but == 1) { exit_app = true; } else { exit_app = false; } } } #endif logMutex.unlock(); if (exit_app) { exit(EXIT_FAILURE); } }