vfs: check userland buffers before reading them.
[haiku.git] / src / apps / powerstatus / PowerStatusView.cpp
blob7dc49608e8a01519cf0909f7f97bd9a6c5922adc
1 /*
2 * Copyright 2006-2017, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Clemens Zeidler, haiku@Clemens-Zeidler.de
8 * Alexander von Gluck, kallisti5@unixzen.com
9 * Kacper Kasper, kacperkasper@gmail.com
13 #include "PowerStatusView.h"
15 #include <algorithm>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
21 #include <AboutWindow.h>
22 #include <Application.h>
23 #include <Bitmap.h>
24 #include <Catalog.h>
25 #include <ControlLook.h>
26 #include <DataIO.h>
27 #include <Deskbar.h>
28 #include <Dragger.h>
29 #include <Drivers.h>
30 #include <File.h>
31 #include <FindDirectory.h>
32 #include <MenuItem.h>
33 #include <MessageRunner.h>
34 #include <Notification.h>
35 #include <Path.h>
36 #include <PopUpMenu.h>
37 #include <Resources.h>
38 #include <Roster.h>
39 #include <TextView.h>
40 #include <TranslationUtils.h>
42 #include "ACPIDriverInterface.h"
43 #include "APMDriverInterface.h"
44 #include "ExtendedInfoWindow.h"
45 #include "PowerStatus.h"
48 #undef B_TRANSLATION_CONTEXT
49 #define B_TRANSLATION_CONTEXT "PowerStatus"
52 extern "C" _EXPORT BView *instantiate_deskbar_item(void);
53 extern const char* kDeskbarItemName;
55 const uint32 kMsgToggleLabel = 'tglb';
56 const uint32 kMsgToggleTime = 'tgtm';
57 const uint32 kMsgToggleStatusIcon = 'tgsi';
58 const uint32 kMsgToggleExtInfo = 'texi';
60 const uint32 kMinIconWidth = 16;
61 const uint32 kMinIconHeight = 16;
63 const int32 kLowBatteryPercentage = 15;
64 const int32 kNoteBatteryPercentage = 30;
67 PowerStatusView::PowerStatusView(PowerStatusDriverInterface* interface,
68 BRect frame, int32 resizingMode, int batteryID, bool inDeskbar)
70 BView(frame, kDeskbarItemName, resizingMode,
71 B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
72 fDriverInterface(interface),
73 fBatteryID(batteryID),
74 fInDeskbar(inDeskbar)
76 _Init();
80 PowerStatusView::PowerStatusView(BMessage* archive)
82 BView(archive),
83 fInDeskbar(false)
85 app_info info;
86 if (be_app->GetAppInfo(&info) == B_OK
87 && !strcasecmp(info.signature, kDeskbarSignature))
88 fInDeskbar = true;
89 _Init();
90 FromMessage(archive);
94 PowerStatusView::~PowerStatusView()
99 status_t
100 PowerStatusView::Archive(BMessage* archive, bool deep) const
102 status_t status = BView::Archive(archive, deep);
103 if (status == B_OK)
104 status = ToMessage(archive);
106 return status;
110 void
111 PowerStatusView::_Init()
113 fShowLabel = true;
114 fShowTime = false;
115 fShowStatusIcon = true;
117 fPercent = 100;
118 fOnline = true;
119 fTimeLeft = 0;
123 void
124 PowerStatusView::AttachedToWindow()
126 BView::AttachedToWindow();
127 if (Parent() != NULL) {
128 if ((Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0)
129 SetViewColor(B_TRANSPARENT_COLOR);
130 else
131 AdoptParentColors();
132 } else
133 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
135 if (ViewUIColor() != B_NO_COLOR)
136 SetLowUIColor(ViewUIColor());
137 else
138 SetLowColor(ViewColor());
140 Update();
144 void
145 PowerStatusView::DetachedFromWindow()
150 void
151 PowerStatusView::MessageReceived(BMessage *message)
153 switch (message->what) {
154 case kMsgUpdate:
155 Update();
156 break;
158 default:
159 BView::MessageReceived(message);
164 void
165 PowerStatusView::_DrawBattery(BView* view, BRect rect)
167 BRect lightningRect = rect;
168 float quarter = floorf((rect.Height() + 1) / 4);
169 rect.top += quarter;
170 rect.bottom -= quarter;
172 rect.InsetBy(2, 0);
174 float left = rect.left;
175 rect.left += rect.Width() / 11;
176 lightningRect.left = rect.left;
177 lightningRect.InsetBy(0.0f, 5.0f * rect.Height() / 16);
179 if (view->LowColor().Brightness() > 100)
180 view->SetHighColor(0, 0, 0);
181 else
182 view->SetHighColor(128, 128, 128);
184 float gap = 1;
185 if (rect.Height() > 8) {
186 gap = ceilf((rect.left - left) / 2);
188 // left
189 view->FillRect(BRect(rect.left, rect.top, rect.left + gap - 1, rect.bottom));
190 // right
191 view->FillRect(BRect(rect.right - gap + 1, rect.top, rect.right,
192 rect.bottom));
193 // top
194 view->FillRect(BRect(rect.left + gap, rect.top, rect.right - gap,
195 rect.top + gap - 1));
196 // bottom
197 view->FillRect(BRect(rect.left + gap, rect.bottom + 1 - gap,
198 rect.right - gap, rect.bottom));
199 } else
200 view->StrokeRect(rect);
202 view->FillRect(BRect(left, floorf(rect.top + rect.Height() / 4) + 1,
203 rect.left - 1, floorf(rect.bottom - rect.Height() / 4)));
205 int32 percent = fPercent;
206 if (percent > 100)
207 percent = 100;
208 else if (percent < 0 || !fHasBattery)
209 percent = 0;
211 if (percent > 0) {
212 rect.InsetBy(gap, gap);
213 rgb_color base = (rgb_color){84, 84, 84, 255};
214 if (view->LowColor().Brightness() < 128)
215 base = (rgb_color){172, 172, 172, 255};
217 if (be_control_look != NULL) {
218 BRect empty = rect;
219 if (fHasBattery && percent > 0)
220 empty.left += empty.Width() * percent / 100.0;
222 be_control_look->DrawButtonBackground(view, empty, empty, base,
223 fHasBattery
224 ? BControlLook::B_ACTIVATED : BControlLook::B_DISABLED,
225 fHasBattery && percent > 0
226 ? (BControlLook::B_ALL_BORDERS
227 & ~BControlLook::B_LEFT_BORDER)
228 : BControlLook::B_ALL_BORDERS);
231 if (fHasBattery) {
232 if (percent <= kLowBatteryPercentage)
233 base.set_to(180, 0, 0);
234 else if (percent <= kNoteBatteryPercentage)
235 base.set_to(200, 140, 0);
236 else
237 base.set_to(20, 180, 0);
239 rect.right = rect.left + rect.Width() * percent / 100.0;
241 if (be_control_look != NULL) {
242 be_control_look->DrawButtonBackground(view, rect, rect, base,
243 fHasBattery ? 0 : BControlLook::B_DISABLED);
244 } else
245 view->FillRect(rect);
249 if (fOnline) {
250 // When charging, draw a lightning symbol over the battery.
251 view->SetHighColor(255, 255, 0, 180);
252 view->SetDrawingMode(B_OP_ALPHA);
254 static const BPoint points[] = {
255 BPoint(3, 14),
256 BPoint(10, 6),
257 BPoint(10, 8),
258 BPoint(17, 3),
259 BPoint(9, 12),
260 BPoint(9, 10)
262 view->FillPolygon(points, 6, lightningRect);
264 view->SetDrawingMode(B_OP_OVER);
267 view->SetHighColor(0, 0, 0);
271 void
272 PowerStatusView::Draw(BRect updateRect)
274 DrawTo(this, Bounds());
277 void
278 PowerStatusView::DrawTo(BView* view, BRect rect)
280 bool inside = rect.Width() >= 40.0f && rect.Height() >= 40.0f;
282 font_height fontHeight;
283 view->GetFontHeight(&fontHeight);
284 float baseLine = ceilf(fontHeight.ascent);
286 char text[64];
287 _SetLabel(text, sizeof(text));
289 float textHeight = ceilf(fontHeight.descent + fontHeight.ascent);
290 float textWidth = view->StringWidth(text);
291 bool showLabel = fShowLabel && text[0];
293 BRect iconRect;
295 if (fShowStatusIcon) {
296 iconRect = rect;
297 if (showLabel) {
298 if (inside == false)
299 iconRect.right -= textWidth + 2;
302 if (iconRect.Width() + 1 >= kMinIconWidth
303 && iconRect.Height() + 1 >= kMinIconHeight) {
304 _DrawBattery(view, iconRect);
305 } else {
306 // there is not enough space for the icon
307 iconRect.Set(0, 0, -1, -1);
311 if (showLabel) {
312 BPoint point(0, baseLine + rect.top);
314 if (iconRect.IsValid()) {
315 if (inside == true) {
316 point.x = rect.left + (iconRect.Width() - textWidth) / 2 +
317 iconRect.Width() / 20;
318 point.y += (iconRect.Height() - textHeight) / 2;
319 } else {
320 point.x = rect.left + iconRect.Width() + 2;
321 point.y += (iconRect.Height() - textHeight) / 2;
323 } else {
324 point.x = rect.left + (Bounds().Width() - textWidth) / 2;
325 point.y += (Bounds().Height() - textHeight) / 2;
328 view->SetDrawingMode(B_OP_OVER);
329 if (fInDeskbar == false || inside == true) {
330 view->SetHighUIColor(B_CONTROL_BACKGROUND_COLOR);
331 view->DrawString(text, BPoint(point.x + 1, point.y + 1));
333 view->SetHighUIColor(B_CONTROL_TEXT_COLOR);
335 view->DrawString(text, point);
340 void
341 PowerStatusView::_SetLabel(char* buffer, size_t bufferLength)
343 if (bufferLength < 1)
344 return;
346 buffer[0] = '\0';
348 if (!fShowLabel)
349 return;
351 const char* open = "";
352 const char* close = "";
353 if (fOnline) {
354 open = "(";
355 close = ")";
358 if (!fShowTime && fPercent >= 0) {
359 snprintf(buffer, bufferLength, "%s%" B_PRId32 "%%%s", open, fPercent,
360 close);
361 } else if (fShowTime && fTimeLeft >= 0) {
362 snprintf(buffer, bufferLength, "%s%" B_PRIdTIME ":%02" B_PRIdTIME "%s",
363 open, fTimeLeft / 3600, (fTimeLeft / 60) % 60, close);
369 void
370 PowerStatusView::Update(bool force)
372 int32 previousPercent = fPercent;
373 time_t previousTimeLeft = fTimeLeft;
374 bool wasOnline = fOnline;
375 bool hadBattery = fHasBattery;
376 _GetBatteryInfo(fBatteryID, &fBatteryInfo);
377 fHasBattery = fBatteryInfo.full_capacity > 0;
379 if (fBatteryInfo.full_capacity > 0 && fHasBattery) {
380 fPercent = (100 * fBatteryInfo.capacity) / fBatteryInfo.full_capacity;
381 fOnline = (fBatteryInfo.state & BATTERY_DISCHARGING) == 0;
382 fTimeLeft = fBatteryInfo.time_left;
383 } else {
384 fPercent = 0;
385 fOnline = false;
386 fTimeLeft = -1;
389 if (fHasBattery && (fPercent <= 0 || fPercent > 100)) {
390 // Just ignore this probe -- it obviously returned invalid values
391 fPercent = previousPercent;
392 fTimeLeft = previousTimeLeft;
393 fOnline = wasOnline;
394 fHasBattery = hadBattery;
395 return;
398 if (fInDeskbar) {
399 // make sure the tray icon is (just) large enough
400 float width = fShowStatusIcon ? kMinIconWidth - 1 : 0;
402 if (fShowLabel) {
403 char text[64];
404 _SetLabel(text, sizeof(text));
406 if (text[0])
407 width += ceilf(StringWidth(text)) + 2;
408 } else {
409 char text[256];
410 const char* open = "";
411 const char* close = "";
412 if (fOnline) {
413 open = "(";
414 close = ")";
416 if (fHasBattery) {
417 size_t length = snprintf(text, sizeof(text), "%s%" B_PRId32
418 "%%%s", open, fPercent, close);
419 if (fTimeLeft >= 0) {
420 length += snprintf(text + length, sizeof(text) - length,
421 "\n%" B_PRIdTIME ":%02" B_PRIdTIME, fTimeLeft / 3600,
422 (fTimeLeft / 60) % 60);
425 const char* state = NULL;
426 if ((fBatteryInfo.state & BATTERY_CHARGING) != 0)
427 state = B_TRANSLATE("charging");
428 else if ((fBatteryInfo.state & BATTERY_DISCHARGING) != 0)
429 state = B_TRANSLATE("discharging");
431 if (state != NULL) {
432 snprintf(text + length, sizeof(text) - length, "\n%s",
433 state);
435 } else
436 strcpy(text, B_TRANSLATE("no battery"));
437 SetToolTip(text);
439 if (width < 8) {
440 // make sure we're not going away completely
441 width = 8;
444 if (width != Bounds().Width()) {
445 ResizeTo(width, Bounds().Height());
447 // inform Deskbar that it needs to realign its replicants
448 BWindow* window = Window();
449 if (window != NULL) {
450 BView* view = window->FindView("Status");
451 if (view != NULL) {
452 BMessenger target((BHandler*)view);
453 BMessage realignReplicants('Algn');
454 target.SendMessage(&realignReplicants);
460 if (force || wasOnline != fOnline
461 || (fShowTime && fTimeLeft != previousTimeLeft)
462 || (!fShowTime && fPercent != previousPercent)) {
463 Invalidate();
466 if (!fOnline && fHasBattery && previousPercent > kLowBatteryPercentage
467 && fPercent <= kLowBatteryPercentage) {
468 _NotifyLowBattery();
473 void
474 PowerStatusView::FromMessage(const BMessage* archive)
476 bool value;
477 if (archive->FindBool("show label", &value) == B_OK)
478 fShowLabel = value;
479 if (archive->FindBool("show icon", &value) == B_OK)
480 fShowStatusIcon = value;
481 if (archive->FindBool("show time", &value) == B_OK)
482 fShowTime = value;
484 //Incase we have a bad saving and none are showed..
485 if (!fShowLabel && !fShowStatusIcon)
486 fShowLabel = true;
488 int32 intValue;
489 if (archive->FindInt32("battery id", &intValue) == B_OK)
490 fBatteryID = intValue;
494 status_t
495 PowerStatusView::ToMessage(BMessage* archive) const
497 status_t status = archive->AddBool("show label", fShowLabel);
498 if (status == B_OK)
499 status = archive->AddBool("show icon", fShowStatusIcon);
500 if (status == B_OK)
501 status = archive->AddBool("show time", fShowTime);
502 if (status == B_OK)
503 status = archive->AddInt32("battery id", fBatteryID);
505 return status;
509 void
510 PowerStatusView::_GetBatteryInfo(int batteryID, battery_info* batteryInfo)
512 if (batteryID >= 0) {
513 fDriverInterface->GetBatteryInfo(batteryID, batteryInfo);
514 } else {
515 bool first = true;
516 memset(batteryInfo, 0, sizeof(battery_info));
518 for (int i = 0; i < fDriverInterface->GetBatteryCount(); i++) {
519 battery_info info;
520 fDriverInterface->GetBatteryInfo(i, &info);
522 if (info.full_capacity <= 0)
523 continue;
525 if (first) {
526 *batteryInfo = info;
527 first = false;
528 } else {
529 batteryInfo->state |= info.state;
530 batteryInfo->capacity += info.capacity;
531 batteryInfo->full_capacity += info.full_capacity;
532 batteryInfo->time_left += info.time_left;
539 void
540 PowerStatusView::_NotifyLowBattery()
542 BBitmap* bitmap = NULL;
543 BResources resources;
544 resources.SetToImage((void*)&instantiate_deskbar_item);
546 if (resources.InitCheck() == B_OK) {
547 size_t resourceSize = 0;
548 const void* resourceData = resources.LoadResource(
549 B_VECTOR_ICON_TYPE, fHasBattery
550 ? "battery_low" : "battery_critical", &resourceSize);
551 if (resourceData != NULL) {
552 BMemoryIO memoryIO(resourceData, resourceSize);
553 bitmap = BTranslationUtils::GetBitmap(&memoryIO);
557 BNotification notification(
558 fHasBattery ? B_INFORMATION_NOTIFICATION : B_ERROR_NOTIFICATION);
560 if (fHasBattery) {
561 notification.SetTitle(B_TRANSLATE("Battery low"));
562 notification.SetContent(B_TRANSLATE(
563 "The battery level is getting low, please plug in the device."));
564 } else {
565 notification.SetTitle(B_TRANSLATE("Battery critical"));
566 notification.SetContent(B_TRANSLATE(
567 "The battery level is critical, please plug in the device "
568 "immediately."));
571 notification.SetIcon(bitmap);
572 notification.Send();
573 delete bitmap;
577 // #pragma mark - Replicant view
580 PowerStatusReplicant::PowerStatusReplicant(BRect frame, int32 resizingMode,
581 bool inDeskbar)
583 PowerStatusView(NULL, frame, resizingMode, -1, inDeskbar),
584 fReplicated(false)
586 _Init();
587 _LoadSettings();
589 if (!inDeskbar) {
590 // we were obviously added to a standard window - let's add a dragger
591 frame.OffsetTo(B_ORIGIN);
592 frame.top = frame.bottom - 7;
593 frame.left = frame.right - 7;
594 BDragger* dragger = new BDragger(frame, this,
595 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
596 AddChild(dragger);
597 } else
598 Update();
602 PowerStatusReplicant::PowerStatusReplicant(BMessage* archive)
604 PowerStatusView(archive),
605 fReplicated(true)
607 _Init();
608 _LoadSettings();
612 PowerStatusReplicant::~PowerStatusReplicant()
614 if (fMessengerExist)
615 delete fExtWindowMessenger;
617 if (fExtendedWindow != NULL && fExtendedWindow->Lock()) {
618 fExtendedWindow->Quit();
619 fExtendedWindow = NULL;
622 fDriverInterface->StopWatching(this);
623 fDriverInterface->Disconnect();
624 fDriverInterface->ReleaseReference();
626 _SaveSettings();
630 PowerStatusReplicant*
631 PowerStatusReplicant::Instantiate(BMessage* archive)
633 if (!validate_instantiation(archive, "PowerStatusReplicant"))
634 return NULL;
636 return new PowerStatusReplicant(archive);
640 status_t
641 PowerStatusReplicant::Archive(BMessage* archive, bool deep) const
643 status_t status = PowerStatusView::Archive(archive, deep);
644 if (status == B_OK)
645 status = archive->AddString("add_on", kSignature);
646 if (status == B_OK)
647 status = archive->AddString("class", "PowerStatusReplicant");
649 return status;
653 void
654 PowerStatusReplicant::MessageReceived(BMessage *message)
656 switch (message->what) {
657 case kMsgToggleLabel:
658 if (fShowStatusIcon)
659 fShowLabel = !fShowLabel;
660 else
661 fShowLabel = true;
663 Update(true);
664 break;
666 case kMsgToggleTime:
667 fShowTime = !fShowTime;
668 Update(true);
669 break;
671 case kMsgToggleStatusIcon:
672 if (fShowLabel)
673 fShowStatusIcon = !fShowStatusIcon;
674 else
675 fShowStatusIcon = true;
677 Update(true);
678 break;
680 case kMsgToggleExtInfo:
681 _OpenExtendedWindow();
682 break;
684 case B_ABOUT_REQUESTED:
685 _AboutRequested();
686 break;
688 case B_QUIT_REQUESTED:
689 _Quit();
690 break;
692 default:
693 PowerStatusView::MessageReceived(message);
698 void
699 PowerStatusReplicant::MouseDown(BPoint point)
701 BMessage* msg = Window()->CurrentMessage();
702 int32 buttons = msg->GetInt32("buttons", 0);
703 if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
704 BMessenger messenger(this);
705 messenger.SendMessage(kMsgToggleExtInfo);
706 } else {
707 BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
708 menu->SetFont(be_plain_font);
710 BMenuItem* item;
711 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Show text label"),
712 new BMessage(kMsgToggleLabel)));
713 if (fShowLabel)
714 item->SetMarked(true);
715 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Show status icon"),
716 new BMessage(kMsgToggleStatusIcon)));
717 if (fShowStatusIcon)
718 item->SetMarked(true);
719 menu->AddItem(new BMenuItem(!fShowTime ? B_TRANSLATE("Show time") :
720 B_TRANSLATE("Show percent"), new BMessage(kMsgToggleTime)));
722 menu->AddSeparatorItem();
723 menu->AddItem(new BMenuItem(B_TRANSLATE("Battery info" B_UTF8_ELLIPSIS),
724 new BMessage(kMsgToggleExtInfo)));
726 menu->AddSeparatorItem();
727 menu->AddItem(new BMenuItem(B_TRANSLATE("About" B_UTF8_ELLIPSIS),
728 new BMessage(B_ABOUT_REQUESTED)));
729 menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"),
730 new BMessage(B_QUIT_REQUESTED)));
731 menu->SetTargetForItems(this);
733 ConvertToScreen(&point);
734 menu->Go(point, true, false, true);
739 void
740 PowerStatusReplicant::_AboutRequested()
742 BAboutWindow* window = new BAboutWindow(
743 B_TRANSLATE_SYSTEM_NAME("PowerStatus"), kSignature);
745 const char* authors[] = {
746 "Axel Dörfler",
747 "Alexander von Gluck",
748 "Clemens Zeidler",
749 NULL
752 window->AddCopyright(2006, "Haiku, Inc.");
753 window->AddAuthors(authors);
755 window->Show();
759 void
760 PowerStatusReplicant::_Init()
762 fDriverInterface = new ACPIDriverInterface;
763 if (fDriverInterface->Connect() != B_OK) {
764 delete fDriverInterface;
765 fDriverInterface = new APMDriverInterface;
766 if (fDriverInterface->Connect() != B_OK) {
767 fprintf(stderr, "No power interface found.\n");
768 _Quit();
772 fExtendedWindow = NULL;
773 fMessengerExist = false;
774 fExtWindowMessenger = NULL;
776 fDriverInterface->StartWatching(this);
780 void
781 PowerStatusReplicant::_Quit()
783 if (fInDeskbar) {
784 BDeskbar deskbar;
785 deskbar.RemoveItem(kDeskbarItemName);
786 } else if (fReplicated) {
787 BDragger *dragger = dynamic_cast<BDragger*>(ChildAt(0));
788 if (dragger != NULL) {
789 BMessenger messenger(dragger);
790 messenger.SendMessage(new BMessage(B_TRASH_TARGET));
792 } else
793 be_app->PostMessage(B_QUIT_REQUESTED);
797 status_t
798 PowerStatusReplicant::_GetSettings(BFile& file, int mode)
800 BPath path;
801 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path,
802 (mode & O_ACCMODE) != O_RDONLY);
803 if (status != B_OK)
804 return status;
806 path.Append("PowerStatus settings");
808 return file.SetTo(path.Path(), mode);
812 void
813 PowerStatusReplicant::_LoadSettings()
815 fShowLabel = false;
817 BFile file;
818 if (_GetSettings(file, B_READ_ONLY) != B_OK)
819 return;
821 BMessage settings;
822 if (settings.Unflatten(&file) < B_OK)
823 return;
825 FromMessage(&settings);
829 void
830 PowerStatusReplicant::_SaveSettings()
832 BFile file;
833 if (_GetSettings(file, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) != B_OK)
834 return;
836 BMessage settings('pwst');
837 ToMessage(&settings);
839 ssize_t size = 0;
840 settings.Flatten(&file, &size);
844 void
845 PowerStatusReplicant::_OpenExtendedWindow()
847 if (!fExtendedWindow) {
848 fExtendedWindow = new ExtendedInfoWindow(fDriverInterface);
849 fExtWindowMessenger = new BMessenger(NULL, fExtendedWindow);
850 fExtendedWindow->Show();
851 return;
854 BMessage msg(B_SET_PROPERTY);
855 msg.AddSpecifier("Hidden", int32(0));
856 if (fExtWindowMessenger->SendMessage(&msg) == B_BAD_PORT_ID) {
857 fExtendedWindow = new ExtendedInfoWindow(fDriverInterface);
858 if (fMessengerExist)
859 delete fExtWindowMessenger;
860 fExtWindowMessenger = new BMessenger(NULL, fExtendedWindow);
861 fMessengerExist = true;
862 fExtendedWindow->Show();
863 } else
864 fExtendedWindow->Activate();
869 // #pragma mark -
872 extern "C" _EXPORT BView*
873 instantiate_deskbar_item(void)
875 return new PowerStatusReplicant(BRect(0, 0, 15, 15), B_FOLLOW_NONE, true);