1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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);
}
|