.so /home/john/prj/re/re.tmac .ds Sf MR .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.