net_server: initial replicant version.
* Still picture-less and thus ugly. * It provides updated information on what the net_server is doing in terms of interface configuration. * It is also able to show simplistic address information for configured interfaces. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20523 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -40,6 +40,11 @@ AutoconfigLooper::~AutoconfigLooper()
|
|||||||
void
|
void
|
||||||
AutoconfigLooper::_ReadyToRun()
|
AutoconfigLooper::_ReadyToRun()
|
||||||
{
|
{
|
||||||
|
BMessage interface(kMsgConfigureInterface);
|
||||||
|
interface.AddString("device", fDevice.String());
|
||||||
|
interface.AddInt32("net:status", kStatusPreparing);
|
||||||
|
fTarget.SendMessage(&interface);
|
||||||
|
|
||||||
// start with DHCP
|
// start with DHCP
|
||||||
|
|
||||||
DHCPClient* client = new DHCPClient(fTarget, fDevice.String());
|
DHCPClient* client = new DHCPClient(fTarget, fDevice.String());
|
||||||
@@ -57,8 +62,7 @@ AutoconfigLooper::_ReadyToRun()
|
|||||||
// TODO: have a look at zeroconf
|
// TODO: have a look at zeroconf
|
||||||
// TODO: this could also be done add-on based
|
// TODO: this could also be done add-on based
|
||||||
|
|
||||||
BMessage interface;
|
interface.ReplaceInt32("net:status", kStatusLinkNoConfig);
|
||||||
interface.AddString("device", fDevice.String());
|
|
||||||
|
|
||||||
uint8 mac[6];
|
uint8 mac[6];
|
||||||
uint8 last = 56;
|
uint8 last = 56;
|
||||||
@@ -80,7 +84,7 @@ AutoconfigLooper::_ReadyToRun()
|
|||||||
address.AddString("gateway", "192.168.0.254");
|
address.AddString("gateway", "192.168.0.254");
|
||||||
interface.AddMessage("address", &address);
|
interface.AddMessage("address", &address);
|
||||||
|
|
||||||
fTarget.SendMessage(kMsgConfigureInterface, &interface);
|
fTarget.SendMessage(&interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -474,6 +474,7 @@ DHCPClient::_Negotiate(dhcp_state state)
|
|||||||
|
|
||||||
fConfiguration.MakeEmpty();
|
fConfiguration.MakeEmpty();
|
||||||
fConfiguration.AddString("device", fDevice.String());
|
fConfiguration.AddString("device", fDevice.String());
|
||||||
|
fConfiguration.AddInt32("net:status", kStatusConnected);
|
||||||
|
|
||||||
BMessage address;
|
BMessage address;
|
||||||
address.AddString("family", "inet");
|
address.AddString("family", "inet");
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Server net_server :
|
|||||||
AutoconfigLooper.cpp
|
AutoconfigLooper.cpp
|
||||||
DHCPClient.cpp
|
DHCPClient.cpp
|
||||||
Services.cpp
|
Services.cpp
|
||||||
|
StatusReplicant.cpp
|
||||||
|
|
||||||
: be libnetwork.so $(TARGET_LIBSTDC++)
|
: be libnetwork.so $(TARGET_LIBSTDC++)
|
||||||
# for PPP
|
# for PPP
|
||||||
|
|||||||
+129
-10
@@ -11,12 +11,15 @@
|
|||||||
#include "NetServer.h"
|
#include "NetServer.h"
|
||||||
#include "Services.h"
|
#include "Services.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "StatusReplicant.h"
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
|
#include <Deskbar.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <NodeMonitor.h>
|
#include <NodeMonitor.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
#include <Roster.h>
|
||||||
#include <Server.h>
|
#include <Server.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
@@ -36,7 +39,12 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
const char *kSignature = "application/x-vnd.haiku-net_server";
|
||||||
|
static const char *kDeskbarSignature = "application/x-vnd.Be-TSKB";
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<std::string, BLooper*> LooperMap;
|
typedef std::map<std::string, BLooper*> LooperMap;
|
||||||
|
typedef std::map<std::string, int> StatusMap;
|
||||||
|
|
||||||
|
|
||||||
class NetServer : public BServer {
|
class NetServer : public BServer {
|
||||||
@@ -61,10 +69,15 @@ class NetServer : public BServer {
|
|||||||
void _ConfigureInterfaces(int socket, BMessage* _missingDevice = NULL);
|
void _ConfigureInterfaces(int socket, BMessage* _missingDevice = NULL);
|
||||||
void _BringUpInterfaces();
|
void _BringUpInterfaces();
|
||||||
void _StartServices();
|
void _StartServices();
|
||||||
|
status_t _AddStatusReplicant(bool force);
|
||||||
|
void _UpdateDeviceStatus(const char *device, int status);
|
||||||
|
void _UpdateReplicantStatus();
|
||||||
|
|
||||||
Settings fSettings;
|
Settings fSettings;
|
||||||
LooperMap fDeviceMap;
|
LooperMap fDeviceMap;
|
||||||
|
StatusMap fStatusMap;
|
||||||
BMessenger fServices;
|
BMessenger fServices;
|
||||||
|
BMessenger fStatusMessenger;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -236,7 +249,7 @@ get_mac_address(const char* device, uint8* address)
|
|||||||
|
|
||||||
|
|
||||||
NetServer::NetServer(status_t& error)
|
NetServer::NetServer(status_t& error)
|
||||||
: BServer("application/x-vnd.haiku-net_server", false, &error)
|
: BServer(kSignature, false, &error)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +279,13 @@ NetServer::ReadyToRun()
|
|||||||
fSettings.StartMonitoring(this);
|
fSettings.StartMonitoring(this);
|
||||||
_BringUpInterfaces();
|
_BringUpInterfaces();
|
||||||
_StartServices();
|
_StartServices();
|
||||||
|
|
||||||
|
// we have to wait for Deskbar to show up before
|
||||||
|
// adding the status replicant
|
||||||
|
be_roster->StartWatching(BMessenger(this), B_REQUEST_LAUNCHED);
|
||||||
|
// but possibly the Deskbar is already running
|
||||||
|
// so add immediatly
|
||||||
|
_AddStatusReplicant(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -305,18 +325,49 @@ NetServer::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need a socket to talk to the networking stack
|
status_t status = B_OK;
|
||||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
if (message->GetInfo("address", NULL) != B_NAME_NOT_FOUND) {
|
||||||
if (socket < 0)
|
// we need a socket to talk to the networking stack
|
||||||
break;
|
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
status_t status = _ConfigureInterface(socket, *message, true);
|
status = _ConfigureInterface(socket, *message, true);
|
||||||
|
|
||||||
BMessage reply(B_REPLY);
|
BMessage reply(B_REPLY);
|
||||||
reply.AddInt32("status", status);
|
reply.AddInt32("status", status);
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
|
|
||||||
close(socket);
|
close(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
const char *device;
|
||||||
|
int32 net_status;
|
||||||
|
if (message->FindInt32("net:status", &net_status) == B_OK &&
|
||||||
|
message->FindString("device", &device) == B_OK) {
|
||||||
|
_UpdateDeviceStatus(device, net_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_SOME_APP_LAUNCHED:
|
||||||
|
{
|
||||||
|
// check if Deskbar was launched
|
||||||
|
const char *signature;
|
||||||
|
if (message->FindString("be:signature", &signature) == B_OK) {
|
||||||
|
if (strcmp(signature, kDeskbarSignature) == 0)
|
||||||
|
_AddStatusReplicant(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kRegisterStatusReplicant:
|
||||||
|
{
|
||||||
|
message->FindMessenger("messenger", &fStatusMessenger);
|
||||||
|
_UpdateReplicantStatus();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,6 +783,13 @@ NetServer::_QuitLooperForDevice(const char* device)
|
|||||||
iterator->second->Quit();
|
iterator->second->Quit();
|
||||||
|
|
||||||
fDeviceMap.erase(iterator);
|
fDeviceMap.erase(iterator);
|
||||||
|
|
||||||
|
StatusMap::iterator it = fStatusMap.find(device);
|
||||||
|
if (it != fStatusMap.end()) {
|
||||||
|
fStatusMap.erase(it);
|
||||||
|
_UpdateReplicantStatus();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,6 +935,67 @@ NetServer::_StartServices()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NetServer::_AddStatusReplicant(bool force)
|
||||||
|
{
|
||||||
|
BDeskbar deskbar;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
if (deskbar.HasItem(kStatusReplicant)) {
|
||||||
|
if (force) {
|
||||||
|
status = deskbar.RemoveItem(kStatusReplicant);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusReplicant *replicant = new StatusReplicant();
|
||||||
|
status = deskbar.AddItem(replicant);
|
||||||
|
delete replicant;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NetServer::_UpdateDeviceStatus(const char *device, int status)
|
||||||
|
{
|
||||||
|
StatusMap::iterator it = fStatusMap.find(device);
|
||||||
|
if (it != fStatusMap.end() && it->second == status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fStatusMap[device] = status;
|
||||||
|
_UpdateReplicantStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NetServer::_UpdateReplicantStatus()
|
||||||
|
{
|
||||||
|
if (!fStatusMessenger.IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int prevaling = kStatusUnknown;
|
||||||
|
|
||||||
|
BMessage message(kStatusUpdate);
|
||||||
|
|
||||||
|
for (StatusMap::iterator it = fStatusMap.begin();
|
||||||
|
it != fStatusMap.end(); ++it) {
|
||||||
|
if (it->second > prevaling)
|
||||||
|
prevaling = it->second;
|
||||||
|
|
||||||
|
message.AddString("intf:name", it->first.c_str());
|
||||||
|
message.AddInt32("intf:status", it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.AddInt32("net:status", prevaling);
|
||||||
|
|
||||||
|
fStatusMessenger.SendMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,17 @@
|
|||||||
|
|
||||||
|
|
||||||
static const uint32 kMsgConfigureInterface = 'COif';
|
static const uint32 kMsgConfigureInterface = 'COif';
|
||||||
|
extern const char *kSignature;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kStatusUnknown = 0,
|
||||||
|
kStatusNoLink,
|
||||||
|
kStatusLinkNoConfig,
|
||||||
|
kStatusConnected,
|
||||||
|
kStatusPreparing,
|
||||||
|
|
||||||
|
kStatusCount
|
||||||
|
};
|
||||||
|
|
||||||
extern bool get_family_index(const char* name, int32& familyIndex);
|
extern bool get_family_index(const char* name, int32& familyIndex);
|
||||||
extern int family_at_index(int32 index);
|
extern int family_at_index(int32 index);
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hugo Santos, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NetServer.h"
|
||||||
|
#include "StatusReplicant.h"
|
||||||
|
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
const char *kStatusReplicant = "NetStatusView";
|
||||||
|
static const uint32 kShowConfiguration = 'shcf';
|
||||||
|
|
||||||
|
static const uint8 kStatusColors[kStatusCount][3] = {
|
||||||
|
{ 0, 0, 0 }, // Unknown
|
||||||
|
{ 255, 0, 0 }, // NoLink
|
||||||
|
{ 0, 0, 255 }, // LinkNoConfig
|
||||||
|
{ 0, 255, 0 }, // Connected
|
||||||
|
{ 255, 255, 0 }, // Preparing
|
||||||
|
};
|
||||||
|
|
||||||
|
struct information_entry {
|
||||||
|
const char *label;
|
||||||
|
int ioc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const information_entry kInformationEntries[] = {
|
||||||
|
{ "Address", SIOCGIFADDR },
|
||||||
|
{ "Broadcast", SIOCGIFBRDADDR },
|
||||||
|
{ "Netmask", SIOCGIFNETMASK },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const char *kStatusDescriptions[] = {
|
||||||
|
"Unknown",
|
||||||
|
"No Link",
|
||||||
|
"No stateful configuration",
|
||||||
|
"Ready",
|
||||||
|
"Configuring",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
StatusReplicant::StatusReplicant()
|
||||||
|
: BView(BRect(0, 0, 15, 15), kStatusReplicant, B_FOLLOW_ALL, 0),
|
||||||
|
fPopup("", false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StatusReplicant::StatusReplicant(BMessage *message)
|
||||||
|
: BView(message), fPopup("", false, false)
|
||||||
|
{
|
||||||
|
// TODO: Load status bitmaps from resources
|
||||||
|
for (int i = 0; i < kStatusCount; i++)
|
||||||
|
fBitmaps[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StatusReplicant::~StatusReplicant()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StatusReplicant *
|
||||||
|
StatusReplicant::Instantiate(BMessage *data)
|
||||||
|
{
|
||||||
|
if (validate_instantiation(data, kStatusReplicant))
|
||||||
|
return new StatusReplicant(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
StatusReplicant::Archive(BMessage *data, bool deep) const
|
||||||
|
{
|
||||||
|
BView::Archive(data, deep);
|
||||||
|
data->AddString("add_on", kSignature);
|
||||||
|
data->AddString("class", kStatusReplicant);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BMessage message(kRegisterStatusReplicant);
|
||||||
|
message.AddMessenger("messenger", BMessenger(this));
|
||||||
|
|
||||||
|
if (BMessenger(kSignature).SendMessage(&message) != B_OK) {
|
||||||
|
// TODO: Remove myself from Deskbar
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeStatus(kStatusUnknown);
|
||||||
|
PrepareMenu(InterfaceStatusList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kStatusUpdate:
|
||||||
|
UpdateFromMessage(message);
|
||||||
|
break;
|
||||||
|
case kShowConfiguration:
|
||||||
|
ShowConfiguration(message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BView::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::MouseDown(BPoint point)
|
||||||
|
{
|
||||||
|
uint32 buttons;
|
||||||
|
BPoint where;
|
||||||
|
|
||||||
|
GetMouse(&where, &buttons, true);
|
||||||
|
where = ConvertToScreen(point);
|
||||||
|
|
||||||
|
fPopup.SetTargetForItems(this);
|
||||||
|
fPopup.Go(where, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::UpdateFromMessage(BMessage *message)
|
||||||
|
{
|
||||||
|
int32 newStatus, intfStatus;
|
||||||
|
|
||||||
|
if (message->FindInt32("net:status", &newStatus) != B_OK
|
||||||
|
|| newStatus < 0 || newStatus >= kStatusCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
InterfaceStatusList status;
|
||||||
|
int index = 0;
|
||||||
|
while (message->FindInt32("intf:status", index, &intfStatus) == B_OK) {
|
||||||
|
if (intfStatus < 0 || intfStatus >= kStatusCount)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const char *name;
|
||||||
|
if (message->FindString("intf:name", index, &name) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
status.push_back(InterfaceStatus(name, intfStatus));
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeStatus(newStatus);
|
||||||
|
PrepareMenu(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::ShowConfiguration(BMessage *message)
|
||||||
|
{
|
||||||
|
const char *device;
|
||||||
|
if (message->FindString("intf:name", &device) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 status;
|
||||||
|
if (message->FindInt32("intf:status", &status) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (status != kStatusConnected && status != kStatusLinkNoConfig)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sock < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (strlen(device) > IF_NAMESIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ifreq request;
|
||||||
|
memset(&request, 0, sizeof(request));
|
||||||
|
strcpy(request.ifr_name, device);
|
||||||
|
|
||||||
|
string text = device;
|
||||||
|
text += " information:\n";
|
||||||
|
size_t boldLength = text.size();
|
||||||
|
|
||||||
|
for (int i = 0; kInformationEntries[i].label; i++) {
|
||||||
|
if (ioctl(sock, kInformationEntries[i].ioc, &request,
|
||||||
|
sizeof(request)) < 0) {
|
||||||
|
close(sock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char address[32];
|
||||||
|
if (inet_ntop(AF_INET, &((sockaddr_in *)&request.ifr_addr)->sin_addr,
|
||||||
|
address, sizeof(address)) == NULL) {
|
||||||
|
close(sock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
text += "\n";
|
||||||
|
text += kInformationEntries[i].label;
|
||||||
|
text += ": ";
|
||||||
|
text += address;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
|
||||||
|
BAlert *info = new BAlert(device, text.c_str(), "Ok");
|
||||||
|
BTextView *view = info->TextView();
|
||||||
|
BFont font;
|
||||||
|
|
||||||
|
view->SetStylable(true);
|
||||||
|
view->GetFont(&font);
|
||||||
|
font.SetSize(12);
|
||||||
|
font.SetFace(B_BOLD_FACE);
|
||||||
|
view->SetFontAndColor(0, boldLength, &font);
|
||||||
|
|
||||||
|
info->Go(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::PrepareMenu(const InterfaceStatusList &status)
|
||||||
|
{
|
||||||
|
while (fPopup.RemoveItem((int32)0));
|
||||||
|
|
||||||
|
if (status.empty()) {
|
||||||
|
fPopup.AddItem(new BMenuItem("No interfaces available.", NULL));
|
||||||
|
fPopup.ItemAt(0)->SetEnabled(false);
|
||||||
|
} else {
|
||||||
|
for (InterfaceStatusList::const_iterator i = status.begin();
|
||||||
|
i != status.end(); ++i) {
|
||||||
|
std::string label = i->first;
|
||||||
|
label += ": ";
|
||||||
|
label += kStatusDescriptions[i->second];
|
||||||
|
|
||||||
|
BMessage *message = new BMessage(kShowConfiguration);
|
||||||
|
message->AddString("intf:name", i->first.c_str());
|
||||||
|
message->AddInt32("intf:status", i->second);
|
||||||
|
|
||||||
|
BMenuItem *item = new BMenuItem(label.c_str(), message);
|
||||||
|
if (i->second != kStatusConnected &&
|
||||||
|
i->second != kStatusLinkNoConfig)
|
||||||
|
item->SetEnabled(false);
|
||||||
|
fPopup.AddItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StatusReplicant::ChangeStatus(int newStatus)
|
||||||
|
{
|
||||||
|
if (fBitmaps[newStatus]) {
|
||||||
|
SetViewColor(Parent()->ViewColor());
|
||||||
|
SetViewBitmap(fBitmaps[newStatus]);
|
||||||
|
} else {
|
||||||
|
ClearViewBitmap();
|
||||||
|
SetViewColor(kStatusColors[newStatus][0],
|
||||||
|
kStatusColors[newStatus][1],
|
||||||
|
kStatusColors[newStatus][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hugo Santos, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STATUS_REPLICANT_H
|
||||||
|
#define _STATUS_REPLICANT_H
|
||||||
|
|
||||||
|
#include "NetServer.h"
|
||||||
|
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
static const uint32 kRegisterStatusReplicant = 'rnsr';
|
||||||
|
static const uint32 kStatusUpdate = 'stup';
|
||||||
|
extern const char *kStatusReplicant;
|
||||||
|
|
||||||
|
class StatusReplicant : public BView {
|
||||||
|
public:
|
||||||
|
StatusReplicant();
|
||||||
|
StatusReplicant(BMessage *);
|
||||||
|
virtual ~StatusReplicant();
|
||||||
|
|
||||||
|
static StatusReplicant *Instantiate(BMessage *);
|
||||||
|
status_t Archive(BMessage *, bool deep) const;
|
||||||
|
|
||||||
|
void AttachedToWindow();
|
||||||
|
void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
void MouseDown(BPoint point);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::pair<std::string, int> InterfaceStatus;
|
||||||
|
typedef std::vector<InterfaceStatus> InterfaceStatusList;
|
||||||
|
|
||||||
|
void UpdateFromMessage(BMessage *);
|
||||||
|
void ShowConfiguration(BMessage *);
|
||||||
|
void PrepareMenu(const InterfaceStatusList &);
|
||||||
|
void ChangeStatus(int newStatus);
|
||||||
|
|
||||||
|
BPopUpMenu fPopup;
|
||||||
|
BBitmap *fBitmaps[kStatusCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user