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