Initial commit

This commit is contained in:
Sasha Koshka
2023-11-03 17:59:24 -04:00
commit 344c3b8431
32 changed files with 838 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
#define charging_width 48
#define charging_height 24
static unsigned char charging_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33,
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37, 0x0c, 0xe6, 0xff, 0x3f, 0xfe, 0x37,
0x46, 0xec, 0xff, 0x07, 0xff, 0x67, 0xe6, 0xec, 0xff, 0x80, 0xff, 0x6f,
0xe6, 0xec, 0x1f, 0xc0, 0xff, 0x6f, 0xe6, 0xec, 0x07, 0xe3, 0xff, 0x6f,
0xe6, 0xec, 0xff, 0x63, 0xf0, 0x6f, 0xe6, 0xec, 0xff, 0x01, 0xfc, 0x6f,
0xe6, 0xec, 0xff, 0x80, 0xff, 0x6f, 0x46, 0xec, 0x7f, 0xf0, 0xff, 0x67,
0x0c, 0xe6, 0x3f, 0xfe, 0xff, 0x37, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37,
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define error_width 48
#define error_height 24
static unsigned char error_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x30,
0x0c, 0x06, 0x40, 0x80, 0x00, 0x30, 0x0c, 0x06, 0xe0, 0xc0, 0x01, 0x30,
0x46, 0x0c, 0xc0, 0xe1, 0x00, 0x60, 0xe6, 0x0c, 0x80, 0x73, 0x00, 0x60,
0xe6, 0x0c, 0x00, 0x3f, 0x00, 0x60, 0xe6, 0x0c, 0x00, 0x1e, 0x00, 0x60,
0xe6, 0x0c, 0x00, 0x1e, 0x00, 0x60, 0xe6, 0x0c, 0x00, 0x3f, 0x00, 0x60,
0xe6, 0x0c, 0x80, 0x73, 0x00, 0x60, 0x46, 0x0c, 0xc0, 0xe1, 0x00, 0x60,
0x0c, 0x06, 0xe0, 0xc0, 0x01, 0x30, 0x0c, 0x06, 0x40, 0x80, 0x00, 0x30,
0x0c, 0x06, 0x00, 0x00, 0x00, 0x30, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define level0_width 48
#define level0_height 24
static unsigned char level0_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x32,
0x0c, 0x06, 0x00, 0x02, 0x00, 0x37, 0x0c, 0x06, 0x00, 0x07, 0x00, 0x37,
0x46, 0x0c, 0x00, 0x07, 0x00, 0x67, 0xe6, 0x0c, 0x00, 0x07, 0x80, 0x6f,
0xe6, 0x0c, 0x00, 0x07, 0x80, 0x6f, 0xe6, 0x0c, 0x00, 0x07, 0x80, 0x6f,
0xe6, 0x0c, 0x00, 0x02, 0x80, 0x6f, 0xe6, 0x0c, 0x00, 0x02, 0x80, 0x6f,
0xe6, 0x0c, 0x00, 0x00, 0x80, 0x6f, 0x46, 0x0c, 0x00, 0x02, 0x00, 0x67,
0x0c, 0x06, 0x00, 0x07, 0x00, 0x37, 0x0c, 0x06, 0x00, 0x02, 0x00, 0x37,
0x0c, 0x06, 0x00, 0x00, 0x00, 0x32, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define level1_width 48
#define level1_height 24
static unsigned char level1_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x00, 0xfe, 0x33,
0x0c, 0x06, 0x00, 0x00, 0xff, 0x37, 0x0c, 0x06, 0x00, 0x00, 0xff, 0x37,
0x46, 0x0c, 0x00, 0x00, 0xff, 0x67, 0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f,
0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f,
0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f,
0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f, 0x46, 0x0c, 0x00, 0x00, 0xff, 0x67,
0x0c, 0x06, 0x00, 0x00, 0xff, 0x37, 0x0c, 0x06, 0x00, 0x00, 0xff, 0x37,
0x0c, 0x06, 0x00, 0x00, 0xfe, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define level2_width 48
#define level2_height 24
static unsigned char level2_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0xf8, 0xff, 0x33,
0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37, 0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37,
0x46, 0x0c, 0x00, 0xfc, 0xff, 0x67, 0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f,
0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f,
0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f,
0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f, 0x46, 0x0c, 0x00, 0xfc, 0xff, 0x67,
0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37, 0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37,
0x0c, 0x06, 0x00, 0xf8, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define level3_width 48
#define level3_height 24
static unsigned char level3_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0xfe, 0xff, 0xff, 0x33,
0x0c, 0x06, 0xff, 0xff, 0xff, 0x37, 0x0c, 0x06, 0xff, 0xff, 0xff, 0x37,
0x46, 0x0c, 0xff, 0xff, 0xff, 0x67, 0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f,
0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f,
0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f,
0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0x46, 0x0c, 0xff, 0xff, 0xff, 0x67,
0x0c, 0x06, 0xff, 0xff, 0xff, 0x37, 0x0c, 0x06, 0xff, 0xff, 0xff, 0x37,
0x0c, 0x06, 0xfe, 0xff, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define level4_width 48
#define level4_height 24
static unsigned char level4_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33,
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37, 0x0c, 0xe6, 0xff, 0xff, 0xff, 0x37,
0x46, 0xec, 0xff, 0xff, 0xff, 0x67, 0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f,
0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f,
0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f,
0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f, 0x46, 0xec, 0xff, 0xff, 0xff, 0x67,
0x0c, 0xe6, 0xff, 0xff, 0xff, 0x37, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37,
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,15 @@
#define not_width 48
#define not_height 24
static unsigned char not_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0x02, 0x50, 0x55, 0x55, 0x55, 0x55, 0x05,
0x08, 0x02, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10,
0x08, 0x02, 0x00, 0x00, 0x00, 0x20, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10,
0x02, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
0xa2, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
0xa2, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
0xa2, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
0x08, 0x02, 0x00, 0x00, 0x00, 0x20, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10,
0x08, 0x02, 0x00, 0x00, 0x00, 0x20, 0x10, 0x01, 0x00, 0x00, 0x00, 0x10,
0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a, 0x40, 0x55, 0x55, 0x55, 0x55, 0x05,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

242
xmbattery/src/main.c Normal file
View File

@@ -0,0 +1,242 @@
/* C99 */
#define _XOPEN_SOURCE
#include <Xm/Xm.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 <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "icons/level0.xbm"
#include "icons/level1.xbm"
#include "icons/level2.xbm"
#include "icons/level3.xbm"
#include "icons/level4.xbm"
#include "icons/charging.xbm"
#include "icons/error.xbm"
#include "icons/not.xbm"
typedef enum {
BatteryStateCharging,
BatteryStateNotCharging,
BatteryStateFull,
BatteryStateDischarging,
BatteryStateError
} BatteryState;
typedef struct {
int level;
BatteryState state;
int hours;
int minutes;
int seconds;
} BatteryInfo;
BatteryInfo getBatteryInfo (void);
Pixmap selectBatteryIcon (BatteryInfo);
void loadAllPixmaps (Widget);
void batteryPoll (XtPointer, XtIntervalId *);
void resetBatteryPollTimeout(void);
void batteryInfoDialog (Widget, XtPointer, XtPointer);
Pixmap levels[8] = { 0 };
XtAppContext application;
Widget icon;
Widget text;
Widget layout;
Widget window;
int main (int argc, char *argv[]) {
window = XtVaAppInitialize (
&application, "Battery",
NULL, 0,
&argc, argv,
NULL,
XmNtitle, "Battery",
NULL);
layout = XtVaCreateWidget (
"layout", xmRowColumnWidgetClass, window,
XmNorientation, XmHORIZONTAL,
NULL);
loadAllPixmaps(layout);
icon = XtVaCreateManagedWidget (
"batteryIcon", xmPushButtonWidgetClass, layout,
XmNleftAttachment, XmATTACH_FORM,
XmNlabelType, XmPIXMAP,
NULL);
XtAddCallback(icon, XmNactivateCallback, batteryInfoDialog, NULL);
XtVaCreateManagedWidget (
"separator", xmSeparatorWidgetClass, layout,
XmNorientation, XmVERTICAL,
NULL);
text = XtVaCreateManagedWidget (
"text", xmLabelGadgetClass, layout,
XmNalignment, XmALIGNMENT_CENTER,
NULL);
batteryPoll(NULL, NULL);
XtManageChild(layout);
XtRealizeWidget(window);
XtAppMainLoop(application);
}
BatteryInfo getBatteryInfo (void) {
BatteryInfo result = { 0 };
char charging[16] = { 0 };
int battery;
FILE *stream = popen("acpi -b", "r");
if (stream == NULL) {
result.state = BatteryStateError;
return result;
}
fscanf (
stream, "Battery %d: %16s %d%%, %d:%d:%d",
&battery, charging, &result.level,
&result.hours, &result.minutes, &result.seconds);
switch (charging[0]) {
case 'C': result.state = BatteryStateCharging; break;
case 'N': result.state = BatteryStateNotCharging; break;
case 'D': result.state = BatteryStateDischarging; break;
case 'F': result.state = BatteryStateFull; break;
default: result.state = BatteryStateError; break;
}
if (pclose(stream) != 0) {
result.state = BatteryStateError;
}
return result;
}
Pixmap selectBatteryIcon (BatteryInfo info) {
if (info.state == BatteryStateCharging) {
return levels[5];
} else if (info.state == BatteryStateNotCharging) {
return levels[7];
} else if (info.state == BatteryStateError) {
return levels[6];
} else if (info.level < 15) {
return levels[0];
} else if (info.level < 35) {
return levels[1];
} else if (info.level < 65) {
return levels[2];
} else if (info.level < 85) {
return levels[3];
} else {
return levels[4];
}
}
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 batteryPoll (XtPointer clientData, XtIntervalId *timer) {
(void)(clientData);
(void)(timer);
BatteryInfo info = getBatteryInfo();
XtVaSetValues (
icon,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, selectBatteryIcon(info),
NULL);
XtVaSetValues (
window,
XmNiconPixmap, selectBatteryIcon(info),
NULL);
#define BUFFER_LEN 32
char buffer[BUFFER_LEN];
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
* the top which is rather annoying. this little quirk bent me over and
* fucked me for hours. */
XtUnmanageChild(text);
XmString string = XmStringCreateLocalized(buffer);
XtVaSetValues (
text,
XmNlabelString, string,
NULL);
XmStringFree(string);
XtManageChild(text);
resetBatteryPollTimeout();
}
void resetBatteryPollTimeout (void) {
XtAppAddTimeOut(application, 2000, batteryPoll, NULL);
}
void batteryInfoDialog (Widget button, XtPointer clientData, XtPointer callData) {
(void)(clientData);
(void)(callData);
BatteryInfo info = getBatteryInfo();
static const char *states[] = {
"Charging",
"Full",
"Discharging",
"Error"
};
#define BUFFER_LEN 48
char timeBuffer[BUFFER_LEN] = { 0 };
switch (info.state) {
case BatteryStateCharging:
snprintf (
timeBuffer, BUFFER_LEN, "\n%d:%02d:%02d until charged.",
info.hours, info.minutes, info.seconds);
break;
case BatteryStateDischarging:
snprintf (
timeBuffer, BUFFER_LEN, "\n%d:%02d:%02d until empty.",
info.hours, info.minutes, info.seconds);
break;
default:
}
#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;
XmString message = XmStringCreateLocalized(messageBuffer);
XtSetArg(args[n], XmNmessageString, message); n ++;
XmString title = XmStringCreateLocalized("Battery Status");
XtSetArg(args[n], XmNdialogTitle, title); n ++;
Widget dialog = XmCreateInformationDialog(button, "batteryInfo", args, n);
XmStringFree(message);
XmStringFree(title);
XtManageChild(dialog);
XtPopup(XtParent(dialog), XtGrabNone);
}