254 lines
5.0 KiB
C++
254 lines
5.0 KiB
C++
/*
|
|
* Copyright 2009-2021, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Michael Weirauch, dev@m-phasis.de
|
|
*/
|
|
|
|
|
|
#include "DeskbarReplicant.h"
|
|
|
|
#include <Alert.h>
|
|
#include <Application.h>
|
|
#include <Bitmap.h>
|
|
#include <Catalog.h>
|
|
#include <Deskbar.h>
|
|
#include <IconUtils.h>
|
|
#include <MenuItem.h>
|
|
#include <Message.h>
|
|
#include <PopUpMenu.h>
|
|
#include <Resources.h>
|
|
#include <Roster.h>
|
|
#include <String.h>
|
|
|
|
#include <bluetoothserver_p.h>
|
|
|
|
|
|
extern "C" _EXPORT BView *instantiate_deskbar_item(float maxWidth, float maxHeight);
|
|
status_t our_image(image_info& image);
|
|
|
|
const uint32 kMsgOpenBluetoothPreferences = 'obtp';
|
|
const uint32 kMsgQuitBluetoothServer = 'qbts';
|
|
|
|
const char* kDeskbarItemName = "BluetoothServerReplicant";
|
|
const char* kClassName = "DeskbarReplicant";
|
|
|
|
|
|
#undef B_TRANSLATION_CONTEXT
|
|
#define B_TRANSLATION_CONTEXT "BluetoothReplicant"
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
DeskbarReplicant::DeskbarReplicant(BRect frame, int32 resizingMode)
|
|
: BView(frame, kDeskbarItemName, resizingMode,
|
|
B_WILL_DRAW | B_TRANSPARENT_BACKGROUND | B_FRAME_EVENTS)
|
|
{
|
|
_Init();
|
|
}
|
|
|
|
|
|
DeskbarReplicant::DeskbarReplicant(BMessage* archive)
|
|
: BView(archive)
|
|
{
|
|
_Init();
|
|
}
|
|
|
|
|
|
DeskbarReplicant::~DeskbarReplicant()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::_Init()
|
|
{
|
|
fIcon = NULL;
|
|
|
|
image_info info;
|
|
if (our_image(info) != B_OK)
|
|
return;
|
|
|
|
BFile file(info.name, B_READ_ONLY);
|
|
if (file.InitCheck() < B_OK)
|
|
return;
|
|
|
|
BResources resources(&file);
|
|
if (resources.InitCheck() < B_OK)
|
|
return;
|
|
|
|
size_t size;
|
|
const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE,
|
|
"tray_icon", &size);
|
|
if (data != NULL) {
|
|
BBitmap* icon = new BBitmap(Bounds(), B_RGBA32);
|
|
if (icon->InitCheck() == B_OK
|
|
&& BIconUtils::GetVectorIcon((const uint8 *)data,
|
|
size, icon) == B_OK) {
|
|
fIcon = icon;
|
|
} else
|
|
delete icon;
|
|
}
|
|
}
|
|
|
|
|
|
DeskbarReplicant *
|
|
DeskbarReplicant::Instantiate(BMessage* archive)
|
|
{
|
|
if (!validate_instantiation(archive, kClassName))
|
|
return NULL;
|
|
|
|
return new DeskbarReplicant(archive);
|
|
}
|
|
|
|
|
|
status_t
|
|
DeskbarReplicant::Archive(BMessage* archive, bool deep) const
|
|
{
|
|
status_t status = BView::Archive(archive, deep);
|
|
if (status == B_OK)
|
|
status = archive->AddString("add_on", BLUETOOTH_SIGNATURE);
|
|
if (status == B_OK)
|
|
status = archive->AddString("class", kClassName);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::AttachedToWindow()
|
|
{
|
|
BView::AttachedToWindow();
|
|
AdoptParentColors();
|
|
|
|
if (ViewUIColor() == B_NO_COLOR)
|
|
SetLowColor(ViewColor());
|
|
else
|
|
SetLowUIColor(ViewUIColor());
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::Draw(BRect updateRect)
|
|
{
|
|
if (!fIcon) {
|
|
/* At least display something... */
|
|
rgb_color lowColor = LowColor();
|
|
SetLowColor(0, 113, 187, 255);
|
|
FillRoundRect(Bounds().InsetBySelf(3.f, 0.f), 5.f, 7.f, B_SOLID_LOW);
|
|
SetLowColor(lowColor);
|
|
} else {
|
|
SetDrawingMode(B_OP_ALPHA);
|
|
DrawBitmap(fIcon);
|
|
SetDrawingMode(B_OP_COPY);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::MessageReceived(BMessage* msg)
|
|
{
|
|
switch (msg->what) {
|
|
case kMsgOpenBluetoothPreferences:
|
|
be_roster->Launch(BLUETOOTH_APP_SIGNATURE);
|
|
break;
|
|
|
|
case kMsgQuitBluetoothServer:
|
|
_QuitBluetoothServer();
|
|
break;
|
|
|
|
default:
|
|
BView::MessageReceived(msg);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::MouseDown(BPoint where)
|
|
{
|
|
BPoint point;
|
|
uint32 buttons;
|
|
GetMouse(&point, &buttons);
|
|
if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) {
|
|
return;
|
|
}
|
|
|
|
BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
|
|
|
menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
|
|
new BMessage(kMsgOpenBluetoothPreferences)));
|
|
|
|
// TODO show list of known/paired devices
|
|
|
|
menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"),
|
|
new BMessage(kMsgQuitBluetoothServer)));
|
|
|
|
menu->SetTargetForItems(this);
|
|
ConvertToScreen(&point);
|
|
menu->Go(point, true, true, true);
|
|
|
|
delete menu;
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::_QuitBluetoothServer()
|
|
{
|
|
if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) {
|
|
// The server isn't running, so remove ourself
|
|
BDeskbar deskbar;
|
|
deskbar.RemoveItem(kDeskbarItemName);
|
|
|
|
return;
|
|
}
|
|
status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage(
|
|
B_QUIT_REQUESTED);
|
|
if (status < B_OK) {
|
|
_ShowErrorAlert(B_TRANSLATE("Stopping the Bluetooth server failed."),
|
|
status);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
DeskbarReplicant::_ShowErrorAlert(BString msg, status_t status)
|
|
{
|
|
BString error = B_TRANSLATE("Error: %status%");
|
|
error.ReplaceFirst("%status%", strerror(status));
|
|
msg << "\n\n" << error;
|
|
BAlert* alert = new BAlert(B_TRANSLATE("Bluetooth error"), msg.String(),
|
|
B_TRANSLATE("OK"));
|
|
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
|
alert->Go(NULL);
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
extern "C" _EXPORT BView *
|
|
instantiate_deskbar_item(float maxWidth, float maxHeight)
|
|
{
|
|
return new DeskbarReplicant(BRect(0, 0, maxHeight - 1, maxHeight - 1),
|
|
B_FOLLOW_NONE);
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
status_t
|
|
our_image(image_info& image)
|
|
{
|
|
int32 cookie = 0;
|
|
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
|
|
if ((char *)our_image >= (char *)image.text
|
|
&& (char *)our_image <= (char *)image.text + image.text_size)
|
|
return B_OK;
|
|
}
|
|
|
|
return B_ERROR;
|
|
}
|