1 /* 2 * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "DebugWindow.h" 7 8 #include <algorithm> 9 #include <stdio.h> 10 11 #include <Button.h> 12 #include <Catalog.h> 13 #include <GroupLayout.h> 14 #include <LayoutBuilder.h> 15 #include <Locale.h> 16 #include <IconUtils.h> 17 #include <Resources.h> 18 #include <RadioButton.h> 19 #include <StripeView.h> 20 #include <TextView.h> 21 22 #undef B_TRANSLATION_CONTEXT 23 #define B_TRANSLATION_CONTEXT "DebugServer" 24 25 26 DebugWindow::DebugWindow(const char* appName) 27 : 28 BWindow(BRect(0, 0, 100, 50), "Crashed program", B_MODAL_WINDOW, 29 B_CLOSE_ON_ESCAPE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS), 30 fBitmap(IconSize(), B_RGBA32), 31 fSemaphore(create_sem(0, "DebugWindow")), 32 fAction(kActionKillTeam) 33 { 34 BString buffer(B_TRANSLATE( 35 "The application:\n\n %app\n\n" 36 "has encountered an error which prevents it from continuing. Haiku " 37 "will terminate the application and clean up.")); 38 buffer.ReplaceFirst("%app", appName); 39 40 BResources resources; 41 resources.SetToImage(B_TRANSLATION_CONTEXT); 42 size_t size; 43 const uint8* iconData = (const uint8*)resources.LoadResource('VICN', 2, 44 &size); 45 BIconUtils::GetVectorIcon(iconData, size, &fBitmap); 46 BStripeView *stripeView = new BStripeView(fBitmap); 47 48 BTextView *message = new BTextView("_tv_"); 49 message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 50 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); 51 message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor); 52 message->MakeEditable(false); 53 message->MakeSelectable(false); 54 message->SetWordWrap(true); 55 message->SetText(buffer); 56 message->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNSET)); 57 float width = message->StringWidth(appName) 58 + message->StringWidth(" ") * 12; 59 width = std::max(width, message->StringWidth("W") * 30); 60 message->SetExplicitMinSize(BSize(width, B_SIZE_UNSET)); 61 62 BRadioButton *terminate = new BRadioButton("terminate", 63 B_TRANSLATE("Terminate"), new BMessage(kActionKillTeam)); 64 #ifdef HANDOVER_USE_DEBUGGER 65 BRadioButton *report = new BRadioButton("report", 66 B_TRANSLATE("Save report"), new BMessage(kActionSaveReportTeam)); 67 #endif 68 BRadioButton *debug = new BRadioButton("debug", 69 B_TRANSLATE("Debug"), new BMessage(kActionDebugTeam)); 70 BRadioButton *core = new BRadioButton("core", 71 B_TRANSLATE("Write core file"), new BMessage(kActionWriteCoreFile)); 72 73 BButton *close = new BButton("close", B_TRANSLATE("Oh no!"), 74 new BMessage(B_QUIT_REQUESTED)); 75 76 terminate->SetValue(B_CONTROL_ON); 77 78 BLayoutBuilder::Group<>(this) 79 .AddGroup(B_HORIZONTAL) 80 .Add(stripeView) 81 .AddGroup(B_VERTICAL) 82 .SetInsets(B_USE_SMALL_SPACING) 83 .Add(message) 84 .AddGroup(B_VERTICAL, 0) 85 .Add(terminate) 86 .Add(debug) 87 .Add(report) 88 .Add(core) 89 .End() 90 .AddGroup(B_HORIZONTAL) 91 .AddGlue() 92 .Add(close) 93 .End() 94 .End() 95 .End(); 96 97 ResizeToPreferred(); 98 CenterOnScreen(); 99 } 100 101 102 DebugWindow::~DebugWindow() 103 { 104 delete_sem(fSemaphore); 105 } 106 107 108 void 109 DebugWindow::MessageReceived(BMessage* message) 110 { 111 switch(message->what) { 112 case B_QUIT_REQUESTED: 113 release_sem(fSemaphore); 114 break; 115 116 case kActionKillTeam: 117 case kActionDebugTeam: 118 case kActionWriteCoreFile: 119 case kActionSaveReportTeam: 120 fAction = message->what; 121 return; 122 } 123 124 BWindow::MessageReceived(message); 125 } 126 127 128 int32 129 DebugWindow::Go() 130 { 131 Show(); 132 133 // Wait for user to close the window 134 acquire_sem(fSemaphore); 135 return fAction; 136 } 137 138 139 BRect 140 DebugWindow::IconSize() 141 { 142 int32 size = std::max((int32)1, ((int32)be_plain_font->Size() + 15) / 16) 143 * 32 - 1; 144 return BRect(0, 0, size, size); 145 } 146