1f01106c3SAxel Dörfler /* 27974d3dcSStephan Aßmus * Copyright 2006-2009, Haiku, Inc. All rights reserved. 3f01106c3SAxel Dörfler * Distributed under the terms of the MIT License. 4f01106c3SAxel Dörfler * 5f01106c3SAxel Dörfler * Authors: 6f01106c3SAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 7f01106c3SAxel Dörfler * Hugo Santos, hugosantos@gmail.com 83b41ad86SStephan Aßmus * Dario Casalinuovo 9f01106c3SAxel Dörfler */ 10f01106c3SAxel Dörfler 11f01106c3SAxel Dörfler 12f01106c3SAxel Dörfler #include "NetworkStatusView.h" 13f01106c3SAxel Dörfler 14195981bbSAxel Dörfler #include <arpa/inet.h> 15195981bbSAxel Dörfler #include <net/if.h> 16195981bbSAxel Dörfler #include <stdio.h> 17195981bbSAxel Dörfler #include <stdlib.h> 18195981bbSAxel Dörfler #include <string.h> 19195981bbSAxel Dörfler #include <sys/socket.h> 20195981bbSAxel Dörfler #include <sys/sockio.h> 21195981bbSAxel Dörfler #include <unistd.h> 22f01106c3SAxel Dörfler 23f01106c3SAxel Dörfler #include <Alert.h> 24f01106c3SAxel Dörfler #include <Application.h> 25757e7059SAdrien Destugues #include <Catalog.h> 26f01106c3SAxel Dörfler #include <Bitmap.h> 27f01106c3SAxel Dörfler #include <Deskbar.h> 28f01106c3SAxel Dörfler #include <Dragger.h> 29f01106c3SAxel Dörfler #include <Drivers.h> 30f01106c3SAxel Dörfler #include <IconUtils.h> 31757e7059SAdrien Destugues #include <Locale.h> 32f01106c3SAxel Dörfler #include <MenuItem.h> 33f01106c3SAxel Dörfler #include <MessageRunner.h> 34*5fe97f21SAxel Dörfler #include <NetworkDevice.h> 35*5fe97f21SAxel Dörfler #include <NetworkInterface.h> 36*5fe97f21SAxel Dörfler #include <NetworkRoster.h> 37f01106c3SAxel Dörfler #include <PopUpMenu.h> 38f01106c3SAxel Dörfler #include <Resources.h> 39d5ba07a3SAxel Dörfler #include <Roster.h> 40f01106c3SAxel Dörfler #include <String.h> 41f01106c3SAxel Dörfler #include <TextView.h> 42f01106c3SAxel Dörfler 43195981bbSAxel Dörfler #include "NetworkStatus.h" 44195981bbSAxel Dörfler #include "NetworkStatusIcons.h" 45*5fe97f21SAxel Dörfler #include "RadioView.h" 46195981bbSAxel Dörfler 47f01106c3SAxel Dörfler 48757e7059SAdrien Destugues #undef B_TRANSLATE_CONTEXT 49757e7059SAdrien Destugues #define B_TRANSLATE_CONTEXT "NetworkStatusView" 50757e7059SAdrien Destugues 51757e7059SAdrien Destugues 52f01106c3SAxel Dörfler static const char *kStatusDescriptions[] = { 53757e7059SAdrien Destugues B_TRANSLATE_MARK("Unknown"), 54757e7059SAdrien Destugues B_TRANSLATE_MARK("No link"), 55757e7059SAdrien Destugues B_TRANSLATE_MARK("No stateful configuration"), 56757e7059SAdrien Destugues B_TRANSLATE_MARK("Configuring"), 57757e7059SAdrien Destugues B_TRANSLATE_MARK("Ready") 58f01106c3SAxel Dörfler }; 59f01106c3SAxel Dörfler 60f01106c3SAxel Dörfler extern "C" _EXPORT BView *instantiate_deskbar_item(void); 61f01106c3SAxel Dörfler 62f01106c3SAxel Dörfler 63f01106c3SAxel Dörfler const uint32 kMsgShowConfiguration = 'shcf'; 64c1502c9aSStephan Aßmus const uint32 kMsgOpenNetworkPreferences = 'onwp'; 65f01106c3SAxel Dörfler 66f01106c3SAxel Dörfler const uint32 kMinIconWidth = 16; 67f01106c3SAxel Dörfler const uint32 kMinIconHeight = 16; 68f01106c3SAxel Dörfler 69195981bbSAxel Dörfler 70*5fe97f21SAxel Dörfler class WirelessNetworkMenuItem : public BMenuItem { 71*5fe97f21SAxel Dörfler public: 72*5fe97f21SAxel Dörfler WirelessNetworkMenuItem(const char* name, 73*5fe97f21SAxel Dörfler int32 signalQuality, bool encrypted, 74*5fe97f21SAxel Dörfler BMessage* message); 75*5fe97f21SAxel Dörfler virtual ~WirelessNetworkMenuItem(); 76*5fe97f21SAxel Dörfler 77*5fe97f21SAxel Dörfler void SetSignalQuality(int32 quality); 78*5fe97f21SAxel Dörfler int32 SignalQuality() const 79*5fe97f21SAxel Dörfler { return fQuality; } 80*5fe97f21SAxel Dörfler bool IsEncrypted() const 81*5fe97f21SAxel Dörfler { return fIsEncrypted; } 82*5fe97f21SAxel Dörfler 83*5fe97f21SAxel Dörfler protected: 84*5fe97f21SAxel Dörfler virtual void DrawContent(); 85*5fe97f21SAxel Dörfler virtual void Highlight(bool isHighlighted); 86*5fe97f21SAxel Dörfler virtual void GetContentSize(float* width, float* height); 87*5fe97f21SAxel Dörfler void DrawRadioIcon(); 88*5fe97f21SAxel Dörfler 89*5fe97f21SAxel Dörfler private: 90*5fe97f21SAxel Dörfler int32 fQuality; 91*5fe97f21SAxel Dörfler bool fIsEncrypted; 92*5fe97f21SAxel Dörfler }; 93*5fe97f21SAxel Dörfler 94*5fe97f21SAxel Dörfler 95195981bbSAxel Dörfler class SocketOpener { 96195981bbSAxel Dörfler public: 97195981bbSAxel Dörfler SocketOpener() 98195981bbSAxel Dörfler { 99195981bbSAxel Dörfler fSocket = socket(AF_INET, SOCK_DGRAM, 0); 100195981bbSAxel Dörfler } 101195981bbSAxel Dörfler 102195981bbSAxel Dörfler ~SocketOpener() 103195981bbSAxel Dörfler { 104195981bbSAxel Dörfler close(fSocket); 105195981bbSAxel Dörfler } 106195981bbSAxel Dörfler 107195981bbSAxel Dörfler status_t InitCheck() 108195981bbSAxel Dörfler { 109195981bbSAxel Dörfler return fSocket >= 0 ? B_OK : B_ERROR; 110195981bbSAxel Dörfler } 111195981bbSAxel Dörfler 112195981bbSAxel Dörfler operator int() const 113195981bbSAxel Dörfler { 114195981bbSAxel Dörfler return fSocket; 115195981bbSAxel Dörfler } 116195981bbSAxel Dörfler 117195981bbSAxel Dörfler private: 118195981bbSAxel Dörfler int fSocket; 119195981bbSAxel Dörfler }; 120195981bbSAxel Dörfler 121195981bbSAxel Dörfler 122*5fe97f21SAxel Dörfler // #pragma mark - WirelessNetworkMenuItem 123*5fe97f21SAxel Dörfler 124*5fe97f21SAxel Dörfler 125*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::WirelessNetworkMenuItem(const char* name, 126*5fe97f21SAxel Dörfler int32 signalQuality, bool encrypted, BMessage* message) 127*5fe97f21SAxel Dörfler : 128*5fe97f21SAxel Dörfler BMenuItem(name, message), 129*5fe97f21SAxel Dörfler fQuality(signalQuality), 130*5fe97f21SAxel Dörfler fIsEncrypted(encrypted) 131*5fe97f21SAxel Dörfler { 132*5fe97f21SAxel Dörfler } 133*5fe97f21SAxel Dörfler 134*5fe97f21SAxel Dörfler 135*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::~WirelessNetworkMenuItem() 136*5fe97f21SAxel Dörfler { 137*5fe97f21SAxel Dörfler } 138*5fe97f21SAxel Dörfler 139*5fe97f21SAxel Dörfler 140*5fe97f21SAxel Dörfler void 141*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::SetSignalQuality(int32 quality) 142*5fe97f21SAxel Dörfler { 143*5fe97f21SAxel Dörfler fQuality = quality; 144*5fe97f21SAxel Dörfler } 145*5fe97f21SAxel Dörfler 146*5fe97f21SAxel Dörfler 147*5fe97f21SAxel Dörfler void 148*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::DrawContent() 149*5fe97f21SAxel Dörfler { 150*5fe97f21SAxel Dörfler DrawRadioIcon(); 151*5fe97f21SAxel Dörfler BMenuItem::DrawContent(); 152*5fe97f21SAxel Dörfler } 153*5fe97f21SAxel Dörfler 154*5fe97f21SAxel Dörfler 155*5fe97f21SAxel Dörfler void 156*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::Highlight(bool isHighlighted) 157*5fe97f21SAxel Dörfler { 158*5fe97f21SAxel Dörfler BMenuItem::Highlight(isHighlighted); 159*5fe97f21SAxel Dörfler } 160*5fe97f21SAxel Dörfler 161*5fe97f21SAxel Dörfler 162*5fe97f21SAxel Dörfler void 163*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::GetContentSize(float* width, float* height) 164*5fe97f21SAxel Dörfler { 165*5fe97f21SAxel Dörfler BMenuItem::GetContentSize(width, height); 166*5fe97f21SAxel Dörfler *width += *height + 4; 167*5fe97f21SAxel Dörfler } 168*5fe97f21SAxel Dörfler 169*5fe97f21SAxel Dörfler 170*5fe97f21SAxel Dörfler void 171*5fe97f21SAxel Dörfler WirelessNetworkMenuItem::DrawRadioIcon() 172*5fe97f21SAxel Dörfler { 173*5fe97f21SAxel Dörfler BRect bounds = Frame(); 174*5fe97f21SAxel Dörfler bounds.left = bounds.right - 4 - bounds.Height(); 175*5fe97f21SAxel Dörfler bounds.right -= 4; 176*5fe97f21SAxel Dörfler bounds.bottom -= 2; 177*5fe97f21SAxel Dörfler 178*5fe97f21SAxel Dörfler RadioView::Draw(Menu(), bounds, fQuality, RadioView::DefaultMax()); 179*5fe97f21SAxel Dörfler } 180*5fe97f21SAxel Dörfler 181*5fe97f21SAxel Dörfler 182195981bbSAxel Dörfler // #pragma mark - 183f01106c3SAxel Dörfler 184f01106c3SAxel Dörfler 185f01106c3SAxel Dörfler NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode, 186f01106c3SAxel Dörfler bool inDeskbar) 187f01106c3SAxel Dörfler : BView(frame, kDeskbarItemName, resizingMode, 188d5ba07a3SAxel Dörfler B_WILL_DRAW | B_FRAME_EVENTS), 189f01106c3SAxel Dörfler fInDeskbar(inDeskbar), 190f01106c3SAxel Dörfler fStatus(kStatusUnknown) 191f01106c3SAxel Dörfler { 192f01106c3SAxel Dörfler _Init(); 193f01106c3SAxel Dörfler 194f01106c3SAxel Dörfler if (!inDeskbar) { 195f01106c3SAxel Dörfler // we were obviously added to a standard window - let's add a dragger 196f01106c3SAxel Dörfler frame.OffsetTo(B_ORIGIN); 197f01106c3SAxel Dörfler frame.top = frame.bottom - 7; 198f01106c3SAxel Dörfler frame.left = frame.right - 7; 199f01106c3SAxel Dörfler BDragger* dragger = new BDragger(frame, this, 200f01106c3SAxel Dörfler B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 201f01106c3SAxel Dörfler AddChild(dragger); 202f01106c3SAxel Dörfler } else 203f01106c3SAxel Dörfler _Update(); 204f01106c3SAxel Dörfler } 205f01106c3SAxel Dörfler 206f01106c3SAxel Dörfler 207f01106c3SAxel Dörfler NetworkStatusView::NetworkStatusView(BMessage* archive) 208d5ba07a3SAxel Dörfler : BView(archive), 209d5ba07a3SAxel Dörfler fInDeskbar(false) 210f01106c3SAxel Dörfler { 211d5ba07a3SAxel Dörfler app_info info; 212d5ba07a3SAxel Dörfler if (be_app->GetAppInfo(&info) == B_OK 213d5ba07a3SAxel Dörfler && !strcasecmp(info.signature, "application/x-vnd.Be-TSKB")) 214d5ba07a3SAxel Dörfler fInDeskbar = true; 215d5ba07a3SAxel Dörfler 216f01106c3SAxel Dörfler _Init(); 217f01106c3SAxel Dörfler } 218f01106c3SAxel Dörfler 219f01106c3SAxel Dörfler 220f01106c3SAxel Dörfler NetworkStatusView::~NetworkStatusView() 221f01106c3SAxel Dörfler { 222f01106c3SAxel Dörfler } 223f01106c3SAxel Dörfler 224f01106c3SAxel Dörfler 225f01106c3SAxel Dörfler void 226f01106c3SAxel Dörfler NetworkStatusView::_Init() 227f01106c3SAxel Dörfler { 228f01106c3SAxel Dörfler for (int i = 0; i < kStatusCount; i++) { 229f01106c3SAxel Dörfler fBitmaps[i] = NULL; 230f01106c3SAxel Dörfler } 231f01106c3SAxel Dörfler 232f01106c3SAxel Dörfler _UpdateBitmaps(); 233f01106c3SAxel Dörfler } 234f01106c3SAxel Dörfler 235f01106c3SAxel Dörfler 236f01106c3SAxel Dörfler void 237f01106c3SAxel Dörfler NetworkStatusView::_UpdateBitmaps() 238f01106c3SAxel Dörfler { 239f01106c3SAxel Dörfler for (int i = 0; i < kStatusCount; i++) { 240f01106c3SAxel Dörfler delete fBitmaps[i]; 241f01106c3SAxel Dörfler fBitmaps[i] = NULL; 242f01106c3SAxel Dörfler } 243f01106c3SAxel Dörfler 244f01106c3SAxel Dörfler image_info info; 245f01106c3SAxel Dörfler if (our_image(info) != B_OK) 246f01106c3SAxel Dörfler return; 247f01106c3SAxel Dörfler 248f01106c3SAxel Dörfler BFile file(info.name, B_READ_ONLY); 249f01106c3SAxel Dörfler if (file.InitCheck() < B_OK) 250f01106c3SAxel Dörfler return; 251f01106c3SAxel Dörfler 252f01106c3SAxel Dörfler BResources resources(&file); 253f01106c3SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_HAIKU 254f01106c3SAxel Dörfler if (resources.InitCheck() < B_OK) 255f01106c3SAxel Dörfler return; 256f01106c3SAxel Dörfler #endif 257f01106c3SAxel Dörfler 258f01106c3SAxel Dörfler for (int i = 0; i < kStatusCount; i++) { 259f01106c3SAxel Dörfler const void* data = NULL; 260f01106c3SAxel Dörfler size_t size; 261f01106c3SAxel Dörfler data = resources.LoadResource(B_VECTOR_ICON_TYPE, 262f01106c3SAxel Dörfler kNetworkStatusNoDevice + i, &size); 263f01106c3SAxel Dörfler if (data != NULL) { 2644c28a737SStephan Aßmus BBitmap* icon = new BBitmap(Bounds(), B_RGBA32); 265f01106c3SAxel Dörfler if (icon->InitCheck() == B_OK 266f01106c3SAxel Dörfler && BIconUtils::GetVectorIcon((const uint8 *)data, 267f01106c3SAxel Dörfler size, icon) == B_OK) { 268f01106c3SAxel Dörfler fBitmaps[i] = icon; 269f01106c3SAxel Dörfler } else 270f01106c3SAxel Dörfler delete icon; 271f01106c3SAxel Dörfler } 272f01106c3SAxel Dörfler } 273f01106c3SAxel Dörfler } 274f01106c3SAxel Dörfler 275f01106c3SAxel Dörfler 276f01106c3SAxel Dörfler void 277f01106c3SAxel Dörfler NetworkStatusView::_Quit() 278f01106c3SAxel Dörfler { 279f01106c3SAxel Dörfler if (fInDeskbar) { 280f01106c3SAxel Dörfler BDeskbar deskbar; 281f01106c3SAxel Dörfler deskbar.RemoveItem(kDeskbarItemName); 282f01106c3SAxel Dörfler } else 283f01106c3SAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 284f01106c3SAxel Dörfler } 285f01106c3SAxel Dörfler 286f01106c3SAxel Dörfler 287f01106c3SAxel Dörfler NetworkStatusView * 288f01106c3SAxel Dörfler NetworkStatusView::Instantiate(BMessage* archive) 289f01106c3SAxel Dörfler { 290f01106c3SAxel Dörfler if (!validate_instantiation(archive, "NetworkStatusView")) 291f01106c3SAxel Dörfler return NULL; 292f01106c3SAxel Dörfler 293f01106c3SAxel Dörfler return new NetworkStatusView(archive); 294f01106c3SAxel Dörfler } 295f01106c3SAxel Dörfler 296f01106c3SAxel Dörfler 297f01106c3SAxel Dörfler status_t 298f01106c3SAxel Dörfler NetworkStatusView::Archive(BMessage* archive, bool deep) const 299f01106c3SAxel Dörfler { 300f01106c3SAxel Dörfler status_t status = BView::Archive(archive, deep); 301f01106c3SAxel Dörfler if (status == B_OK) 302f01106c3SAxel Dörfler status = archive->AddString("add_on", kSignature); 303f01106c3SAxel Dörfler if (status == B_OK) 304f01106c3SAxel Dörfler status = archive->AddString("class", "NetworkStatusView"); 305f01106c3SAxel Dörfler 306f01106c3SAxel Dörfler return status; 307f01106c3SAxel Dörfler } 308f01106c3SAxel Dörfler 309f01106c3SAxel Dörfler 310f01106c3SAxel Dörfler void 311f01106c3SAxel Dörfler NetworkStatusView::AttachedToWindow() 312f01106c3SAxel Dörfler { 313f01106c3SAxel Dörfler BView::AttachedToWindow(); 314f01106c3SAxel Dörfler if (Parent()) 315f01106c3SAxel Dörfler SetViewColor(Parent()->ViewColor()); 316f01106c3SAxel Dörfler else 317f01106c3SAxel Dörfler SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 318f01106c3SAxel Dörfler 319f01106c3SAxel Dörfler SetLowColor(ViewColor()); 320f01106c3SAxel Dörfler 321195981bbSAxel Dörfler start_watching_network( 322195981bbSAxel Dörfler B_WATCH_NETWORK_INTERFACE_CHANGES | B_WATCH_NETWORK_LINK_CHANGES, this); 323f01106c3SAxel Dörfler 324f01106c3SAxel Dörfler _Update(); 325f01106c3SAxel Dörfler } 326f01106c3SAxel Dörfler 327f01106c3SAxel Dörfler 328f01106c3SAxel Dörfler void 329f01106c3SAxel Dörfler NetworkStatusView::DetachedFromWindow() 330f01106c3SAxel Dörfler { 331195981bbSAxel Dörfler stop_watching_network(this); 332f01106c3SAxel Dörfler } 333f01106c3SAxel Dörfler 334f01106c3SAxel Dörfler 335f01106c3SAxel Dörfler void 336f01106c3SAxel Dörfler NetworkStatusView::MessageReceived(BMessage* message) 337f01106c3SAxel Dörfler { 338f01106c3SAxel Dörfler switch (message->what) { 339195981bbSAxel Dörfler case B_NETWORK_MONITOR: 340f01106c3SAxel Dörfler _Update(); 341f01106c3SAxel Dörfler break; 342f01106c3SAxel Dörfler 343f01106c3SAxel Dörfler case kMsgShowConfiguration: 344f01106c3SAxel Dörfler _ShowConfiguration(message); 345f01106c3SAxel Dörfler break; 346f01106c3SAxel Dörfler 347c1502c9aSStephan Aßmus case kMsgOpenNetworkPreferences: 3483b41ad86SStephan Aßmus _OpenNetworksPreferences(); 3493b41ad86SStephan Aßmus break; 3503b41ad86SStephan Aßmus 351f01106c3SAxel Dörfler case B_ABOUT_REQUESTED: 352f01106c3SAxel Dörfler _AboutRequested(); 353f01106c3SAxel Dörfler break; 354f01106c3SAxel Dörfler 355f01106c3SAxel Dörfler case B_QUIT_REQUESTED: 356f01106c3SAxel Dörfler _Quit(); 357f01106c3SAxel Dörfler break; 358f01106c3SAxel Dörfler 359f01106c3SAxel Dörfler default: 360f01106c3SAxel Dörfler BView::MessageReceived(message); 361f01106c3SAxel Dörfler } 362f01106c3SAxel Dörfler } 363f01106c3SAxel Dörfler 364f01106c3SAxel Dörfler 365f01106c3SAxel Dörfler void 366f01106c3SAxel Dörfler NetworkStatusView::FrameResized(float width, float height) 367f01106c3SAxel Dörfler { 368f01106c3SAxel Dörfler _UpdateBitmaps(); 369d5ba07a3SAxel Dörfler Invalidate(); 370f01106c3SAxel Dörfler } 371f01106c3SAxel Dörfler 372f01106c3SAxel Dörfler 373f01106c3SAxel Dörfler void 374f01106c3SAxel Dörfler NetworkStatusView::Draw(BRect updateRect) 375f01106c3SAxel Dörfler { 376f01106c3SAxel Dörfler if (fBitmaps[fStatus] == NULL) 377f01106c3SAxel Dörfler return; 378f01106c3SAxel Dörfler 379f01106c3SAxel Dörfler SetDrawingMode(B_OP_ALPHA); 380f01106c3SAxel Dörfler DrawBitmap(fBitmaps[fStatus]); 381f01106c3SAxel Dörfler SetDrawingMode(B_OP_COPY); 382f01106c3SAxel Dörfler } 383f01106c3SAxel Dörfler 384f01106c3SAxel Dörfler 385f01106c3SAxel Dörfler void 386f01106c3SAxel Dörfler NetworkStatusView::_ShowConfiguration(BMessage* message) 387f01106c3SAxel Dörfler { 388f01106c3SAxel Dörfler static const struct information_entry { 389f01106c3SAxel Dörfler const char* label; 390f01106c3SAxel Dörfler int32 control; 391f01106c3SAxel Dörfler } kInformationEntries[] = { 392f01106c3SAxel Dörfler { "Address", SIOCGIFADDR }, 393f01106c3SAxel Dörfler { "Broadcast", SIOCGIFBRDADDR }, 394f01106c3SAxel Dörfler { "Netmask", SIOCGIFNETMASK }, 395f01106c3SAxel Dörfler { NULL } 396f01106c3SAxel Dörfler }; 397f01106c3SAxel Dörfler 398195981bbSAxel Dörfler SocketOpener socket; 399195981bbSAxel Dörfler if (socket.InitCheck() != B_OK) 400195981bbSAxel Dörfler return; 401195981bbSAxel Dörfler 402f01106c3SAxel Dörfler const char* name; 403f01106c3SAxel Dörfler if (message->FindString("interface", &name) != B_OK) 404f01106c3SAxel Dörfler return; 405f01106c3SAxel Dörfler 406f01106c3SAxel Dörfler ifreq request; 407f01106c3SAxel Dörfler if (!_PrepareRequest(request, name)) 408f01106c3SAxel Dörfler return; 409f01106c3SAxel Dörfler 410757e7059SAdrien Destugues BString text = NULL; 411757e7059SAdrien Destugues if (strncmp("Address", name, strlen(name)) == 0) 412757e7059SAdrien Destugues text = B_TRANSLATE("Address information:\n"); 413757e7059SAdrien Destugues 414757e7059SAdrien Destugues if (strncmp("Broadcast", name, strlen(name)) == 0) 415757e7059SAdrien Destugues text = B_TRANSLATE("Broadcast information:\n"); 416757e7059SAdrien Destugues 417757e7059SAdrien Destugues if (strncmp("Netmask", name, strlen(name)) == 0) 418757e7059SAdrien Destugues text = B_TRANSLATE("Netmask information:\n"); 419757e7059SAdrien Destugues 420f01106c3SAxel Dörfler size_t boldLength = text.Length(); 421f01106c3SAxel Dörfler 422f01106c3SAxel Dörfler for (int i = 0; kInformationEntries[i].label; i++) { 423195981bbSAxel Dörfler if (ioctl(socket, kInformationEntries[i].control, &request, 424f01106c3SAxel Dörfler sizeof(request)) < 0) { 425f01106c3SAxel Dörfler continue; 426f01106c3SAxel Dörfler } 427f01106c3SAxel Dörfler 428f01106c3SAxel Dörfler char address[32]; 429f01106c3SAxel Dörfler sockaddr_in* inetAddress = NULL; 430f01106c3SAxel Dörfler switch (kInformationEntries[i].control) { 431f01106c3SAxel Dörfler case SIOCGIFNETMASK: 432f01106c3SAxel Dörfler inetAddress = (sockaddr_in*)&request.ifr_mask; 433f01106c3SAxel Dörfler break; 434f01106c3SAxel Dörfler default: 435f01106c3SAxel Dörfler inetAddress = (sockaddr_in*)&request.ifr_addr; 436f01106c3SAxel Dörfler break; 437f01106c3SAxel Dörfler } 438f01106c3SAxel Dörfler 439f01106c3SAxel Dörfler if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, 440f01106c3SAxel Dörfler sizeof(address)) == NULL) { 441f01106c3SAxel Dörfler return; 442f01106c3SAxel Dörfler } 443f01106c3SAxel Dörfler 444f01106c3SAxel Dörfler text += "\n"; 445757e7059SAdrien Destugues 446757e7059SAdrien Destugues if (strncmp("Address", kInformationEntries[i].label, 447757e7059SAdrien Destugues strlen(kInformationEntries[i].label)) == 0) 448757e7059SAdrien Destugues text += B_TRANSLATE("Address"); 449757e7059SAdrien Destugues 450757e7059SAdrien Destugues if (strncmp("Broadcast", kInformationEntries[i].label, 451757e7059SAdrien Destugues strlen(kInformationEntries[i].label)) == 0) 452757e7059SAdrien Destugues text += B_TRANSLATE("Broadcast"); 453757e7059SAdrien Destugues 454757e7059SAdrien Destugues if (strncmp("Netmask", kInformationEntries[i].label, 455757e7059SAdrien Destugues strlen(kInformationEntries[i].label)) == 0) 456757e7059SAdrien Destugues text += B_TRANSLATE("Netmask"); 457757e7059SAdrien Destugues 458f01106c3SAxel Dörfler text += ": "; 459f01106c3SAxel Dörfler text += address; 460f01106c3SAxel Dörfler } 461f01106c3SAxel Dörfler 462757e7059SAdrien Destugues BAlert* alert = new BAlert(name, text.String(), B_TRANSLATE("OK")); 463f01106c3SAxel Dörfler BTextView* view = alert->TextView(); 464f01106c3SAxel Dörfler BFont font; 465f01106c3SAxel Dörfler 466f01106c3SAxel Dörfler view->SetStylable(true); 467f01106c3SAxel Dörfler view->GetFont(&font); 468f01106c3SAxel Dörfler font.SetFace(B_BOLD_FACE); 469f01106c3SAxel Dörfler view->SetFontAndColor(0, boldLength, &font); 470f01106c3SAxel Dörfler 471f01106c3SAxel Dörfler alert->Go(NULL); 472f01106c3SAxel Dörfler } 473f01106c3SAxel Dörfler 474f01106c3SAxel Dörfler 475f01106c3SAxel Dörfler void 476f01106c3SAxel Dörfler NetworkStatusView::MouseDown(BPoint point) 477f01106c3SAxel Dörfler { 478f01106c3SAxel Dörfler BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false); 479a31688d2SAxel Dörfler menu->SetAsyncAutoDestruct(true); 480f01106c3SAxel Dörfler menu->SetFont(be_plain_font); 481f01106c3SAxel Dörfler 482*5fe97f21SAxel Dörfler // Add interfaces 483*5fe97f21SAxel Dörfler 484f01106c3SAxel Dörfler for (int32 i = 0; i < fInterfaces.CountItems(); i++) { 485f01106c3SAxel Dörfler BString& name = *fInterfaces.ItemAt(i); 486f01106c3SAxel Dörfler 487f01106c3SAxel Dörfler BString label = name; 488f01106c3SAxel Dörfler label += ": "; 489f01106c3SAxel Dörfler label += kStatusDescriptions[ 490f01106c3SAxel Dörfler _DetermineInterfaceStatus(name.String())]; 491f01106c3SAxel Dörfler 492f01106c3SAxel Dörfler BMessage* info = new BMessage(kMsgShowConfiguration); 493f01106c3SAxel Dörfler info->AddString("interface", name.String()); 494f01106c3SAxel Dörfler menu->AddItem(new BMenuItem(label.String(), info)); 495f01106c3SAxel Dörfler } 496f01106c3SAxel Dörfler 497f01106c3SAxel Dörfler menu->AddSeparatorItem(); 498*5fe97f21SAxel Dörfler 499*5fe97f21SAxel Dörfler // Add wireless networks, if any 500*5fe97f21SAxel Dörfler 501*5fe97f21SAxel Dörfler for (int32 i = 0; i < fInterfaces.CountItems(); i++) { 502*5fe97f21SAxel Dörfler BNetworkDevice device(fInterfaces.ItemAt(i)->String()); 503*5fe97f21SAxel Dörfler if (!device.IsWireless()) 504*5fe97f21SAxel Dörfler continue; 505*5fe97f21SAxel Dörfler 506*5fe97f21SAxel Dörfler wireless_network network; 507*5fe97f21SAxel Dörfler int32 count = 0; 508*5fe97f21SAxel Dörfler for (int32 i = 0; device.GetScanResultAt(i, network) == B_OK; i++) { 509*5fe97f21SAxel Dörfler printf("%s: noise %u : rssi %u\n", network.name, 510*5fe97f21SAxel Dörfler network.noise_level, network.signal_strength); 511*5fe97f21SAxel Dörfler menu->AddItem(new WirelessNetworkMenuItem(network.name, 512*5fe97f21SAxel Dörfler network.signal_strength, false, NULL)); 513*5fe97f21SAxel Dörfler count++; 514*5fe97f21SAxel Dörfler } 515*5fe97f21SAxel Dörfler if (count == 0) { 516*5fe97f21SAxel Dörfler BMenuItem* item = new BMenuItem( 517*5fe97f21SAxel Dörfler B_TRANSLATE("<no wireless networks found>"), NULL); 518*5fe97f21SAxel Dörfler item->SetEnabled(false); 519*5fe97f21SAxel Dörfler menu->AddItem(item); 520*5fe97f21SAxel Dörfler } 521*5fe97f21SAxel Dörfler menu->AddSeparatorItem(); 522*5fe97f21SAxel Dörfler 523*5fe97f21SAxel Dörfler // We only show the networks of the first wireless device we find. 524*5fe97f21SAxel Dörfler break; 525*5fe97f21SAxel Dörfler } 526*5fe97f21SAxel Dörfler 527757e7059SAdrien Destugues menu->AddItem(new BMenuItem(B_TRANSLATE( 528757e7059SAdrien Destugues "Open network preferences" B_UTF8_ELLIPSIS), 529c1502c9aSStephan Aßmus new BMessage(kMsgOpenNetworkPreferences))); 5303b41ad86SStephan Aßmus 531*5fe97f21SAxel Dörfler if (fInDeskbar) { 532757e7059SAdrien Destugues menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 533757e7059SAdrien Destugues new BMessage(B_QUIT_REQUESTED))); 534*5fe97f21SAxel Dörfler } 535f01106c3SAxel Dörfler menu->SetTargetForItems(this); 536f01106c3SAxel Dörfler 537f01106c3SAxel Dörfler ConvertToScreen(&point); 538a31688d2SAxel Dörfler menu->Go(point, true, true, true); 539f01106c3SAxel Dörfler } 540f01106c3SAxel Dörfler 541f01106c3SAxel Dörfler 542f01106c3SAxel Dörfler void 543f01106c3SAxel Dörfler NetworkStatusView::_AboutRequested() 544f01106c3SAxel Dörfler { 545*5fe97f21SAxel Dörfler BString about = B_TRANSLATE( 546757e7059SAdrien Destugues "NetworkStatus\n\twritten by %1 and Hugo Santos\n\t%2, Haiku, Inc.\n" 547757e7059SAdrien Destugues ); 548*5fe97f21SAxel Dörfler about.ReplaceFirst("%1", "Axel Dörfler"); 549757e7059SAdrien Destugues // Append a new developer here 550*5fe97f21SAxel Dörfler about.ReplaceFirst("%2", "Copyright 2007-2010"); 551757e7059SAdrien Destugues // Append a new year here 552*5fe97f21SAxel Dörfler BAlert* alert = new BAlert("about", about, B_TRANSLATE("OK")); 553f01106c3SAxel Dörfler BTextView *view = alert->TextView(); 554f01106c3SAxel Dörfler BFont font; 555f01106c3SAxel Dörfler 556f01106c3SAxel Dörfler view->SetStylable(true); 557f01106c3SAxel Dörfler 558f01106c3SAxel Dörfler view->GetFont(&font); 559f01106c3SAxel Dörfler font.SetSize(18); 560f01106c3SAxel Dörfler font.SetFace(B_BOLD_FACE); 561f01106c3SAxel Dörfler view->SetFontAndColor(0, 13, &font); 562f01106c3SAxel Dörfler 563f01106c3SAxel Dörfler alert->Go(); 564f01106c3SAxel Dörfler } 565f01106c3SAxel Dörfler 566f01106c3SAxel Dörfler 567f01106c3SAxel Dörfler bool 568f01106c3SAxel Dörfler NetworkStatusView::_PrepareRequest(struct ifreq& request, const char* name) 569f01106c3SAxel Dörfler { 570f01106c3SAxel Dörfler if (strlen(name) > IF_NAMESIZE) 571f01106c3SAxel Dörfler return false; 572f01106c3SAxel Dörfler 573f01106c3SAxel Dörfler strcpy(request.ifr_name, name); 574f01106c3SAxel Dörfler return true; 575f01106c3SAxel Dörfler } 576f01106c3SAxel Dörfler 577f01106c3SAxel Dörfler 578f01106c3SAxel Dörfler int32 579f01106c3SAxel Dörfler NetworkStatusView::_DetermineInterfaceStatus(const char* name) 580f01106c3SAxel Dörfler { 581*5fe97f21SAxel Dörfler BNetworkInterface interface(name); 582*5fe97f21SAxel Dörfler uint32 flags = interface.Flags(); 583f01106c3SAxel Dörfler int32 status = kStatusNoLink; 584f01106c3SAxel Dörfler 585f01106c3SAxel Dörfler // TODO: no kStatusLinkNoConfig yet 586f01106c3SAxel Dörfler 587f01106c3SAxel Dörfler if (flags & IFF_CONFIGURING) 588f01106c3SAxel Dörfler status = kStatusConnecting; 5892a17be44SAxel Dörfler else if ((flags & (IFF_UP | IFF_LINK)) == (IFF_UP | IFF_LINK)) 590f01106c3SAxel Dörfler status = kStatusReady; 591f01106c3SAxel Dörfler 592f01106c3SAxel Dörfler return status; 593f01106c3SAxel Dörfler } 594f01106c3SAxel Dörfler 595f01106c3SAxel Dörfler 596f01106c3SAxel Dörfler void 597f01106c3SAxel Dörfler NetworkStatusView::_Update(bool force) 598f01106c3SAxel Dörfler { 599f01106c3SAxel Dörfler int32 oldStatus = fStatus; 600f01106c3SAxel Dörfler fStatus = kStatusUnknown; 601f01106c3SAxel Dörfler fInterfaces.MakeEmpty(); 602f01106c3SAxel Dörfler 603*5fe97f21SAxel Dörfler BNetworkRoster& roster = BNetworkRoster::Default(); 604*5fe97f21SAxel Dörfler BNetworkInterface interface; 605*5fe97f21SAxel Dörfler uint32 cookie = 0; 606*5fe97f21SAxel Dörfler 607*5fe97f21SAxel Dörfler while (roster.GetNextInterface(&cookie, interface) == B_OK) { 608*5fe97f21SAxel Dörfler if ((interface.Flags() & IFF_LOOPBACK) == 0) { 609*5fe97f21SAxel Dörfler fInterfaces.AddItem(new BString(interface.Name())); 610*5fe97f21SAxel Dörfler int32 status = _DetermineInterfaceStatus(interface.Name()); 611f01106c3SAxel Dörfler if (status > fStatus) 612f01106c3SAxel Dörfler fStatus = status; 613f01106c3SAxel Dörfler } 614f01106c3SAxel Dörfler } 615f01106c3SAxel Dörfler 616f01106c3SAxel Dörfler if (fStatus != oldStatus) 617f01106c3SAxel Dörfler Invalidate(); 618f01106c3SAxel Dörfler } 619f01106c3SAxel Dörfler 620f01106c3SAxel Dörfler 6213b41ad86SStephan Aßmus void 6223b41ad86SStephan Aßmus NetworkStatusView::_OpenNetworksPreferences() 6233b41ad86SStephan Aßmus { 624195981bbSAxel Dörfler status_t status = be_roster->Launch("application/x-vnd.Haiku-Network"); 62546cac7f7SAlexandre Deckner if (status != B_OK && status != B_ALREADY_RUNNING) { 626757e7059SAdrien Destugues BString errorMessage(B_TRANSLATE("Launching the network preflet " 627757e7059SAdrien Destugues "failed.\n\nError: ")); 628195981bbSAxel Dörfler errorMessage << strerror(status); 6293b41ad86SStephan Aßmus BAlert* alert = new BAlert("launch error", errorMessage.String(), 630757e7059SAdrien Destugues B_TRANSLATE("OK")); 631195981bbSAxel Dörfler 632195981bbSAxel Dörfler // asynchronous alert in order to not block replicant host application 6333b41ad86SStephan Aßmus alert->Go(NULL); 6343b41ad86SStephan Aßmus } 6353b41ad86SStephan Aßmus } 6363b41ad86SStephan Aßmus 6373b41ad86SStephan Aßmus 638f01106c3SAxel Dörfler // #pragma mark - 639f01106c3SAxel Dörfler 640f01106c3SAxel Dörfler 641f01106c3SAxel Dörfler extern "C" _EXPORT BView * 642f01106c3SAxel Dörfler instantiate_deskbar_item(void) 643f01106c3SAxel Dörfler { 64466eba86fSAxel Dörfler return new NetworkStatusView(BRect(0, 0, 15, 15), 64566eba86fSAxel Dörfler B_FOLLOW_LEFT | B_FOLLOW_TOP, true); 646f01106c3SAxel Dörfler } 647f01106c3SAxel Dörfler 648