vfs: check userland buffers before reading them.
[haiku.git] / src / apps / expander / PasswordAlert.cpp
bloba99cd79aef3a57e783988f6d021e099218f8f7de
1 /*
2 * Copyright 2003-2010 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Jérôme Duval
7 */
10 #include "PasswordAlert.h"
12 #include <string.h>
14 #include <File.h>
15 #include <FindDirectory.h>
16 #include <IconUtils.h>
17 #include <Path.h>
18 #include <Resources.h>
19 #include <Screen.h>
20 #include <View.h>
23 static const int kWindowIconOffset = 27;
24 static const int kIconStripeWidth = 30;
25 static const int kTextIconOffset = kWindowIconOffset + kIconStripeWidth - 2;
26 static const int kTextTopOffset = 6;
27 static const int kSemTimeOut = 50000;
30 class TAlertView : public BView {
31 public:
32 TAlertView(BRect frame);
33 TAlertView(BMessage* archive);
34 ~TAlertView();
36 virtual void Draw(BRect updateRect);
38 void SetBitmap(BBitmap* Icon) { fIconBitmap = Icon; }
39 BBitmap* Bitmap() { return fIconBitmap; }
41 private:
42 BBitmap* fIconBitmap;
46 // #pragma mark - PasswordAlert
49 PasswordAlert::PasswordAlert(const char* title, const char* text)
51 BWindow(BRect(0, 0, 450, 45), title, B_MODAL_WINDOW,
52 B_NOT_CLOSABLE | B_NOT_RESIZABLE),
53 fTextControl(NULL),
54 fAlertSem(-1)
56 // Set up the "_master_" view
57 TAlertView* masterView = new TAlertView(Bounds());
58 masterView->SetBitmap(InitIcon());
59 AddChild(masterView);
61 // Set up the text view
62 BRect textControlRect(kTextIconOffset, kTextTopOffset,
63 Bounds().right - 5, Bounds().bottom);
65 fTextControl = new BTextControl(textControlRect, "_password_", text,
66 NULL, new BMessage('pass'), B_FOLLOW_ALL);
67 fTextControl->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
68 fTextControl->TextView()->HideTyping(true);
69 fTextControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
70 fTextControl->SetDivider(10 + fTextControl->StringWidth(text));
72 masterView->AddChild(fTextControl);
74 BRect screenFrame = BScreen(B_MAIN_SCREEN_ID).Frame();
75 BPoint point;
76 point.x = screenFrame.Width() / 2 - Bounds().Width() / 2;
77 point.y = screenFrame.Height() / 2 - Bounds().Height() / 2;
78 if (screenFrame.Contains(point))
79 MoveTo(point);
81 fTextControl->MakeFocus();
85 PasswordAlert::~PasswordAlert()
90 BBitmap*
91 PasswordAlert::InitIcon()
93 // The alert icons are in the app_server resources
94 BBitmap* icon = NULL;
95 BPath path;
96 if (find_directory(B_BEOS_SERVERS_DIRECTORY, &path) == B_OK) {
97 path.Append("app_server");
98 BFile file;
99 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK) {
100 BResources resources;
101 if (resources.SetTo(&file) == B_OK) {
102 // Which icon are we trying to load?
103 const char* iconName = "warn";
105 // Load the raw icon data
106 size_t size;
107 const void* rawIcon
108 = resources.LoadResource(B_VECTOR_ICON_TYPE, iconName,
109 &size);
111 if (rawIcon != NULL) {
112 // Now build the bitmap
113 icon = new BBitmap(BRect(0, 0, 31, 31), B_RGBA32);
114 if (BIconUtils::GetVectorIcon((const uint8*)rawIcon, size,
115 icon) != B_OK) {
116 delete icon;
117 return NULL;
124 return icon;
128 void
129 PasswordAlert::Go(BString& password)
131 fAlertSem = create_sem(0, "AlertSem");
132 if (fAlertSem < B_OK) {
133 Quit();
134 return;
137 // Get the originating window, if it exists
138 BWindow* window
139 = dynamic_cast<BWindow*>(BLooper::LooperForThread(find_thread(NULL)));
141 Show();
143 // Heavily modified from TextEntryAlert code; the original didn't let the
144 // blocked window ever draw.
145 if (window != NULL) {
146 status_t result;
147 for (;;) {
148 do {
149 result = acquire_sem_etc(fAlertSem, 1, B_RELATIVE_TIMEOUT,
150 kSemTimeOut);
151 // We've (probably) had our time slice taken away from us
152 } while (result == B_INTERRUPTED);
154 if (result == B_BAD_SEM_ID) {
155 // Semaphore was finally nuked in MessageReceived
156 break;
158 window->UpdateIfNeeded();
160 } else {
161 // No window to update, so just hang out until we're done.
162 while (acquire_sem(fAlertSem) == B_INTERRUPTED) {
167 // Have to cache the value since we delete on Quit()
168 password = fTextControl->Text();
169 if (Lock())
170 Quit();
174 void
175 PasswordAlert::MessageReceived(BMessage* msg)
177 if (msg->what != 'pass')
178 return BWindow::MessageReceived(msg);
180 delete_sem(fAlertSem);
181 fAlertSem = -1;
185 // #pragma mark - TAlertView
188 TAlertView::TAlertView(BRect frame)
190 BView(frame, "TAlertView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
191 fIconBitmap(NULL)
193 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
197 TAlertView::~TAlertView()
199 delete fIconBitmap;
203 void
204 TAlertView::Draw(BRect updateRect)
206 // Here's the fun stuff
207 if (fIconBitmap != NULL) {
208 BRect stripeRect = Bounds();
209 stripeRect.right = kIconStripeWidth;
210 SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
211 FillRect(stripeRect);
213 SetDrawingMode(B_OP_ALPHA);
214 DrawBitmapAsync(fIconBitmap, BPoint(18, 6));
215 SetDrawingMode(B_OP_COPY);