diff --git a/src/apps/powerstatus/ACPIDriverInterface.cpp b/src/apps/powerstatus/ACPIDriverInterface.cpp index 527ac732f0..b5300acba2 100644 --- a/src/apps/powerstatus/ACPIDriverInterface.cpp +++ b/src/apps/powerstatus/ACPIDriverInterface.cpp @@ -76,26 +76,33 @@ Battery::InitCheck() status_t -Battery::GetBatteryInfo(battery_info* info) +Battery::ReadBatteryInfo() { - acpi_battery_info acpiInfo; status_t status; - status = ioctl(fDriverHandler, GET_BATTERY_INFO, &acpiInfo, + status = ioctl(fDriverHandler, GET_BATTERY_INFO, &fCachedAcpiInfo, sizeof(acpi_battery_info)); if (status != B_OK) return status; - info->state = acpiInfo.state; - info->current_rate = acpiInfo.current_rate; - info->capacity = acpiInfo.capacity; + return B_OK; +} + + +status_t +Battery::GetBatteryInfoCached(battery_info* info) +{ + info->state = fCachedAcpiInfo.state; + info->current_rate = fCachedAcpiInfo.current_rate; + info->capacity = fCachedAcpiInfo.capacity; info->full_capacity = fExtendedBatteryInfo.last_full_charge; - fRateBuffer.AddRate(acpiInfo.current_rate); - if (acpiInfo.current_rate > 0) - info->time_left = 3600 * acpiInfo.capacity / fRateBuffer.GetMeanRate(); + fRateBuffer.AddRate(fCachedAcpiInfo.current_rate); + if (fCachedAcpiInfo.current_rate > 0) + info->time_left = 3600 * fCachedAcpiInfo.capacity + / fRateBuffer.GetMeanRate(); else info->time_left = -1; - + return B_OK; } @@ -125,8 +132,7 @@ Battery::_Init() if (fInitStatus != B_OK) return; - acpi_battery_info info; - fInitStatus = ioctl(fDriverHandler, GET_BATTERY_INFO, &info, + fInitStatus = ioctl(fDriverHandler, GET_BATTERY_INFO, &fCachedAcpiInfo, sizeof(acpi_battery_info)); if (fInitStatus != B_OK) return; @@ -158,12 +164,12 @@ ACPIDriverInterface::Connect() status_t ACPIDriverInterface::GetBatteryInfo(battery_info* info, int32 index) { - BAutolock autolock(fBatteryStatusLock); + BAutolock autolock(fInterfaceLocker); if (index < 0 || index >= fDriverList.CountItems()) return B_ERROR; status_t status; - status = fDriverList.ItemAt(index)->GetBatteryInfo(info); + status = fDriverList.ItemAt(index)->GetBatteryInfoCached(info); return status; } @@ -172,7 +178,7 @@ status_t ACPIDriverInterface::GetExtendedBatteryInfo(acpi_extended_battery_info* info, int32 index) { - BAutolock autolock(fBatteryStatusLock); + BAutolock autolock(fInterfaceLocker); if (index < 0 || index >= fDriverList.CountItems()) return B_ERROR; @@ -190,6 +196,16 @@ ACPIDriverInterface::GetBatteryCount() } +status_t +ACPIDriverInterface::_ReadBatteryInfo() +{ + for (int i = 0; i < fDriverList.CountItems(); i++) + fDriverList.ItemAt(i)->ReadBatteryInfo(); + + return B_OK; +} + + void ACPIDriverInterface::_WatchPowerStatus() { @@ -197,6 +213,7 @@ ACPIDriverInterface::_WatchPowerStatus() // every two seconds while (atomic_get(&fIsWatching) > 0) { + _ReadBatteryInfo(); Broadcast(kMsgUpdate); snooze(kUpdateInterval); } diff --git a/src/apps/powerstatus/ACPIDriverInterface.h b/src/apps/powerstatus/ACPIDriverInterface.h index b8a5c52e69..04f71190d5 100644 --- a/src/apps/powerstatus/ACPIDriverInterface.h +++ b/src/apps/powerstatus/ACPIDriverInterface.h @@ -14,6 +14,7 @@ #include #include + const int8 kRateBufferSize = 10; class RateBuffer @@ -39,7 +40,9 @@ public: status_t InitCheck(); - status_t GetBatteryInfo(battery_info* info); + // Read battery info and update the cache. + status_t ReadBatteryInfo(); + status_t GetBatteryInfoCached(battery_info* info); status_t GetExtendedBatteryInfo( acpi_extended_battery_info* info); @@ -53,6 +56,7 @@ private: acpi_extended_battery_info fExtendedBatteryInfo; RateBuffer fRateBuffer; + acpi_battery_info fCachedAcpiInfo; }; @@ -69,12 +73,15 @@ public: virtual int32 GetBatteryCount(); protected: + // Read the battery info from the hardware. + virtual status_t _ReadBatteryInfo(); + virtual void _WatchPowerStatus(); virtual status_t _FindDrivers(const char* path); BObjectList fDriverList; - BLocker fBatteryStatusLock; + BLocker fInterfaceLocker; }; #endif diff --git a/src/apps/powerstatus/ExtendedInfoWindow.cpp b/src/apps/powerstatus/ExtendedInfoWindow.cpp index 1990bcdb15..1319d91596 100644 --- a/src/apps/powerstatus/ExtendedInfoWindow.cpp +++ b/src/apps/powerstatus/ExtendedInfoWindow.cpp @@ -15,20 +15,38 @@ #include -BatteryInfoView::BatteryInfoView(BRect frame, int32 resizingMode) +FontString::FontString() +{ + font = be_plain_font; +} + + +const int kLineSpacing = 5; + +BatteryInfoView::BatteryInfoView() : - BView(frame, "battery info view", resizingMode, B_WILL_DRAW | - B_FULL_UPDATE_ON_RESIZE) + BView("battery info view", B_WILL_DRAW | + B_FULL_UPDATE_ON_RESIZE), + fPreferredSize(200, 200), + fMaxStringSize(0, 0) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); } +BatteryInfoView::~BatteryInfoView() +{ + _ClearStringList(); +} + + void BatteryInfoView::Update(battery_info& info, acpi_extended_battery_info& extInfo) { fBatteryInfo = info; fBatteryExtendedInfo = extInfo; + + _FillStringList(); } @@ -37,6 +55,50 @@ BatteryInfoView::Draw(BRect updateRect) { SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + BPoint point(10, 10); + + float space = _MeasureString("").height + kLineSpacing; + + for (int i = 0; i < fStringList.CountItems(); i ++) + { + FontString* fontString = fStringList.ItemAt(i); + SetFont(fontString->font); + DrawString(fontString->string.String(), point); + point.y += space; + } +} + + +void +BatteryInfoView::GetPreferredSize(float *width, float *height) +{ + *width = fPreferredSize.width; + *height = fPreferredSize.height; +} + + +BSize +BatteryInfoView::_MeasureString(const BString& string) +{ + BFont font; + GetFont(&font); + BSize size; + + size.width = font.StringWidth(string); + + font_height height; + font.GetHeight(&height); + size.height = height.ascent + height.descent; + + return size; +} + + +void +BatteryInfoView::_FillStringList() +{ + _ClearStringList(); + BString powerUnit; BString rateUnit; switch (fBatteryExtendedInfo.power_unit) { @@ -51,102 +113,127 @@ BatteryInfoView::Draw(BRect updateRect) break; } - BString text; + FontString* fontString; + + fontString = new FontString; + fStringList.AddItem(fontString); + fontString->font = be_bold_font; + if (fBatteryInfo.state & BATTERY_CHARGING) - text = "Battery charging"; + fontString->string = "Battery charging"; else if (fBatteryInfo.state & BATTERY_DISCHARGING) - text = "Battery discharging"; + fontString->string = "Battery discharging"; else if (fBatteryInfo.state & BATTERY_CRITICAL_STATE) - text = "Empty Battery Slot"; + fontString->string = "Empty Battery Slot"; else - text = "Battery unused"; - BPoint point(10, 10); - int textHeight = 15; - int space = textHeight + 5; - DrawString(text.String(), point); - point.y += space; - - text = "Capacity: "; - text << fBatteryInfo.capacity; - text << powerUnit; - DrawString(text.String(), point); - point.y += space; - - text = "Last full Charge: "; - text << fBatteryInfo.full_capacity; - text << powerUnit; - DrawString(text.String(), point); - point.y += space; - - text = "Current Rate: "; - text << fBatteryInfo.current_rate; - text << rateUnit; - DrawString(text.String(), point); - point.y += space; - - point.y += space; - - text = "Design Capacity: "; - text << fBatteryExtendedInfo.design_capacity; - text << powerUnit; - DrawString(text.String(), point); - point.y += space; - - text = "Technology: "; - text << fBatteryExtendedInfo.technology; - DrawString(text.String(), point); - point.y += space; - - text = "Design Voltage: "; - text << fBatteryExtendedInfo.design_voltage; - text << " mV"; - DrawString(text.String(), point); - point.y += space; - - text = "Design Capacity Warning: "; - text << fBatteryExtendedInfo.design_capacity_warning; - text << powerUnit; - DrawString(text.String(), point); - point.y += space; - - text = "Design Capacity low Warning: "; - text << fBatteryExtendedInfo.design_capacity_low; - text << powerUnit; - DrawString(text.String(), point); - point.y += space; - - text = "Capacity Granularity 1: "; - text << fBatteryExtendedInfo.capacity_granularity_1; - DrawString(text.String(), point); - point.y += space; - - text = "Capacity Granularity 2: "; - text << fBatteryExtendedInfo.capacity_granularity_2; - DrawString(text.String(), point); - point.y += space; - - text = "Model Number: "; - text << fBatteryExtendedInfo.model_number; - DrawString(text.String(), point); - point.y += space; - - text = "Serial number: "; - text << fBatteryExtendedInfo.serial_number; - DrawString(text.String(), point); - point.y += space; - - text = "Type: "; - text += fBatteryExtendedInfo.type; - DrawString(text.String(), point); - point.y += space; - - text = "OEM Info: "; - text += fBatteryExtendedInfo.oem_info; - DrawString(text.String(), point); - point.y += space; - -} + fontString->string = "Battery unused"; + fontString = new FontString; + fontString->string = "Capacity: "; + fontString->string << fBatteryInfo.capacity; + fontString->string << powerUnit; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Last full Charge: "; + fontString->string << fBatteryInfo.full_capacity; + fontString->string << powerUnit; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Current Rate: "; + fontString->string << fBatteryInfo.current_rate; + fontString->string << rateUnit; + _AddToStringList(fontString); + + // empty line + fontString = new FontString; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Design Capacity: "; + fontString->string << fBatteryExtendedInfo.design_capacity; + fontString->string << powerUnit; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Technology: "; + fontString->string << fBatteryExtendedInfo.technology; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Design Voltage: "; + fontString->string << fBatteryExtendedInfo.design_voltage; + fontString->string << " mV"; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Design Capacity Warning: "; + fontString->string << fBatteryExtendedInfo.design_capacity_warning; + fontString->string << powerUnit; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Design Capacity low Warning: "; + fontString->string << fBatteryExtendedInfo.design_capacity_low; + fontString->string << powerUnit; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Capacity Granularity 1: "; + fontString->string << fBatteryExtendedInfo.capacity_granularity_1; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Capacity Granularity 2: "; + fontString->string << fBatteryExtendedInfo.capacity_granularity_2; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Model Number: "; + fontString->string << fBatteryExtendedInfo.model_number; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Serial number: "; + fontString->string << fBatteryExtendedInfo.serial_number; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "Type: "; + fontString->string += fBatteryExtendedInfo.type; + _AddToStringList(fontString); + + fontString = new FontString; + fontString->string = "OEM Info: "; + fontString->string += fBatteryExtendedInfo.oem_info; + _AddToStringList(fontString); + + fPreferredSize.width = fMaxStringSize.width + 10; + fPreferredSize.height = (fMaxStringSize.height + kLineSpacing) * + fStringList.CountItems(); +} + + +void +BatteryInfoView::_AddToStringList(FontString* fontString) +{ + fStringList.AddItem(fontString); + BSize stringSize = _MeasureString(fontString->string); + if (fMaxStringSize.width < stringSize.width) + fMaxStringSize = stringSize; +} + + +void +BatteryInfoView::_ClearStringList() +{ + for (int i = 0; i < fStringList.CountItems(); i ++) + delete fStringList.ItemAt(i); + fStringList.MakeEmpty(); + fMaxStringSize = BSize(0, 0); +} + ExtPowerStatusView::ExtPowerStatusView(PowerStatusDriverInterface* interface, BRect frame, int32 resizingMode, int batteryId, @@ -157,7 +244,7 @@ ExtPowerStatusView::ExtPowerStatusView(PowerStatusDriverInterface* interface, fBatteryInfoView(window->GetExtendedBatteryInfoView()), fSelected(false) { - + } @@ -225,7 +312,8 @@ ExtPowerStatusView::_Update(bool force) ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface) : BWindow(BRect(100, 150, 500, 500), "Extended Battery Info", B_TITLED_WINDOW, - B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), + B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AVOID_FRONT | + B_ASYNCHRONOUS_CONTROLS), fDriverInterface(interface), fSelectedView(NULL) { @@ -252,13 +340,17 @@ ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface) batteryView->GroupLayout()->SetSpacing(10); infoLayout->AddView(batteryView); - fBatteryInfoView = new BatteryInfoView(BRect(0, 0, 270, 310), B_FOLLOW_ALL); + // create before the battery views + fBatteryInfoView = new BatteryInfoView(); BGroupLayout* batteryLayout = batteryView->GroupLayout(); BRect batteryRect(0, 0, 50, 30); for (int i = 0; i < interface->GetBatteryCount(); i++) { ExtPowerStatusView* view = new ExtPowerStatusView(interface, - batteryRect, B_FOLLOW_ALL, i, this); + batteryRect, B_FOLLOW_NONE, i, this); + view->SetExplicitMaxSize(BSize(70, 80)); + view->SetExplicitMinSize(BSize(70, 80)); + batteryLayout->AddView(view); fBatteryViewList.AddItem(view); fDriverInterface->StartWatching(view); @@ -268,7 +360,7 @@ ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface) batteryLayout->AddItem(BSpaceLayoutItem::CreateGlue()); - infoLayout->AddView(fBatteryInfoView, 20); + infoLayout->AddView(fBatteryInfoView); if (!fSelectedView && fBatteryViewList.CountItems() > 0) fSelectedView = fBatteryViewList.ItemAt(0); diff --git a/src/apps/powerstatus/ExtendedInfoWindow.h b/src/apps/powerstatus/ExtendedInfoWindow.h index 671262cc82..5532364ec2 100644 --- a/src/apps/powerstatus/ExtendedInfoWindow.h +++ b/src/apps/powerstatus/ExtendedInfoWindow.h @@ -10,7 +10,7 @@ #define EXTENDED_INFO_WINDOW_H #include -#include +#include #include #include @@ -18,18 +18,40 @@ #include "PowerStatusView.h" +class FontString +{ +public: + FontString(); + + const BFont* font; + BString string; +}; + + class BatteryInfoView : public BView { public: - BatteryInfoView(BRect frame, int32 resizingMode); + BatteryInfoView(); + ~BatteryInfoView(); virtual void Update(battery_info& info, acpi_extended_battery_info& extInfo); virtual void Draw(BRect updateRect); - + virtual void GetPreferredSize(float *width, float *height); + private: - battery_info fBatteryInfo; - acpi_extended_battery_info fBatteryExtendedInfo; + BSize _MeasureString(const BString& string); + void _FillStringList(); + void _AddToStringList(FontString* fontString); + void _ClearStringList(); + + battery_info fBatteryInfo; + acpi_extended_battery_info fBatteryExtendedInfo; + + BSize fPreferredSize; + + BObjectList fStringList; + BSize fMaxStringSize; }; @@ -44,7 +66,7 @@ class ExtPowerStatusView : public PowerStatusView virtual void Draw(BRect updateRect); virtual void MouseDown(BPoint where); - + virtual void Select(bool select = true); // return true if it battery is in a none critical state diff --git a/src/apps/powerstatus/PowerStatusView.cpp b/src/apps/powerstatus/PowerStatusView.cpp index 17658069a4..56dad98ebb 100644 --- a/src/apps/powerstatus/PowerStatusView.cpp +++ b/src/apps/powerstatus/PowerStatusView.cpp @@ -295,7 +295,7 @@ PowerStatusView::_SetLabel(char* buffer, size_t bufferLength) if (!fShowTime && fPercent >= 0) snprintf(buffer, bufferLength, "%s%ld%%%s", open, fPercent, close); else if (fShowTime && fTimeLeft >= 0) { - snprintf(buffer, bufferLength, "%s%ld:%ld%s", + snprintf(buffer, bufferLength, "%s%ld:%02ld%s", open, fTimeLeft / 3600, (fTimeLeft / 60) % 60, close); } }