vfs: check userland buffers before reading them.
[haiku.git] / src / apps / debugger / user_interface / gui / utility_windows / ConnectionConfigWindow.cpp
blob3be6a1313523a470ecd0811162f9434447118f10
1 /*
2 * Copyright 2016-2017, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
4 */
5 #include "ConnectionConfigWindow.h"
7 #include <Application.h>
8 #include <Button.h>
9 #include <GroupView.h>
10 #include <MenuField.h>
11 #include <LayoutBuilder.h>
13 #include <AutoDeleter.h>
14 #include <AutoLocker.h>
16 #include "AppMessageCodes.h"
17 #include "ConnectionConfigHandlerRoster.h"
18 #include "Settings.h"
19 #include "TargetHostInterfaceInfo.h"
20 #include "TargetHostInterfaceRoster.h"
21 #include "TargetHostInterface.h"
24 enum {
25 MSG_SWITCH_CONNECTION_TYPE = 'swct',
26 MSG_CREATE_CONNECTION = 'crco'
30 ConnectionConfigWindow::ConnectionConfigWindow()
32 BWindow(BRect(), "Create new connection", B_TITLED_WINDOW,
33 B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
34 ConnectionConfigView::Listener(),
35 fConnectionTypeField(NULL),
36 fConfigGroupView(NULL),
37 fCloseButton(NULL),
38 fConnectButton(NULL),
39 fCurrentSettings(NULL),
40 fActiveInfo(NULL)
45 ConnectionConfigWindow::~ConnectionConfigWindow()
47 if (fCurrentSettings != NULL)
48 fCurrentSettings->ReleaseReference();
52 ConnectionConfigWindow*
53 ConnectionConfigWindow::Create()
55 ConnectionConfigWindow* self = new ConnectionConfigWindow();
57 try {
58 self->_Init();
59 } catch (...) {
60 delete self;
61 throw;
64 return self;
69 void
70 ConnectionConfigWindow::Show()
72 CenterOnScreen();
73 BWindow::Show();
77 bool
78 ConnectionConfigWindow::QuitRequested()
80 return be_app_messenger.SendMessage(MSG_CONNECTION_CONFIG_WINDOW_CLOSED)
81 == B_OK;
85 void
86 ConnectionConfigWindow::ConfigurationChanged(Settings* settings)
88 if (fCurrentSettings != NULL)
89 fCurrentSettings->ReleaseReference();
90 fCurrentSettings = settings;
91 fCurrentSettings->AcquireReference();
93 fConnectButton->SetEnabled(fActiveInfo->IsConfigured(settings));
97 void
98 ConnectionConfigWindow::MessageReceived(BMessage* message)
100 switch (message->what) {
101 case MSG_CREATE_CONNECTION:
103 TargetHostInterfaceRoster* roster
104 = TargetHostInterfaceRoster::Default();
105 AutoLocker<TargetHostInterfaceRoster> rosterLocker(roster);
107 TargetHostInterface* interface;
108 status_t error = roster->CreateInterface(fActiveInfo,
109 fCurrentSettings, interface);
111 // TODO: notify user.
112 if (error != B_OK)
113 break;
115 PostMessage(B_QUIT_REQUESTED);
116 break;
118 default:
119 BWindow::MessageReceived(message);
120 break;
125 void
126 ConnectionConfigWindow::_Init()
128 BMenu* menu = _BuildTypeMenu();
130 fConfigGroupView = new BGroupView(B_HORIZONTAL);
132 BLayoutBuilder::Group<>(this, B_VERTICAL)
133 .SetInsets(B_USE_DEFAULT_SPACING)
134 .Add(fConnectionTypeField = new BMenuField("Type:", menu))
135 .AddGroup(fConfigGroupView)
136 // this group is a placeholder to contain
137 // the actual config view
138 .End()
139 .AddGroup(B_HORIZONTAL)
140 .SetInsets(B_USE_SMALL_SPACING)
141 .AddGlue()
142 .Add(fCloseButton = new BButton("Close",
143 new BMessage(B_QUIT_REQUESTED)))
144 .Add(fConnectButton = new BButton("Connect",
145 new BMessage(MSG_CREATE_CONNECTION)))
146 .End();
148 fConnectionTypeField->Menu()->SetLabelFromMarked(true);
149 fConnectionTypeField->Menu()->SetTargetForItems(this);
151 fCloseButton->SetTarget(this);
152 fConnectButton->SetTarget(this);
153 fConnectButton->SetEnabled(false);
155 if (menu->CountItems() > 0) {
156 BMenuItem* item = menu->ItemAt(0);
157 BMessage* message = item->Message();
158 TargetHostInterfaceInfo* info = NULL;
159 if (message->FindPointer("info", reinterpret_cast<void**>(&info))
160 == B_OK) {
161 _UpdateActiveConfig(info);
162 menu->ItemAt(0)->SetMarked(true);
168 BMenu*
169 ConnectionConfigWindow::_BuildTypeMenu()
171 BMenu* menu = new BMenu("Types");
172 TargetHostInterfaceRoster* roster = TargetHostInterfaceRoster::Default();
174 AutoLocker<TargetHostInterfaceRoster> rosterLocker(roster);
176 for (int32 i = 0; i < roster->CountInterfaceInfos(); i++) {
177 TargetHostInterfaceInfo* info = roster->InterfaceInfoAt(i);
178 if (info->IsLocal())
179 continue;
181 BMenuItem* item = new BMenuItem(info->Name(), new BMessage(
182 MSG_SWITCH_CONNECTION_TYPE));
183 item->Message()->AddPointer("info", info);
184 menu->AddItem(item);
187 return menu;
191 void
192 ConnectionConfigWindow::_UpdateActiveConfig(TargetHostInterfaceInfo* info)
194 if (fConfigGroupView->CountChildren() > 0) {
195 BView* view = fConfigGroupView->ChildAt(0);
196 fConfigGroupView->RemoveChild(view);
197 delete view;
200 ConnectionConfigHandlerRoster* roster
201 = ConnectionConfigHandlerRoster::Default();
203 if (roster->HasHandlerFor(info)) {
204 ConnectionConfigView* view = NULL;
205 status_t error = roster->CreateConfigView(info, this, view);
206 if (error != B_OK)
207 return;
209 ObjectDeleter<ConnectionConfigView> viewDeleter(view);
210 BLayoutItem* item = fConfigGroupView->GroupLayout()->AddView(view);
211 if (item != NULL)
212 viewDeleter.Detach();
214 fActiveInfo = info;
217 fConfigGroupView->InvalidateLayout();