aboutsummaryrefslogtreecommitdiff
path: root/xbattext.c
diff options
context:
space:
mode:
authorJohn Ankarstr\xf6m <john@ankarstrom.se>2021-06-01 16:20:24 +0200
committerJohn Ankarstr\xf6m <john@ankarstrom.se>2021-06-01 16:20:24 +0200
commit603e8ca2e2b4df967ce8d251a7718485f971d353 (patch)
treee6c433824d3184f0cf8edbb75540bb2e8356f04a /xbattext.c
downloadxbattext-603e8ca2e2b4df967ce8d251a7718485f971d353.tar.gz
Use Motif instead of Athena
Diffstat (limited to 'xbattext.c')
-rw-r--r--xbattext.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/xbattext.c b/xbattext.c
new file mode 100644
index 0000000..5e59ce1
--- /dev/null
+++ b/xbattext.c
@@ -0,0 +1,120 @@
+/*
+ * This is a simple X11 program that displays the battery percentage
+ * on NetBSD.
+ *
+ * It should be compiled with the following flags:
+ *
+ * CFLAGS = -I/usr/X11R7/include -I/usr/pkg/include
+ * LDFLAGS = -lXm -L/usr/X11R7/lib -L/usr/pkg/lib
+ * LDFLAGS += -Wl,-R/usr/X11R7/lib -Wl,-R/usr/pkg/lib
+ *
+ * It requires x11/motif to be installed.
+ * The fontList resource controls the font used.
+ *
+ * xbattext is written by John Ankarstr\xf6m <john@ankarstrom.se> and
+ * is released into the public domain; do whatever you want with it.
+ */
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <Xm/Label.h>
+#include <Xm/Xm.h>
+#include <err.h>
+#include <fcntl.h>
+#include <machine/apmvar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/envsys.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+/* interval in seconds */
+#define INTERVAL 30
+
+/* low battery level */
+#define ALERT 30
+
+void update(XtPointer, XtIntervalId *);
+
+/* application state */
+Arg wargs[10];
+char *s;
+int apmfd, alert;
+struct apm_power_info info;
+Widget toplevel, label;
+XmString str;
+XtAppContext app_context;
+XtIntervalId timer = 0;
+
+int
+main(int argc, char* argv[])
+{
+ toplevel = XtVaAppInitialize(
+ &app_context,
+ "XBat",
+ NULL, 0,
+ &argc, argv,
+ NULL,
+ NULL);
+
+ if ((apmfd = open("/dev/apm", O_RDONLY, 0755)) == -1)
+ err(1, "open");
+
+ if ((s = malloc(5*sizeof(char))) == NULL)
+ err(1, "malloc");
+
+ XtSetLanguageProc(NULL, NULL, NULL);
+
+ /* create motif label */
+ label = XtVaCreateManagedWidget("text",
+ xmLabelWidgetClass, toplevel,
+ XmNlabel, "",
+ NULL);
+ alert = 0;
+
+ update(NULL, &timer);
+ XtRealizeWidget(toplevel);
+ XtAppMainLoop(app_context);
+}
+
+/* update battery status and (re-)add timer */
+void
+update(XtPointer client_data, XtIntervalId *t)
+{
+ /* remove current timer */
+ if (t == NULL && timer) {
+ XtRemoveTimeOut(timer);
+ timer = 0;
+ }
+
+ /* get battery info */
+ memset(&info, 0, sizeof(info));
+ if (ioctl(apmfd, APM_IOC_GETPOWER, &info) == -1) {
+ fprintf(stderr, "ioctl APM_IOC_GETPOWER failed\n");
+ sprintf(s, "?");
+ goto end;
+ }
+
+ /* put battery status into label */
+ sprintf(s, "%d%%", info.battery_life);
+ str = XmStringCreate(s, XmFONTLIST_DEFAULT_TAG);
+ XtSetArg(wargs[0], XmNlabelString, str);
+ XtSetValues(label, wargs, 1);
+ XmStringFree(str);
+
+ /* change color if low battery */
+#ifdef ALERT
+ if (!alert && info.battery_life < ALERT) {
+ XtVaSetValues(label,
+ XtVaTypedArg, XmNforeground, XmRString, "red", 4);
+ alert = 1;
+ } else if (alert && info.battery_life >= ALERT) {
+ XtVaSetValues(label,
+ XtVaTypedArg, XmNforeground, XmRString, "black", 4);
+ alert = 0;
+ }
+#endif
+
+ /* add new timer */
+end: timer = XtAppAddTimeOut(app_context, INTERVAL * 1000, update, toplevel);
+}