aboutsummaryrefslogtreecommitdiff
path: root/xbattext.ms
blob: c54f74cec295f0954908451b4c96959e4430eef3 (plain)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
.so /home/john/prj/re/re.tmac
.de Q
\\$3\(lq\\$1\(rq\\$2
..
.TL
.BI xbattext ,
an X11 battery monitor for NetBSD
.AU
John Ankarström
.AB
.LP
.I xbattext
is a simple X11 program that displays, in text,
the current battery level.
Its source code serves as a good introduction to X11 programnming.
It is short, simple and easy to follow,
as it accounts only for a single system \(en NetBSD.
It makes use of both Xt (X toolkit intrinsics) and Xm (Motif),
two of the most popular X libraries.
It demonstrates how to access resources from
.I ~/.Xdefaults ,
how to display text in various colors and fonts and
how to set timers outside of the main event loop
to perform asynchronous tasks that are not triggered by user interaction.
.PP
This document is a commented version of the
.I xbattext
source code.
It is generated with
.I re ,
a reference-based literate programming system available at the WWW address
http://git.\:ankarstrom.se/re/.
.AE
.Re xbattext.c:/^#include/
.LP
.I Xm/Label.h
contains the definitions for Motif's label widget,
which is used to display the text.
That file, in turn, includes
.I X11/Xlib.h
for us.
.PP
.I machine/apmvar.h
is needed in order to inspect the battery status on NetBSD.
.Re xbattext.c:/^\/\* interval in seconds/
.LP
By default, the battery status is checked every ten seconds.
.Re xbattext.c:/^struct res/
.LP
Two structures are created to access the application's resources:
.I res ,
which will hold the values of the resources, and
.I res_opts ,
which defines how those resources should be retrieved.
.PP
The
.I res
structure is going to be filled by the function
.I XtGetApp\%licationResources
using the information defined in
.I res_opts .\**
.FS
For more information about resource management and the structure of the
.I XtResource
type, see
.nh
http://lesstif.sourceforge.net/doc/super-ux/g1ae03e/part1/chap9.html.
.hy
.FE
.Re xbattext.c:/"alertFontList"/
\&
.Re xbattext.c:/^\/\* application state/
.LP
There is not space to explain the function of all variables
used by the program,
but some of them deserve a special mention:
.PP
.ps -1p
.vs -1p
.I wargs
is used by
.I XtSetArg ,
which stores arguments in it, and
.I XtSetValues ,
which sets new values for a widget
according to the arguments stored in it.
.PP
.ps -1p
.vs -1p
.I alert
and
.I charge
are boolean variables that are set to true
whenever
.I xbattext
detects that the battery is low or
that the AC adapter is plugged in.
.Re xbattext.c:/XtVaAppInitialize(/
.LP
Many Xt functions have two variants:
a non-variadic variant, which uses
.I XtSetArg
to collect arguments,
and a variadic variant, marked by the
.I Va
component of its name.
.PP
.I toplevel
contains the
.Q main
widget that contains all actual widgets.
.Re xbattext.c:/open("\/dev\/apm"/
.LP
The battery level is queried through
.I ioctl
requests to
.I /dev/apm .
The file descriptor is closed by the kernel when the program exits.
.Re xbattext.c:/^	\/\* load application resources/
.LP
As mentioned earlier,
.I XtGetApplicationResources
uses the
.I XtResour\%ce
list defined above to fill the
.I res
structure with the corresponding resources.
.bp
.Re xbattext.c:/^	\/\* create motif label/
.LP
The battery level is displayed in a Motif label widget.
It starts out containing an empty string.
.Re xbattext.c:/^	update(/
.LP
Before starting the main event loop, the
.I update
function is called, which registers a timeout that will run
independently of the event loop.\**
.FS
For more information about timeouts, see
http://motifdeveloper.com/tips/tip16.html.
.FE
.Re xbattext.c:/^\/\* update battery status and (re-)add timer/
.LP
The
.I update
function, which is called at the end of each timeout,
is responsible for checking the battery status and
updating the label.
.PP
The first argument is a pointer to a value set by the user
when the timeout is registered.
The second argument contains a pointer to the timeout ID.
Neither argument is used in this program.
.Re xbattext.c:/^	\/\* get battery info/
.LP
As mentioned earlier,
the battery status is retrieved through an
.I ioctl
request,
.CW APM_IOC_GETPOWER .
It returns an
.I apm_power_info
structure (which must be zeroed first).
.Re xbattext.c:/^	\/\* put battery status into label/
.LP
The battery percentage, contained in
.I info.battery_life ,
is written to an
.I XmString ,
which is a special type of string used by Motif.
It is associated with a
.Q "font list element tag" ,
which contains information about the visual characteristics of the text.
We just use the default.
.Re xbattext.c:/^	\/\* set color and font/
.LP
In the following section, the
.I wargs
array mentioned earlier is filled with a number of arguments
that determine the visual appearance of the label widget.
The number of arguments set is kept track of in the
.I i
variable.
To begin with, the widget's label string is set to the previously defined
.I XmString
value.
.bp
.Re xbattext.c:/^	\/\* check .* ac adapter .* plugged in/
.LP
Whenever the value of
.I info.ac_\:state
is changed to
.CW APM_AC_ON ,
signifying that the AC adapter is plugged in,
the label widget's foreground color and font is set
according to the application resources.
If no
.I chargeForeground
resource is defined, the
.I XtGetApplicationResources
function sets the color to the integer value zero,
which is the color black
(thus, the program cannot differentiate
between a missing value and a value of
.I black ).
The font list, however, is set to null if undefined.
If it is undefined, the main font list is used.
.PP
Note that the
.I charge
variable is set in order to prevent these font and color changes
from unnecessarily  being applied every timeout
regardless of whether the charging status has changed.
Note also that any further checks are skipped via a
.I goto
statement,
as the charging indication should override the low battery indication.
.Re xbattext.c:/^	\/\* check low battery/
.LP
The same applies when the program checks whether the battery level is below
.CW ALERT ,
which is set to 30 by default.
.PP
If, after being below the threshold, the battery level rises above it,
the color and font are reset to their default values.
.bp
.Re xbattext.c:/^	\/\* check .* ac adapter .* plugged out/
.LP
After the low battery checks,
the program checks whether the AC adapter has been plugged out.
While the low battery indication should not be overriden
by a return to a normal, non-charging state,
it is important that the
.I charge
variable is updated to reflect the state.
.PP
The value of the
.I i
counter is inspected to see whether the low battery checks above
have triggered any color or font changes.
If they haven't, the color and font are reset to their default values,
signifying a neither charging nor low battery.
.Re xbattext.c:/^set:/
.LP
Finally, the values collected in
.I wargs
are associated with the label widget through the
.I XtSetValues
function.
The
.I XmString
is freed,
as a new one will be created on the next call to
.I update ,
which at the end is registered through the
.I Xt\%AppAddTimeOut
function to occur in
.CW INTERVAL
seconds.