Battery monitor shows percentage on icon
This commit is contained in:
parent
3ba59aa2ab
commit
dda82b48a3
@ -1,17 +1,20 @@
|
||||
/* C99 */
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/MainW.h>
|
||||
#include <Xm/Scale.h>
|
||||
#include <Xm/LabelG.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/MessageB.h>
|
||||
#include <Xm/RowColumn.h>
|
||||
#include <Xm/Separator.h>
|
||||
|
||||
#include <Xmd/Icon.h>
|
||||
#include <Xmd/Exec.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "icons/level0.xbm"
|
||||
#include "icons/level1.xbm"
|
||||
@ -39,34 +42,39 @@ typedef struct {
|
||||
} BatteryInfo;
|
||||
|
||||
BatteryInfo getBatteryInfo (void);
|
||||
Pixmap selectBatteryIcon (BatteryInfo);
|
||||
void loadAllPixmaps (Widget);
|
||||
Pixmap selectBatteryIcon (BatteryInfo, Pixmap[8]);
|
||||
void loadAllPixmaps (Widget, Pixmap[8]);
|
||||
void batteryPoll (XtPointer, XtIntervalId *);
|
||||
void resetBatteryPollTimeout(void);
|
||||
void batteryInfoDialog (Widget, XtPointer, XtPointer);
|
||||
|
||||
Pixmap levels[8] = { 0 };
|
||||
Pixmap levels[8] = { 0 };
|
||||
Pixmap iconLevels[8] = { 0 };
|
||||
XtAppContext application;
|
||||
Widget icon;
|
||||
Widget text;
|
||||
Widget layout;
|
||||
Widget window;
|
||||
Widget topLevel;
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
window = XtVaAppInitialize (
|
||||
topLevel = XtVaAppInitialize (
|
||||
&application, "Battery",
|
||||
NULL, 0,
|
||||
&argc, argv,
|
||||
NULL,
|
||||
XmNtitle, "Battery",
|
||||
XmNiconName, "Battery",
|
||||
NULL);
|
||||
Widget window = XtVaCreateManagedWidget (
|
||||
"window", xmMainWindowWidgetClass, topLevel,
|
||||
NULL);
|
||||
|
||||
layout = XtVaCreateWidget (
|
||||
"layout", xmRowColumnWidgetClass, window,
|
||||
XmNorientation, XmHORIZONTAL,
|
||||
NULL);
|
||||
|
||||
loadAllPixmaps(layout);
|
||||
loadAllPixmaps(topLevel, iconLevels);
|
||||
loadAllPixmaps(layout, levels);
|
||||
icon = XtVaCreateManagedWidget (
|
||||
"batteryIcon", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
@ -87,7 +95,7 @@ int main (int argc, char *argv[]) {
|
||||
batteryPoll(NULL, NULL);
|
||||
|
||||
XtManageChild(layout);
|
||||
XtRealizeWidget(window);
|
||||
XtRealizeWidget(topLevel);
|
||||
XtAppMainLoop(application);
|
||||
}
|
||||
|
||||
@ -96,7 +104,11 @@ BatteryInfo getBatteryInfo (void) {
|
||||
char charging[16] = { 0 };
|
||||
int battery;
|
||||
|
||||
FILE *stream = popen("acpi -b", "r");
|
||||
pid_t child;
|
||||
FILE *stream = XmdVaPipedExecPath (
|
||||
"acpi", &child, "r",
|
||||
"acpi", "-b",
|
||||
NULL);
|
||||
if (stream == NULL) {
|
||||
result.state = BatteryStateError;
|
||||
return result;
|
||||
@ -113,13 +125,14 @@ BatteryInfo getBatteryInfo (void) {
|
||||
case 'F': result.state = BatteryStateFull; break;
|
||||
default: result.state = BatteryStateError; break;
|
||||
}
|
||||
if (pclose(stream) != 0) {
|
||||
if (fclose(stream) != 0) {
|
||||
result.state = BatteryStateError;
|
||||
}
|
||||
waitpid(child, NULL, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
Pixmap selectBatteryIcon (BatteryInfo info) {
|
||||
Pixmap selectBatteryIcon (BatteryInfo info, Pixmap levels[8]) {
|
||||
if (info.state == BatteryStateCharging) {
|
||||
return levels[5];
|
||||
} else if (info.state == BatteryStateNotCharging) {
|
||||
@ -139,15 +152,15 @@ Pixmap selectBatteryIcon (BatteryInfo info) {
|
||||
}
|
||||
}
|
||||
|
||||
void loadAllPixmaps (Widget widget) {
|
||||
levels[0] = XmdLoadBitmapIcon(widget, level0);
|
||||
levels[1] = XmdLoadBitmapIcon(widget, level1);
|
||||
levels[2] = XmdLoadBitmapIcon(widget, level2);
|
||||
levels[3] = XmdLoadBitmapIcon(widget, level3);
|
||||
levels[4] = XmdLoadBitmapIcon(widget, level4);
|
||||
levels[5] = XmdLoadBitmapIcon(widget, charging);
|
||||
levels[6] = XmdLoadBitmapIcon(widget, error);
|
||||
levels[7] = XmdLoadBitmapIcon(widget, not);
|
||||
void loadAllPixmaps (Widget widget, Pixmap destination[8]) {
|
||||
destination[0] = XmdLoadBitmapIcon(widget, level0);
|
||||
destination[1] = XmdLoadBitmapIcon(widget, level1);
|
||||
destination[2] = XmdLoadBitmapIcon(widget, level2);
|
||||
destination[3] = XmdLoadBitmapIcon(widget, level3);
|
||||
destination[4] = XmdLoadBitmapIcon(widget, level4);
|
||||
destination[5] = XmdLoadBitmapIcon(widget, charging);
|
||||
destination[6] = XmdLoadBitmapIcon(widget, error);
|
||||
destination[7] = XmdLoadBitmapIcon(widget, not);
|
||||
}
|
||||
|
||||
void batteryPoll (XtPointer clientData, XtIntervalId *timer) {
|
||||
@ -158,17 +171,15 @@ void batteryPoll (XtPointer clientData, XtIntervalId *timer) {
|
||||
XtVaSetValues (
|
||||
icon,
|
||||
XmNlabelType, XmPIXMAP,
|
||||
XmNlabelPixmap, selectBatteryIcon(info),
|
||||
XmNlabelPixmap, selectBatteryIcon(info, levels),
|
||||
NULL);
|
||||
XtVaSetValues (
|
||||
window,
|
||||
XmNiconPixmap, selectBatteryIcon(info),
|
||||
topLevel,
|
||||
XmNiconPixmap, selectBatteryIcon(info, iconLevels),
|
||||
NULL);
|
||||
|
||||
#define BUFFER_LEN 32
|
||||
char buffer[BUFFER_LEN];
|
||||
snprintf(buffer, BUFFER_LEN, "%d%%", info.level);
|
||||
#undef BUFFER_LEN
|
||||
char buffer[32];
|
||||
snprintf(buffer, XtNumber(buffer), "%d%%", info.level);
|
||||
|
||||
/* if we don't unmanage and then re-manage the child, the text flies to
|
||||
* the top which is rather annoying. this little quirk bent me over and
|
||||
@ -182,6 +193,11 @@ void batteryPoll (XtPointer clientData, XtIntervalId *timer) {
|
||||
XmStringFree(string);
|
||||
XtManageChild(text);
|
||||
|
||||
XtVaSetValues (
|
||||
topLevel,
|
||||
XmNiconName, buffer,
|
||||
NULL);
|
||||
|
||||
resetBatteryPollTimeout();
|
||||
}
|
||||
|
||||
@ -195,35 +211,40 @@ void batteryInfoDialog (Widget button, XtPointer clientData, XtPointer callData)
|
||||
|
||||
BatteryInfo info = getBatteryInfo();
|
||||
|
||||
static const char *states[] = {
|
||||
static const String states[] = {
|
||||
"Charging",
|
||||
"Not charging",
|
||||
"Full",
|
||||
"Discharging",
|
||||
"Error"
|
||||
};
|
||||
|
||||
#define BUFFER_LEN 48
|
||||
char timeBuffer[BUFFER_LEN] = { 0 };
|
||||
String messageBuffer = NULL;
|
||||
switch (info.state) {
|
||||
case BatteryStateCharging:
|
||||
snprintf (
|
||||
timeBuffer, BUFFER_LEN, "\n%d:%02d:%02d until charged.",
|
||||
XtAsprintf (
|
||||
&messageBuffer,
|
||||
"%d%%, %s\n"
|
||||
"%d:%02d:%02d until charged.",
|
||||
info.level, states[info.state],
|
||||
info.hours, info.minutes, info.seconds);
|
||||
break;
|
||||
case BatteryStateDischarging:
|
||||
snprintf (
|
||||
timeBuffer, BUFFER_LEN, "\n%d:%02d:%02d until empty.",
|
||||
XtAsprintf (
|
||||
&messageBuffer,
|
||||
"%d%%, %s\n"
|
||||
"%d:%02d:%02d until empty.",
|
||||
info.level, states[info.state],
|
||||
info.hours, info.minutes, info.seconds);
|
||||
break;
|
||||
|
||||
default:
|
||||
XtAsprintf (
|
||||
&messageBuffer,
|
||||
"%d%%, %s",
|
||||
info.level, states[info.state]);
|
||||
break;
|
||||
}
|
||||
#undef BUFFER_LEN
|
||||
#define BUFFER_LEN 128
|
||||
char messageBuffer[BUFFER_LEN];
|
||||
snprintf (
|
||||
messageBuffer, BUFFER_LEN, "%d%%, %s%s",
|
||||
info.level, states[info.state], timeBuffer);
|
||||
#undef BUFFER_LEN
|
||||
|
||||
Arg args[5] = { 0 };
|
||||
int n = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user