1 /* 2 * Copyright 2009, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Weirauch, dev@m-phasis.de 7 */ 8 9 10 #include "DeskbarReplicant.h" 11 12 #include <Alert.h> 13 #include <Application.h> 14 #include <Bitmap.h> 15 #include <Deskbar.h> 16 #include <IconUtils.h> 17 #include <MenuItem.h> 18 #include <Message.h> 19 #include <PopUpMenu.h> 20 #include <Resources.h> 21 #include <Roster.h> 22 #include <String.h> 23 24 #include <bluetoothserver_p.h> 25 26 extern "C" _EXPORT BView *instantiate_deskbar_item(void); 27 status_t our_image(image_info& image); 28 29 const uint32 kMsgShowBluetoothServerConsole = 'sbtc'; 30 const uint32 kMsgOpenBluetoothPreferences = 'obtp'; 31 const uint32 kMsgQuitBluetoothServer = 'qbts'; 32 33 const char* kDeskbarItemName = "BluetoothServerReplicant"; 34 const char* kClassName = "DeskbarReplicant"; 35 36 // #pragma mark - 37 38 39 DeskbarReplicant::DeskbarReplicant(BRect frame, int32 resizingMode) 40 : BView(frame, kDeskbarItemName, resizingMode, 41 B_WILL_DRAW | B_FRAME_EVENTS) 42 { 43 _Init(); 44 } 45 46 47 DeskbarReplicant::DeskbarReplicant(BMessage* archive) 48 : BView(archive) 49 { 50 _Init(); 51 } 52 53 54 DeskbarReplicant::~DeskbarReplicant() 55 { 56 } 57 58 59 void 60 DeskbarReplicant::_Init() 61 { 62 fIcon = NULL; 63 64 image_info info; 65 if (our_image(info) != B_OK) 66 return; 67 68 BFile file(info.name, B_READ_ONLY); 69 if (file.InitCheck() < B_OK) 70 return; 71 72 BResources resources(&file); 73 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 74 if (resources.InitCheck() < B_OK) 75 return; 76 #endif 77 78 size_t size; 79 const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, 80 "BEOS:ICON", &size); 81 if (data != NULL) { 82 BBitmap* icon = new BBitmap(Bounds(), B_RGBA32); 83 if (icon->InitCheck() == B_OK 84 && BIconUtils::GetVectorIcon((const uint8 *)data, 85 size, icon) == B_OK) { 86 fIcon = icon; 87 } else 88 delete icon; 89 } 90 } 91 92 93 DeskbarReplicant * 94 DeskbarReplicant::Instantiate(BMessage* archive) 95 { 96 if (!validate_instantiation(archive, kClassName)) 97 return NULL; 98 99 return new DeskbarReplicant(archive); 100 } 101 102 103 status_t 104 DeskbarReplicant::Archive(BMessage* archive, bool deep) const 105 { 106 status_t status = BView::Archive(archive, deep); 107 if (status == B_OK) 108 status = archive->AddString("add_on", BLUETOOTH_SIGNATURE); 109 if (status == B_OK) 110 status = archive->AddString("class", kClassName); 111 112 return status; 113 } 114 115 116 void 117 DeskbarReplicant::AttachedToWindow() 118 { 119 BView::AttachedToWindow(); 120 if (Parent()) 121 SetViewColor(Parent()->ViewColor()); 122 else 123 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 124 125 SetLowColor(ViewColor()); 126 } 127 128 129 void 130 DeskbarReplicant::Draw(BRect updateRect) 131 { 132 if (!fIcon) { 133 /* At least display something... */ 134 rgb_color lowColor = LowColor(); 135 SetLowColor(0, 113, 187, 255); 136 FillRoundRect(Bounds().InsetBySelf(3.f, 0.f), 5.f, 7.f, B_SOLID_LOW); 137 SetLowColor(lowColor); 138 } else { 139 SetDrawingMode(B_OP_ALPHA); 140 DrawBitmap(fIcon); 141 SetDrawingMode(B_OP_COPY); 142 } 143 } 144 145 146 void 147 DeskbarReplicant::MessageReceived(BMessage* msg) 148 { 149 switch (msg->what) { 150 case kMsgShowBluetoothServerConsole: 151 _ShowBluetoothServerConsole(); 152 break; 153 154 case kMsgOpenBluetoothPreferences: 155 _OpenBluetoothPreferences(); 156 break; 157 158 case kMsgQuitBluetoothServer: 159 _QuitBluetoothServer(); 160 break; 161 162 default: 163 BView::MessageReceived(msg); 164 } 165 } 166 167 168 void 169 DeskbarReplicant::MouseDown(BPoint where) 170 { 171 BPoint point; 172 uint32 buttons; 173 GetMouse(&point, &buttons); 174 if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) { 175 return; 176 } 177 178 BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false); 179 180 menu->AddItem(new BMenuItem("Open Preferences"B_UTF8_ELLIPSIS, 181 new BMessage(kMsgOpenBluetoothPreferences))); 182 183 // TODO show list of known/paired devices 184 185 /* The code below is for development purposes only, but doesn't 186 * hurt to be enabled as long as in alpha state. 187 */ 188 menu->AddSeparatorItem(); 189 190 menu->AddItem(new BMenuItem("Show Server Console" B_UTF8_ELLIPSIS, 191 new BMessage(kMsgShowBluetoothServerConsole))); 192 193 menu->AddItem(new BMenuItem("Stop Server", 194 new BMessage(kMsgQuitBluetoothServer))); 195 196 menu->SetTargetForItems(this); 197 ConvertToScreen(&point); 198 menu->Go(point, true, true, true); 199 } 200 201 202 void 203 DeskbarReplicant::_OpenBluetoothPreferences() 204 { 205 status_t status = be_roster->Launch(BLUETOOTH_APP_SIGNATURE); 206 if (status < B_OK) { 207 _ShowErrorAlert("Launching the Bluetooth preflet failed.", status); 208 } 209 } 210 211 212 void 213 DeskbarReplicant::_ShowBluetoothServerConsole() 214 { 215 if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) { 216 return; 217 } 218 status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage( 219 BT_MSG_SERVER_SHOW_CONSOLE); 220 if (status < B_OK) { 221 _ShowErrorAlert("Showing the Bluetooth Server Console failed.", status); 222 } 223 } 224 225 226 void 227 DeskbarReplicant::_QuitBluetoothServer() 228 { 229 if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) { 230 return; 231 } 232 status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage( 233 B_QUIT_REQUESTED); 234 if (status < B_OK) { 235 _ShowErrorAlert("Stopping the Bluetooth Server failed.", status); 236 } 237 } 238 239 240 void 241 DeskbarReplicant::_ShowErrorAlert(BString msg, status_t status) 242 { 243 msg << "\n\nError: " << strerror(status); 244 BAlert* alert = new BAlert("Bluetooth Error", msg.String(), "Ok"); 245 alert->Go(NULL); 246 } 247 248 // #pragma mark - 249 250 251 extern "C" _EXPORT BView * 252 instantiate_deskbar_item(void) 253 { 254 return new DeskbarReplicant(BRect(0, 0, 15, 15), 255 B_FOLLOW_LEFT | B_FOLLOW_TOP); 256 } 257 258 // #pragma mark - 259 260 261 status_t 262 our_image(image_info& image) 263 { 264 int32 cookie = 0; 265 while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) { 266 if ((char *)our_image >= (char *)image.text 267 && (char *)our_image <= (char *)image.text + image.text_size) 268 return B_OK; 269 } 270 271 return B_ERROR; 272 } 273