From 51380525e7bb362ceb3024c65fb84e8504003596 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 19 Sep 2014 23:23:18 -0500 Subject: [PATCH] wmbattery: Add to repository. Version 2.44. Source obtained from: http://ftp.de.debian.org/debian/pool/main/w/wmbattery/wmbattery_2.44.tar.gz --- wmbattery/.gitattributes | 1 + wmbattery/GPL | 340 +++++++++++++++++ wmbattery/INSTALL | 195 ++++++++++ wmbattery/Makefile | 52 +++ wmbattery/README | 41 +++ wmbattery/TODO | 11 + wmbattery/acpi.c | 445 ++++++++++++++++++++++ wmbattery/acpi.h | 67 ++++ wmbattery/apm.h | 27 ++ wmbattery/autoconf/install-sh | 250 +++++++++++++ wmbattery/autoconf/makeinfo.in | 21 ++ wmbattery/battery_blink.xpm | 19 + wmbattery/battery_high.xpm | 19 + wmbattery/battery_low.xpm | 20 + wmbattery/battery_medium.xpm | 20 + wmbattery/battery_none.xpm | 18 + wmbattery/bigfont.xpm | 17 + wmbattery/charging.xpm | 19 + wmbattery/config.h.in | 9 + wmbattery/configure.ac | 44 +++ wmbattery/debian/changelog | 546 +++++++++++++++++++++++++++ wmbattery/debian/compat | 1 + wmbattery/debian/control | 24 ++ wmbattery/debian/copyright | 12 + wmbattery/debian/docs | 2 + wmbattery/debian/menu | 2 + wmbattery/debian/rules | 11 + wmbattery/dial_bright.xpm | 43 +++ wmbattery/dial_dim.xpm | 43 +++ wmbattery/face.xpm | 74 ++++ wmbattery/mask.xbm | 46 +++ wmbattery/nocharging.xpm | 18 + wmbattery/plugged.xpm | 17 + wmbattery/simplehal.c | 223 +++++++++++ wmbattery/simplehal.h | 2 + wmbattery/smallfont.xpm | 16 + wmbattery/sonypi.c | 74 ++++ wmbattery/sonypi.h | 19 + wmbattery/unplugged.xpm | 17 + wmbattery/upower.c | 151 ++++++++ wmbattery/upower.h | 2 + wmbattery/wmbattery.1x | 110 ++++++ wmbattery/wmbattery.c | 653 +++++++++++++++++++++++++++++++++ wmbattery/wmbattery.h | 70 ++++ 44 files changed, 3811 insertions(+) create mode 100644 wmbattery/.gitattributes create mode 100644 wmbattery/GPL create mode 100644 wmbattery/INSTALL create mode 100644 wmbattery/Makefile create mode 100644 wmbattery/README create mode 100644 wmbattery/TODO create mode 100644 wmbattery/acpi.c create mode 100644 wmbattery/acpi.h create mode 100644 wmbattery/apm.h create mode 100755 wmbattery/autoconf/install-sh create mode 100644 wmbattery/autoconf/makeinfo.in create mode 100644 wmbattery/battery_blink.xpm create mode 100644 wmbattery/battery_high.xpm create mode 100644 wmbattery/battery_low.xpm create mode 100644 wmbattery/battery_medium.xpm create mode 100644 wmbattery/battery_none.xpm create mode 100644 wmbattery/bigfont.xpm create mode 100644 wmbattery/charging.xpm create mode 100644 wmbattery/config.h.in create mode 100644 wmbattery/configure.ac create mode 100644 wmbattery/debian/changelog create mode 100644 wmbattery/debian/compat create mode 100644 wmbattery/debian/control create mode 100644 wmbattery/debian/copyright create mode 100644 wmbattery/debian/docs create mode 100644 wmbattery/debian/menu create mode 100755 wmbattery/debian/rules create mode 100644 wmbattery/dial_bright.xpm create mode 100644 wmbattery/dial_dim.xpm create mode 100644 wmbattery/face.xpm create mode 100644 wmbattery/mask.xbm create mode 100644 wmbattery/nocharging.xpm create mode 100644 wmbattery/plugged.xpm create mode 100644 wmbattery/simplehal.c create mode 100644 wmbattery/simplehal.h create mode 100644 wmbattery/smallfont.xpm create mode 100644 wmbattery/sonypi.c create mode 100644 wmbattery/sonypi.h create mode 100644 wmbattery/unplugged.xpm create mode 100644 wmbattery/upower.c create mode 100644 wmbattery/upower.h create mode 100644 wmbattery/wmbattery.1x create mode 100644 wmbattery/wmbattery.c create mode 100644 wmbattery/wmbattery.h diff --git a/wmbattery/.gitattributes b/wmbattery/.gitattributes new file mode 100644 index 0000000..5d42584 --- /dev/null +++ b/wmbattery/.gitattributes @@ -0,0 +1 @@ +debian/changelog merge=dpkg-mergechangelogs diff --git a/wmbattery/GPL b/wmbattery/GPL new file mode 100644 index 0000000..b7b5f53 --- /dev/null +++ b/wmbattery/GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/wmbattery/INSTALL b/wmbattery/INSTALL new file mode 100644 index 0000000..6255a97 --- /dev/null +++ b/wmbattery/INSTALL @@ -0,0 +1,195 @@ +Quickstart: + + make + make install + +To install in the same location as previous version's Makefile did, +run configure like this: + + ./configure --prefix=/usr/X11R6 --datadir=/usr/share + +Note that you will need libxpm to build and use the program. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/wmbattery/Makefile b/wmbattery/Makefile new file mode 100644 index 0000000..b5262d5 --- /dev/null +++ b/wmbattery/Makefile @@ -0,0 +1,52 @@ +include makeinfo + +all: wmbattery + +clean: + rm -f wmbattery *.o + +distclean: clean + rm -f config.status config.cache config.log makeinfo config.h configure + +install: all + $(INSTALL) -d $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) $(DESTDIR)$(icondir) + $(INSTALL_PROGRAM) wmbattery $(DESTDIR)$(bindir) + $(INSTALL_DATA) $(srcdir)/wmbattery.1x $(DESTDIR)$(man1dir)/wmbattery.1x + $(INSTALL_DATA) $(srcdir)/*.xpm $(DESTDIR)$(icondir) + +uninstall: + rm -rf $(bindir)/wmbattery $(man1dir)/wmbattery.1x $(icondir) + +OBJS=wmbattery.o acpi.o sonypi.o + +ifdef USE_HAL +LIBS+=$(shell pkg-config --libs hal) +OBJS+=simplehal.o +CFLAGS+=-DHAL +simplehal.o: simplehal.c + $(CC) $(CFLAGS) $(shell pkg-config --cflags hal) -c simplehal.c -o simplehal.o +endif + +ifdef USE_UPOWER +LIBS+=$(shell pkg-config --libs upower-glib) +OBJS+=upower.o +CFLAGS+=-DUPOWER +upower.o: upower.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(shell pkg-config --cflags upower-glib) -c upower.c -o upower.o +endif + +LIBS+=-lapm -lXext -lXpm + +wmbattery: $(OBJS) + $(CC) -o wmbattery $(LDFLAGS) $(OBJS) $(LIBS) + +wmbattery.o: wmbattery.c wmbattery.h + +configure: configure.ac + autoconf + +config.status: configure + ./configure + +makeinfo: autoconf/makeinfo.in config.status + ./config.status diff --git a/wmbattery/README b/wmbattery/README new file mode 100644 index 0000000..60c54bc --- /dev/null +++ b/wmbattery/README @@ -0,0 +1,41 @@ +wmbattery displays the status of your laptop's battery in a small icon. This +includes if it is plugged in, if the battery is charging, how many minutes +of battery life remain, battery life remaining (with both a percentage and a +graph), and battery status (high - green, low - yellow, or critical - red). + +wmbattery is based on wmapm by Chris D. Faulhaber +-- see the copyright file for more information. + +wmapm is a nice program - why have I modified it into wmbattery? Here are +some improvements in wmbattery: + + - Improved icon layout. I crammed the same information into less space + while making the icon more elegant and visually pleasing (IMHO). + - Easier to drag onto dock. + - It consumes a little less memory. + - Uses only 10 colors. + - You can run in on a different display via -d (broken in wmapm). + - Support for getting battery status from the sonypi driver instead of APM, + for some Sony laptops that do not have apm support. + - ACPI support, including multiple battery support and battery charging + completion countdown timer. + - HAL support. + - upower support. + - Can make its own estimatess of time remaining or time until full + charge, even if APM does not. + +Conversely, here are some reasons to stick with wmapm: + + - You like its look. + - It has a neat rainbow-colored progress bar. + - It has buttons to suspend the laptop and stuff. + - It may be more actively and/or better maintained. Or not. + Decide for yourself. + +Still, forking is evil, and if I was doing this all over again, I suppose +I'd try to add theme support to wmamn so it could morph into wmbattery with +a theme. Oh well. + +The homepage for wmbattery is + +-- Joey Hess diff --git a/wmbattery/TODO b/wmbattery/TODO new file mode 100644 index 0000000..7b41755 --- /dev/null +++ b/wmbattery/TODO @@ -0,0 +1,11 @@ +* The dial doesn't fill up/drain out very prettily. Add some code to special + case things so it looks better. +* Make it load up the mask from file, not #include it. +* Allow user-settable colors, like asclock does. +* Improve the battery lifetime estimation algo. +* Break the ACPI code out into a proper standalone library (already 2 other + programs use it). +* Make -b 0 display an overall average of the status of all batteries, + much like apm does on multi-battery laptops. +* The simplehal interface is not very good. It polls once per second, + it would be much better if it let HAL notify it about changes instead. diff --git a/wmbattery/acpi.c b/wmbattery/acpi.c new file mode 100644 index 0000000..96950e6 --- /dev/null +++ b/wmbattery/acpi.c @@ -0,0 +1,445 @@ +/* + * A not-yet-general-purpose ACPI library, by Joey Hess + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef ACPI_APM +#include "apm.h" +#endif +#include +#include +#include + +#include "acpi.h" + +#define SYSFS_PATH "/sys/class/power_supply" +#define ACPI_MAXITEM 8 + +int acpi_batt_count = 0; +/* Filenames of the battery info files for each system battery. */ +char acpi_batt_info[ACPI_MAXITEM][128]; +/* Filenames of the battery status files for each system battery. */ +char acpi_batt_status[ACPI_MAXITEM][128]; +/* Stores battery capacity, or 0 if the battery is absent. */ +int acpi_batt_capacity[ACPI_MAXITEM]; + +int acpi_ac_count = 0; +char acpi_ac_adapter_info[ACPI_MAXITEM][128]; +char acpi_ac_adapter_status[ACPI_MAXITEM][128]; + +char *acpi_labels[] = { + "uevent", + "status", + "Battery", + "Mains", + "POWER_SUPPLY_CAPACITY=", + "POWER_SUPPLY_??????_FULL_DESIGN=", /* CHARGE or ENERGY */ + "POWER_SUPPLY_PRESENT=", + "POWER_SUPPLY_??????_NOW=", + "POWER_SUPPLY_CURRENT_NOW=", + "POWER_SUPPLY_STATUS=", +#if ACPI_THERMAL + "thermal_zone", +#endif + "POWER_SUPPLY_ONLINE=", + "POWER_SUPPLY_??????_FULL=", + NULL +}; + +#if ACPI_THERMAL +int acpi_thermal_count = 0; +char acpi_thermal_info[ACPI_MAXITEM][128]; +char acpi_thermal_status[ACPI_MAXITEM][128]; +#endif + +/* Read in an entire ACPI proc file (well, the first 1024 bytes anyway), and + * return a statically allocated array containing it. */ +inline char *get_acpi_file (const char *file) { + int fd; + int end; + static char buf[1024]; + fd = open(file, O_RDONLY); + if (fd == -1) return NULL; + end = read(fd, buf, sizeof(buf)); + buf[end-1] = '\0'; + close(fd); + return buf; +} + +int strmcmp(const char *s1, const char *s2) +{ + for (; (*s1 == *s2) || (*s2 == '?'); s1++, s2++) { + if (*s1 == '\0') + return 0; + } + if (*s2 == '\0') + return 0; + else + return 1; +} + +/* Given a buffer holding an acpi file, searches for the given key in it, + * and returns the numeric value. 0 is returned on failure. */ +inline int scan_acpi_num (const char *buf, const char *key) { + char *ptr; + int ret = 0; + + do { + ptr = strchr(buf, '\n'); + if (!strmcmp(buf, key)) { + if ((ptr = strchr(buf, '='))) { + sscanf(ptr + 1, "%d", &ret); + return ret; + } else { + return 0; + } + } + if (ptr) + ptr++; + buf = ptr; + } while (buf != NULL); + return 0; +} + +/* Given a buffer holding an acpi file, searches for the given key in it, + * and returns its value in a statically allocated string. */ +inline char *scan_acpi_value (const char *buf, const char *key) { + char *ptr; + static char ret[256]; + + do { + ptr = strchr(buf, '\n'); + if (!strmcmp(buf, key)) { + if ((ptr = strchr(buf, '='))) { + if (sscanf(ptr + 1, "%255s", ret) == 1) { + return ret; + } else { + return NULL; + } + } else { + return NULL; + } + } + if (ptr) + ptr++; + buf = ptr; + } while (buf != NULL); + return NULL; +} + +/* Read an ACPI proc file, pull out the requested piece of information, and + * return it (statically allocated string). Returns NULL on error, This is + * the slow, dumb way, fine for initialization or if only one value is needed + * from a file, slow if called many times. */ +char *get_acpi_value (const char *file, const char *key) { + char *buf = get_acpi_file(file); + if (! buf) return NULL; + return scan_acpi_value(buf, key); +} + +/* Returns the last full charge capacity of a battery. + */ +int get_acpi_batt_capacity(int battery) { + char *s; + + s = get_acpi_value(acpi_batt_info[battery], acpi_labels[label_last_full_capacity]); + if (s == NULL) { + return 0; + } else { + return atoi(s); + } +} + +/* Comparison function for qsort. */ +int _acpi_compare_strings (const void *a, const void *b) { + const char **pa = (const char **)a; + const char **pb = (const char **)b; + return strcasecmp((const char *)*pa, (const char *)*pb); +} + +/* Find something (batteries, ac adpaters, etc), and set up a string array + * to hold the paths to info and status files of the things found. + * Returns the number of items found. */ +int find_items (char *itemname, char infoarray[ACPI_MAXITEM][128], + char statusarray[ACPI_MAXITEM][128]) { + DIR *dir; + struct dirent *ent; + int num_devices=0; + int i; + char **devices = malloc(ACPI_MAXITEM * sizeof(char *)); + + char pathname[128]; + + sprintf(pathname, SYSFS_PATH); + + dir = opendir(pathname); + if (dir == NULL) + return 0; + while ((ent = readdir(dir))) { + char filename[128]; + char buf[1024]; + + if (!strcmp(".", ent->d_name) || + !strcmp("..", ent->d_name)) + continue; + + snprintf(filename, sizeof(filename), SYSFS_PATH "/%s/type", ent->d_name); + int fd = open(filename, O_RDONLY); + if (fd != -1) { + int end = read(fd, buf, sizeof(buf)); + buf[end-1] = '\0'; + close(fd); + if (strstr(buf, itemname) != buf) + continue; + } + + devices[num_devices]=strdup(ent->d_name); + num_devices++; + if (num_devices >= ACPI_MAXITEM) + break; + } + closedir(dir); + + /* Sort, since readdir can return in any order. /sys/ does + * sometimes list BAT1 before BAT0. */ + qsort(devices, num_devices, sizeof(char *), _acpi_compare_strings); + + for (i = 0; i < num_devices; i++) { + snprintf(infoarray[i], sizeof(infoarray[i]), SYSFS_PATH "/%s/%s", devices[i], + acpi_labels[label_info]); + snprintf(statusarray[i], sizeof(statusarray[i]), SYSFS_PATH "/%s/%s", devices[i], + acpi_labels[label_status]); + free(devices[i]); + } + + return num_devices; +} + +/* Find batteries, return the number, and set acpi_batt_count to it as well. */ +int find_batteries(void) { + int i; + acpi_batt_count = find_items(acpi_labels[label_battery], acpi_batt_info, acpi_batt_status); + for (i = 0; i < acpi_batt_count; i++) + acpi_batt_capacity[i] = get_acpi_batt_capacity(i); + return acpi_batt_count; +} + +/* Find AC power adapters, return the number found, and set acpi_ac_count to it + * as well. */ +int find_ac_adapters(void) { + acpi_ac_count = find_items(acpi_labels[label_ac_adapter], acpi_ac_adapter_info, acpi_ac_adapter_status); + return acpi_ac_count; +} + +#if ACPI_THERMAL +/* Find thermal information sources, return the number found, and set + * thermal_count to it as well. */ +int find_thermal(void) { + acpi_thermal_count = find_items(acpi_labels[label_thermal], acpi_thermal_info, acpi_thermal_status); + return acpi_thermal_count; +} +#endif + +/* Returns true if the system is on ac power. Call find_ac_adapters first. */ +int on_ac_power (void) { + int i; + for (i = 0; i < acpi_ac_count; i++) { + char *online=get_acpi_value(acpi_ac_adapter_info[i], acpi_labels[label_ac_state]); + if (online && atoi(online)) + return 1; + else + return 0; + } + return 0; +} + +/* See if we have ACPI support and check version. Also find batteries and + * ac power adapters. */ +int acpi_supported (void) { + char *version; + DIR *dir; + int num; + + if (!(dir = opendir(SYSFS_PATH))) { + return 0; + } + closedir(dir); + + /* If kernel is 2.6.21 or newer, version is in + /sys/module/acpi/parameters/acpica_version */ + + version = get_acpi_file("/sys/module/acpi/parameters/acpica_version"); + if (version == NULL) { + return 0; + } + num = atoi(version); + if (num < ACPI_VERSION) { + fprintf(stderr, "ACPI subsystem %s too is old, consider upgrading to %i.\n", + version, ACPI_VERSION); + return 0; + } + + find_batteries(); + find_ac_adapters(); +#if ACPI_THERMAL + find_thermal(); +#endif + + return 1; +} + +#ifdef ACPI_APM +/* Read ACPI info on a given power adapter and battery, and fill the passed + * apm_info struct. */ +int acpi_read (int battery, apm_info *info) { + char *buf, *state; + + if (acpi_batt_count == 0) { + info->battery_percentage = 0; + info->battery_time = 0; + info->battery_status = BATTERY_STATUS_ABSENT; + acpi_batt_capacity[battery] = 0; + /* Where else would the power come from, eh? ;-) */ + info->ac_line_status = 1; + return 0; + } + + /* Internally it's zero indexed. */ + battery--; + + buf = get_acpi_file(acpi_batt_info[battery]); + if (buf == NULL) { + fprintf(stderr, "unable to read %s\n", acpi_batt_info[battery]); + perror("read"); + exit(1); + } + + info->ac_line_status = 0; + info->battery_flags = 0; + info->using_minutes = 1; + + /* Work out if the battery is present, and what percentage of full + * it is and how much time is left. */ + if (strcmp(scan_acpi_value(buf, acpi_labels[label_present]), "1") == 0) { + int pcap = scan_acpi_num(buf, acpi_labels[label_remaining_capacity]); + int rate = scan_acpi_num(buf, acpi_labels[label_present_rate]); + if (rate) { + /* time remaining = (current_capacity / discharge rate) */ + info->battery_time = (float) pcap / (float) rate * 60; + } + else { + char *rate_s = scan_acpi_value(buf, acpi_labels[label_present_rate]); + if (! rate_s) { + /* Time remaining unknown. */ + info->battery_time = 0; + } + else { + /* a zero or unknown in the file; time + * unknown so use a negative one to + * indicate this */ + info->battery_time = -1; + } + } + + state = scan_acpi_value(buf, acpi_labels[label_charging_state]); + if (state) { + if (state[0] == 'D') { /* discharging */ + info->battery_status = BATTERY_STATUS_CHARGING; + /* Expensive ac power check used here + * because AC power might be on even if a + * battery is discharging in some cases. */ + info->ac_line_status = on_ac_power(); + } + else if (state[0] == 'C' && state[1] == 'h') { /* charging */ + info->battery_status = BATTERY_STATUS_CHARGING; + info->ac_line_status = 1; + info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING; + if (rate) + info->battery_time = -1 * (float) (acpi_batt_capacity[battery] - pcap) / (float) rate * 60; + else + info->battery_time = 0; + if (abs(info->battery_time) < 0.5) + info->battery_time = 0; + } + else if (state[0] == 'F') { /* full */ + /* charged, on ac power */ + info->battery_status = BATTERY_STATUS_HIGH; + info->ac_line_status = 1; + } + else if (state[0] == 'C') { /* not charging, so must be critical */ + info->battery_status = BATTERY_STATUS_CRITICAL; + /* Expensive ac power check used here + * because AC power might be on even if a + * battery is critical in some cases. */ + info->ac_line_status = on_ac_power(); + } + else if (state[0] == 'U') { /* unknown */ + info->ac_line_status = on_ac_power(); + int current = scan_acpi_num(buf, acpi_labels[label_present_rate]); + if (info->ac_line_status) { + if (current == 0) + info->battery_status = BATTERY_STATUS_HIGH; + else + info->battery_status = BATTERY_STATUS_CHARGING; + } + else { + info->battery_status = BATTERY_STATUS_CHARGING; + } + } + else { + fprintf(stderr, "unknown battery state: %s\n", state); + } + } + else { + /* Battery state unknown. */ + info->battery_status = BATTERY_STATUS_ABSENT; + } + + if (acpi_batt_capacity[battery] == 0) { + /* The battery was absent, and now is present. + * Well, it might be a different battery. So + * re-probe the battery. */ + /* NOTE that this invalidates buf. No accesses of + * buf below this point! */ + acpi_batt_capacity[battery] = get_acpi_batt_capacity(battery); + } + else if (pcap > acpi_batt_capacity[battery]) { + /* Battery is somehow charged to greater than max + * capacity. Rescan for a new max capacity. */ + find_batteries(); + } + + if (pcap && acpi_batt_capacity[battery]) { + info->battery_percentage = 100 * pcap / acpi_batt_capacity[battery]; + if (info->battery_percentage > 100) + info->battery_percentage = 100; + } + else { + info->battery_percentage = -1; + } + + } + else { + info->battery_percentage = 0; + info->battery_time = 0; + info->battery_status = BATTERY_STATUS_ABSENT; + acpi_batt_capacity[battery] = 0; + if (acpi_batt_count == 0) { + /* Where else would the power come from, eh? ;-) */ + info->ac_line_status = 1; + } + else { + /* Expensive ac power check. */ + info->ac_line_status = on_ac_power(); + } + } + + return 0; +} +#endif diff --git a/wmbattery/acpi.h b/wmbattery/acpi.h new file mode 100644 index 0000000..f82cba7 --- /dev/null +++ b/wmbattery/acpi.h @@ -0,0 +1,67 @@ +/* + * A not-yet-general-purpose ACPI library, by Joey Hess + */ + +/* Define ACPI_THERMAL to make the library support finding info about thermal + * sources. */ +//#define ACPI_THERMAL 1 + +/* Define ACPI_APM to get the acpi_read function, which is like apm_read. */ +//#define ACPI_APM 1 + +/* The lowest version of ACPI proc files supported. */ +#define ACPI_VERSION 20011018 + +/* The number of acpi items of each class supported. */ +#define ACPI_MAXITEM 8 + +int acpi_supported (void); +#ifdef ACPI_APM +int acpi_read (int battery, apm_info *info); +#endif +char *get_acpi_file (const char *file); +int scan_acpi_num (const char *buf, const char *key); +char *scan_acpi_value (const char *buf, const char *key); +char *get_acpi_value (const char *file, const char *key); +int get_acpi_batt_capacity(int battery); + +extern int acpi_batt_count; +/* Filenames of the battery info files for each system battery. */ +extern char acpi_batt_info[ACPI_MAXITEM][128]; +/* Filenames of the battery status files for each system battery. */ +extern char acpi_batt_status[ACPI_MAXITEM][128]; +/* Stores battery capacity, or 0 if the battery is absent. */ +extern int acpi_batt_capacity[ACPI_MAXITEM]; + +extern int acpi_ac_count; +extern char acpi_ac_adapter_info[ACPI_MAXITEM][128]; +extern char acpi_ac_adapter_status[ACPI_MAXITEM][128]; + +#if ACPI_THERMAL +extern int acpi_thermal_count; +extern char acpi_thermal_info[ACPI_MAXITEM][128]; +extern char acpi_thermal_status[ACPI_MAXITEM][128]; +#endif + +/* This enum is used to index into the acpi_labels */ +enum acpi_labels_items { + label_info, + label_status, + label_battery, + label_ac_adapter, + label_capacity, + label_design_capacity, + label_present, + label_remaining_capacity, + label_present_rate, + label_charging_state, +#if ACPI_THERMAL + label_thermal, +#endif + label_ac_state, + label_last_full_capacity, +}; + +/* This is set to point to a list of strings used for the given acpi + * * version. */ +extern char *acpi_labels[]; diff --git a/wmbattery/apm.h b/wmbattery/apm.h new file mode 100644 index 0000000..a5aec22 --- /dev/null +++ b/wmbattery/apm.h @@ -0,0 +1,27 @@ +#include + +/* Symbolic constants for apm may be in system apm.h, or may not. */ +#ifndef AC_LINE_STATUS_ON +#define AC_LINE_STATUS_OFF (0) +#define AC_LINE_STATUS_ON (1) +#define AC_LINE_STATUS_BACKUP (2) +#define AC_LINE_STATUS_UNKNOWN (0xff) + +#define BATTERY_STATUS_HIGH (0) +#define BATTERY_STATUS_LOW (1) +#define BATTERY_STATUS_CRITICAL (2) +#define BATTERY_STATUS_CHARGING (3) +#define BATTERY_STATUS_ABSENT (4) +#define BATTERY_STATUS_UNKNOWN (0xff) + +#define BATTERY_FLAGS_HIGH (0x1) +#define BATTERY_FLAGS_LOW (0x2) +#define BATTERY_FLAGS_CRITICAL (0x4) +#define BATTERY_FLAGS_CHARGING (0x8) +#define BATTERY_FLAGS_ABSENT (0x80) + +#define BATTERY_PERCENTAGE_UNKNOWN (-1) + +#define BATTERY_TIME_UNKNOWN (-1) +#endif /* AC_LINE_STATUS_ON */ + diff --git a/wmbattery/autoconf/install-sh b/wmbattery/autoconf/install-sh new file mode 100755 index 0000000..ebc6691 --- /dev/null +++ b/wmbattery/autoconf/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/wmbattery/autoconf/makeinfo.in b/wmbattery/autoconf/makeinfo.in new file mode 100644 index 0000000..abb9ae9 --- /dev/null +++ b/wmbattery/autoconf/makeinfo.in @@ -0,0 +1,21 @@ +# Info for make, this will be preprocessed by autoconf. +bindir = @bindir@ +exec_prefix = @exec_prefix@ +icondir = @datadir@/icons/wmbattery +man1dir = @mandir@/man1 +prefix = @prefix@ +srcdir = @srcdir@ + +CC = @CC@ +CFLAGS = @CFLAGS@ -Wall -DACPI_APM +CPPFLAGS = @CPPFLAGS@ -DICONDIR=\"$(icondir)\" +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ + +#remove hal support +#USE_HAL = 1 + +USE_UPOWER = 1 diff --git a/wmbattery/battery_blink.xpm b/wmbattery/battery_blink.xpm new file mode 100644 index 0000000..28c5ef6 --- /dev/null +++ b/wmbattery/battery_blink.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char * battery_blink_xpm[] = { +"25 13 3 1", +" c #208120812081", +". c #000049244103", +"X c #2081B2CAAEBA", +" ..................... ", +".. .. ", +". . ", +". ... ... X . ", +". . . . . . X X X ...", +". . . . . . X X ...", +". ... ... X ...", +". . . . . . X X ...", +". . . . . . X X X ...", +". ... ... . . ", +". . ", +".. .. ", +" ..................... "}; diff --git a/wmbattery/battery_high.xpm b/wmbattery/battery_high.xpm new file mode 100644 index 0000000..034f8ed --- /dev/null +++ b/wmbattery/battery_high.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char * battery_high_xpm[] = { +"25 13 3 1", +" c #208120812081", +". c #2081B2CAAEBA", +"X c #000049244103", +" ..................... ", +".X X. ", +". . ", +". XXX XXX . . ", +". X X X X X . . . ...", +". X X X X X . . ...", +". XXX XXX . ...", +". X X X X X . . ...", +". X X X X X . . . ...", +". XXX XXX . . ", +". . ", +".X X. ", +" ..................... "}; diff --git a/wmbattery/battery_low.xpm b/wmbattery/battery_low.xpm new file mode 100644 index 0000000..c707a75 --- /dev/null +++ b/wmbattery/battery_low.xpm @@ -0,0 +1,20 @@ +/* XPM */ +static char * battery_low_xpm[] = { +"25 13 4 1", +" c #208120812081", +". c #FFFF00000000", +"X c #000049244103", +"o c #2081B2CAAEBA", +" ..................... ", +".X X. ", +". . ", +". XXX XXX o . ", +". X X X X X o o o ...", +". X X X X X o o ...", +". XXX XXX o ...", +". X X X X X o o ...", +". X X X X X o o o ...", +". XXX XXX o . ", +". . ", +".X X. ", +" ..................... "}; diff --git a/wmbattery/battery_medium.xpm b/wmbattery/battery_medium.xpm new file mode 100644 index 0000000..730f0ac --- /dev/null +++ b/wmbattery/battery_medium.xpm @@ -0,0 +1,20 @@ +/* XPM */ +static char * battery_medium_xpm[] = { +"25 13 4 1", +" c #208120812081", +". c #FFFFFFFF0000", +"X c #000049244103", +"o c #2081B2CAAEBA", +" ..................... ", +".X X. ", +". . ", +". XXX XXX o . ", +". X X X X X o o o ...", +". X X X X X o o ...", +". XXX XXX o ...", +". X X X X X o o ...", +". X X X X X o o o ...", +". XXX XXX o . ", +". . ", +".X X. ", +" ..................... "}; diff --git a/wmbattery/battery_none.xpm b/wmbattery/battery_none.xpm new file mode 100644 index 0000000..d97902f --- /dev/null +++ b/wmbattery/battery_none.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * battery_none_xpm[] = { +"25 13 2 1", +" c #208120812081", +". c #000049244103", +" ..................... ", +".. .. ", +". . ", +". ... ... . . ", +". . . . . . . . . ...", +". . . . . . . . ...", +". ... ... . ...", +". . . . . . . . ...", +". . . . . . . . . ...", +". ... ... . . ", +". . ", +".. .. ", +" ..................... "}; diff --git a/wmbattery/bigfont.xpm b/wmbattery/bigfont.xpm new file mode 100644 index 0000000..7b79a86 --- /dev/null +++ b/wmbattery/bigfont.xpm @@ -0,0 +1,17 @@ +/* XPM */ +static char * bigfont_xpm[] = { +"84 9 5 1", +" c #208120812081", +". c #2081B2CAAEBA", +"X c #000049244103", +"o c #104079E779E7", +"O c #18618A288617", +" .... XXXXo o....O o....o oXXXXo o....o o....O o....o o....O o....O XXXX ", +". . X . X . X . . . . X . X X . . . . . XX X X ", +". . X . X . X . . . . X . X X . . . . . XX X X ", +". . X . X . X . . . . X . X X . . . . . X X ", +"oXXXXo XXXXo o....o o....o o....o o....o o....o XXXXo o....o o....o o....o ", +". . X . . X X . X . X . . . X . . . X . X X ", +". . X . . X X . X . X . . . X . . . X . XX X X ", +". . X . . X X . X . X . . . X . . . X . XX X X ", +" .... XXXXo o....o o....o XXXXo o....o o....o XXXXo o....o o....o XXXX "}; diff --git a/wmbattery/charging.xpm b/wmbattery/charging.xpm new file mode 100644 index 0000000..29c5f40 --- /dev/null +++ b/wmbattery/charging.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char *charging[] = { +/* width height num_colors chars_per_pixel */ +" 15 9 3 1", +/* colors */ +". c #202020", +"# c #004941", +"a c #20b2ae", +/* pixels */ +"........#a.....", +".......#aaa#...", +".......aaa#aa#.", +"......#aa#..#aa", +"......aaa......", +"aa#..#aa#......", +".#aa#aaa.......", +"...#aaa#.......", +"....#a#........" +}; diff --git a/wmbattery/config.h.in b/wmbattery/config.h.in new file mode 100644 index 0000000..dd5a6b3 --- /dev/null +++ b/wmbattery/config.h.in @@ -0,0 +1,9 @@ +#ifndef CONFIG_H +#define CONFIG_H + +/* What system header files can I use? */ +#undef HAVE_GETOPT_H +#undef HAVE_SYS_FILE_H +#undef HAVE_SYS_IOCTL_H + +#endif diff --git a/wmbattery/configure.ac b/wmbattery/configure.ac new file mode 100644 index 0000000..4d2163e --- /dev/null +++ b/wmbattery/configure.ac @@ -0,0 +1,44 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(wmbattery.c) +AC_CONFIG_HEADER(config.h) + +AC_CONFIG_AUX_DIR(autoconf) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL + +dnl Locate X11. +AC_PATH_X +if test "x${no_x}" = "xyes"; then + AC_MSG_ERROR(Can't find X windows include files and libraries) +fi +if test "x${x_includes}" != "x"; then + CPPFLAGS="$CPPFLAGS -I`echo ${x_includes}`" +fi +if test "x${x_libraries}" != "x"; then + LIBS="$LIBS -L`echo ${x_libraries}`" +fi + +dnl Checks for libraries. +AC_CHECK_LIB(X11, XOpenDisplay) +AC_CHECK_LIB(Xext, XShapeCombineMask) +AC_CHECK_LIB(Xpm, XpmReadFileToPixmap) +AC_CHECK_LIB(apm, apm_read) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(X11/xpm.h) +AC_CHECK_HEADERS(X11/extensions/shape.h) +AC_CHECK_HEADERS(getopt.h) +AC_CHECK_HEADERS(apm.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +dnl Checks for library functions. +AC_PROG_GCC_TRADITIONAL +AC_FUNC_VPRINTF +AC_CHECK_FUNCS(strdup) + +AC_OUTPUT(makeinfo:autoconf/makeinfo.in) diff --git a/wmbattery/debian/changelog b/wmbattery/debian/changelog new file mode 100644 index 0000000..eac1b89 --- /dev/null +++ b/wmbattery/debian/changelog @@ -0,0 +1,546 @@ +wmbattery (2.44) unstable; urgency=medium + + * Better AC detection. + * Support times with upower and acpi (Closes: #740885). + * Use the latest upower API (Closes: #748935). + * Fix upower detection. + + -- Andrew Shadura Fri, 18 Jul 2014 01:14:49 +0200 + +wmbattery (2.43) unstable; urgency=low + + * Orphaned the package. It will probably be removed as it does not work with + current kernels. + * Added -i to display as icon. Thanks, Tovar Closes: #732398 + + -- Joey Hess Tue, 27 May 2014 16:01:34 -0400 + +wmbattery (2.42) unstable; urgency=medium + + * Stop building with flash-in-the-pan HAL. Instead update acpi + interface to use /sys/class/power_supply. + Note that this needs acpica_version 20011018. + Closes: #613166 + (Patch developed by Andrew Shadura.) + * Also added support for upower, which is used by default, + to avoid chasing kernel sysfs changes. + (Patch developed by Andrew Shadura.) + Closes: #727102 + + -- Joey Hess Thu, 05 Dec 2013 15:29:41 -0400 + +wmbattery (2.41) unstable; urgency=low + + * Accumulated packaging modernizations. Closes: #666370 + + -- Joey Hess Fri, 30 Mar 2012 10:20:17 -0400 + +wmbattery (2.40) unstable; urgency=low + + * Add -s option which can be used to ignore fluctuations + in reported battery charge (as seen on the EeePC) when + using -e. Closes: #527870 (Joseph Huang) + + -- Joey Hess Sat, 09 May 2009 16:53:10 -0400 + +wmbattery (2.39) unstable; urgency=low + + * Use debhelper v7; rules file minimisation. + * Depend on hal since /proc/acpi is gone from the default kernels now. + Closes: #491099 + + -- Joey Hess Tue, 22 Jul 2008 00:23:47 -0400 + +wmbattery (2.38) unstable; urgency=low + + * Magic header file reordering to work around the disgusting + linux-libc-dev/libc headers conflicts (#435700). Closes: #463811 + + -- Joey Hess Wed, 27 Feb 2008 15:08:53 -0500 + +wmbattery (2.37) unstable; urgency=low + + * Support reconnecting to dbus if it's restarted. (AKA giant dbus-PITA) + + -- Joey Hess Wed, 20 Feb 2008 22:44:00 -0500 + +wmbattery (2.36) unstable; urgency=low + + * Support reconnecting to hal if the connection is closed, as happens + if the hal is restarted. + + -- Joey Hess Wed, 20 Feb 2008 22:29:00 -0500 + +wmbattery (2.35) unstable; urgency=low + + * Don't spew error messages if optional hal properties are not available. + * Only check to see if a battery is charging if hal reports there is AC + power. This is perhaps not 100% correct in systems with multiple batteries + that may cross-charge when off AC, but it's faster and it avoids bugs in + hal (#463740). + + -- Joey Hess Sat, 02 Feb 2008 17:28:37 -0500 + +wmbattery (2.34) unstable; urgency=low + + * Bit the bullet, stopped trying to track the kernel's ever changing + interfaces, and added support for querying battery information from hal. + Support for the old kernel interfaces (APM, ACPI, etc) is still present, + but to use new interfaces such 2.6.24's /sys/class/power_adapter, you'll + have to have dbus and hal. + Closes: #456247, #246641, #290712, #393616, #456248 + * Fix -e option. + + -- Joey Hess Fri, 01 Feb 2008 21:36:39 -0500 + +wmbattery (2.33) unstable; urgency=low + + * Correct issue with the statically allocated string returned by + get_acpi_value that caused it to only look at last full capacity and never + really at design capacity. + + -- Joey Hess Sat, 22 Dec 2007 22:26:38 -0500 + +wmbattery (2.32) unstable; urgency=low + + * Guard some divisions against division by zero. I've never seen that + happen and can't reproduce it, but see #454766. + * Merge acpi change from procmeter3: Limit string length when reading from + /proc/. + + -- Joey Hess Fri, 07 Dec 2007 14:56:41 -0500 + +wmbattery (2.31) unstable; urgency=low + + * Further fix for my strange battery. If the present capacity is larger + than the maximum capacity, rescan to figure out the new max capacity. + + -- Joey Hess Sun, 02 Dec 2007 15:50:29 -0500 + +wmbattery (2.30) unstable; urgency=low + + * My new battery has a design capacity of 7800 mAh and yet its + last full capacity was 9488, and its currently charged to 8540. + Deal with this wonderful miracle^W^Wcrap hardware by taking the max + of the design or last full capacities. + + -- Joey Hess Tue, 23 Oct 2007 22:21:06 -0400 + +wmbattery (2.29) unstable; urgency=low + + * Update to new menu policy. + * The repository has moved from svn to git. + + -- Joey Hess Fri, 19 Oct 2007 21:14:22 -0400 + +wmbattery (2.28) unstable; urgency=low + + * Correct off-by-one in acpi.c + * Put url to new web page in README. + + -- Joey Hess Mon, 04 Jun 2007 16:44:03 -0400 + +wmbattery (2.27) unstable; urgency=low + + * Minor bug fix to acpi code, don't skip over dotfiles. + * Patch from Vincent Bernat adding support for 2.6.21, which changes + yet again where the ACPI version number is stored. Closes: #423612 + + -- Joey Hess Mon, 14 May 2007 14:23:09 -0400 + +wmbattery (2.26) unstable; urgency=medium + + * Add missing build dep on libxt-dev. Closes: #379247 + + -- Joey Hess Tue, 25 Jul 2006 22:00:41 -0400 + +wmbattery (2.25) unstable; urgency=low + + * Merge acpi.c changes for more robust AC power status from sleepd 1.3.0. + + -- Joey Hess Thu, 30 Mar 2006 14:59:31 -0500 + +wmbattery (2.24) unstable; urgency=low + + * Current policy. + * Man page section fix. + * Menu file move. + * GPL update. + * Remove configure script in distclean. + + -- Joey Hess Sun, 18 Dec 2005 17:39:07 -0500 + +wmbattery (2.23) unstable; urgency=low + + * xlibs-dev transition + + -- Joey Hess Fri, 16 Dec 2005 14:54:25 -0500 + +wmbattery (2.22) unstable; urgency=low + + * Fix acpi detection, the code to read /proc/acpi/info was not updated + to the new cd-less code. Closes: #307278 + + -- Joey Hess Mon, 2 May 2005 18:14:01 -0400 + +wmbattery (2.21) unstable; urgency=low + + * Merge in changes from procmeter3's version of acpi.c, made by Andrew M. + Bishop, that avoid the ugly chdir to /proc/acpi and add a bit of error + checking. Now fully synced with procmeter3 3.4d. + + -- Joey Hess Sat, 30 Apr 2005 22:58:44 -0400 + +wmbattery (2.20) unstable; urgency=low + + * Patch from Kris Verbeeck to add a -a option to play an au file + on low battery. + * Document it in the man page. + * Unicode dash fixes on man page. + * Some indentation fixes. + + -- Joey Hess Wed, 24 Nov 2004 16:20:39 -0500 + +wmbattery (2.19) unstable; urgency=low + + * Use the proper new-style acpi string when looking for ac adaptor status. + Closes: #220039 + * Remove the hack I added for my old picturebook, as it causes bad results + on systems that label a fully charged battery's charging rate as + unknown and state as charging. + * Base battery charge calculations for ACPI on design capacity, instead of + last full capacity. Some batteries may exceed previous last full on + their next charging, and this also lets you see when you have a damaged + battery that is not fully charging. + * If acpi battery charging state is unknown, but the rate is 0, + then the battery is charged and on AC power, and the unknown state can + be ignored. Analysis and patch by "TeXitoi". + + -- Joey Hess Mon, 17 Nov 2003 20:28:56 -0500 + +wmbattery (2.18) unstable; urgency=low + + * Sort devices returned by readdir in acpi, since the order can be random. + Closes: #204721 + + -- Joey Hess Wed, 13 Aug 2003 01:45:55 -0400 + +wmbattery (2.17) unstable; urgency=low + + * Make acpi code put -1 in the time remaining field if the "present rate" + is 0. Closes: #204722 + * Enable internal time estimate code in this case. + + -- Joey Hess Mon, 11 Aug 2003 17:21:17 -0400 + +wmbattery (2.16) unstable; urgency=low + + * Another patch from Hugo Haas, this time it adds time-till-charged + estimates for systems that lack them. The estimates are on by default, + though they're only linear guesses and may not be accurate. + * Display dimmed time estimate field if there is no estimate available. + * -e switch renamed to -r and forces both estimates on. + + -- Joey Hess Thu, 7 Aug 2003 16:41:37 -0400 + +wmbattery (2.15) unstable; urgency=low + + * Patch from Hugo Haas to change when the icon is + refreshed for less latency. + * Patch from Hugo Haas to have wmbattery do its own time left estimates + if that info is not available from the machine. + * Add -r switch to force wmbattery to estimate the time left. + + -- Joey Hess Sun, 3 Aug 2003 00:00:09 -0400 + +wmbattery (2.14) unstable; urgency=low + + * Set the cutoff point for old acpi to 20020214 (was 20020208). + Closes: #202083 + + -- Joey Hess Sun, 20 Jul 2003 13:44:59 +0200 + +wmbattery (2.13) unstable; urgency=low + + * Added support for ACPI version 20030109 (2.5 kernel), and generally + support for changing ACPI strings across versions. Closes: #177249 + + -- Joey Hess Thu, 6 Feb 2003 14:50:21 -0500 + +wmbattery (2.12) unstable; urgency=low + + * Rebuild w/o /usr/doc link. + + -- Joey Hess Fri, 15 Nov 2002 15:23:13 -0500 + +wmbattery (2.11) unstable; urgency=low + + * Corrected inverted test to see if ac power is online, that was only called + on 2 battery systems. Closes: #152356 + + -- Joey Hess Wed, 10 Jul 2002 16:10:40 -0400 + +wmbattery (2.10) unstable; urgency=low + + * Deal with acpi putting nothing but "Present: no" in the info file for the + second battery of a thinkpad. This was with kernel 2.4.19-pre10. + Closes: #149715 + * Moved DEB_BUILD_OPTIONS out of makeinfo. + * Updated to new autoconf. + + -- Joey Hess Tue, 11 Jun 2002 22:51:45 -0400 + +wmbattery (2.09) unstable; urgency=low + + * Moved makefile stuff out of makeinfo, so it is just definitions. + * Support DEB_BUILD_OPTIONS. + * debhelper v4. + + -- Joey Hess Sat, 1 Jun 2002 16:31:53 -0400 + +wmbattery (2.08) unstable; urgency=low + + * Don't crash if there is a /proc/acpi/ with no status file. + + -- Joey Hess Fri, 31 May 2002 21:35:06 -0400 + +wmbattery (2.07) unstable; urgency=low + + * Added symbolic apm info constants to "apm.h", in case they are + not in the system . + * Put $(LIBS) last at link time. + + -- Joey Hess Tue, 23 Apr 2002 11:49:16 -0400 + +wmbattery (2.06) unstable; urgency=low + + * Deal with -1 time left from apm (no estimate). + * Never dim colon, fixes display bug. + + -- Joey Hess Mon, 22 Apr 2002 12:30:35 -0400 + +wmbattery (2.05) unstable; urgency=low + + * (acpi) don't display the rather wacky "- :0" on an almost full battery + + -- Joey Hess Tue, 9 Apr 2002 23:19:35 -0400 + +wmbattery (2.04) unstable; urgency=low + + * Work around stupid ACPI output format bug. Critical battery detection + now works. + + -- Joey Hess Mon, 8 Apr 2002 22:49:43 -0400 + +wmbattery (2.03) unstable; urgency=low + + * Better error reporting. + + -- Joey Hess Sun, 7 Apr 2002 22:57:17 -0400 + +wmbattery (2.02) unstable; urgency=medium + + * Improved acpi interface (also used for procmeter3 module now). + * Fixed segfault on non-ACPI systems. + + -- Joey Hess Sun, 7 Apr 2002 17:48:41 -0400 + +wmbattery (2.01) unstable; urgency=low + + * Corrected minus sign in bigfont to proper faux-lcd appearance. Also fixed + offset slightly. + + -- Joey Hess Fri, 5 Apr 2002 23:34:38 -0500 + +wmbattery (2.00) unstable; urgency=low + + * Added ACPI support, including battery change detection, and battery + charging time countdown timer. + * Added -w parameter to configure delay time. + * Added -c and -l parameters to allow user control of battery low/critical + percentages. + * Use constant defs from apm.h instead of nasty hardcoded numbers. + * Made -Wall clean. + * Reorg. + * Removed -s option, just fall back to SPIC if ACPI and APM are not + available. + + -- Joey Hess Fri, 5 Apr 2002 12:53:18 -0500 + +wmbattery (1.23) unstable; urgency=low + + * Added support for querying for battery status via the sonypi driver, for + sony laptops that do not have apm support. This is a stopgap until linux + gets full ACPI support. + + -- Joey Hess Thu, 4 Apr 2002 10:25:31 -0500 + +wmbattery (1.22) unstable; urgency=low + + * Converted to use libapm, instead of the hacked up old version of it + used before. This probably breaks wmbattery on the BSD's, for now. The + correct fix for the BSD's will be to get support for their apm + implementations into libapm. To that end, I have filed a bug with all the + code I ripped out. + * The -f option also had to be removed. If libapm does not work right on + systems that needed that flag it's probably a bug in the library. + * Closes: #100027 + + -- Joey Hess Sun, 24 Feb 2002 12:47:53 -0500 + +wmbattery (1.21) unstable; urgency=low + + * Typo, Closes: #125485 + + -- Joey Hess Mon, 17 Dec 2001 21:41:52 -0500 + +wmbattery (1.20) unstable; urgency=low + + * Still show percent sign when blinking low. Closes: #123183 + + -- Joey Hess Sun, 9 Dec 2001 22:44:17 -0500 + +wmbattery (1.19) unstable; urgency=low + + * Used two more grey's in the transition between shadow and highlight + in the dial. Looks a bit better. + + -- Joey Hess Wed, 7 Nov 2001 22:35:37 -0500 + +wmbattery (1.18) unstable; urgency=low + + * Autoconf 2.50 demands an absolute --mandir= + + -- Joey Hess Thu, 24 May 2001 15:04:23 -0400 + +wmbattery (1.17) unstable; urgency=low + + * Patch from Edward Betts to make the icon redraw + immediatly when it gets an expose event. The patch also lowers the CPU + time used as the icon is not needlessly redrawn every second. Thanks + Edward! Closes: #97779 + * Battery blink fixup. (I seem to have inexplicably lost the changelog + and version involving making the battery blink red on and off when the + status is critical -- I did this recently because the eye tends to + notice the motion). + + -- Joey Hess Thu, 17 May 2001 13:16:55 -0400 + +wmbattery (1.16) unstable; urgency=low + + * Another patch from Kevin, which allows removal of the + config.{sub,guess} files and does smarter detection. + + -- Joey Hess Mon, 5 Mar 2001 19:49:36 -0800 + +wmbattery (1.15) unstable; urgency=medium + + * Fixed icon search path. + + -- Joey Hess Tue, 27 Feb 2001 18:00:44 -0800 + +wmbattery (1.14) unstable; urgency=low + + * OpenBSD port by Kevin Christen + * Uses autoconf. + + -- Joey Hess Mon, 26 Feb 2001 22:06:55 -0800 + +wmbattery (1.13) unstable; urgency=low + + * Added support for using files other than /proc/apm, via a -f switch. + (See bug #69585) + + -- Joey Hess Mon, 21 Aug 2000 11:52:21 -0700 + +wmbattery (1.12) unstable; urgency=low + + * Use /usr/share/icons/wmbattery, not /usr/X11R6/share. Sheesh. + + -- Joey Hess Thu, 6 Apr 2000 13:16:52 -0700 + +wmbattery (1.11) unstable; urgency=low + + * Build deps. + + -- Joey Hess Sat, 4 Dec 1999 16:56:32 -0800 + +wmbattery (1.10) unstable; urgency=low + + * Removed install-stamp target, which can cause obscure problems. + + -- Joey Hess Thu, 30 Sep 1999 13:32:33 -0700 + +wmbattery (1.9) unstable; urgency=low + + * Expanded the man page to detail exactly what all parts of the display + mean. + + -- Joey Hess Mon, 13 Sep 1999 11:37:11 -0700 + +wmbattery (1.8) unstable; urgency=low + + * Integrated with my build system. + + -- Joey Hess Sun, 12 Sep 1999 12:47:00 -0700 + +wmbattery (1.7) unstable; urgency=low + + * FHS. + + -- Joey Hess Mon, 6 Sep 1999 16:57:13 -0700 + +wmbattery (1.6) unstable; urgency=low + + * FreeBSD support, patch from Motoyuki Kasahara . + + -- Joey Hess Sun, 8 Aug 1999 20:04:10 -0700 + +wmbattery (1.5) unstable; urgency=low + + * Built w/o that ugly bug source known as fakeroot. Now all files are + owned by root, not me. + + -- Joey Hess Sun, 8 Aug 1999 17:35:32 -0700 + +wmbattery (1.4) unstable; urgency=low + + * Let's try again on that patch. + + -- Joey Hess Sun, 8 Aug 1999 17:30:18 -0700 + +wmbattery (1.3) unstable; urgency=low + + * Patch from Hugo Haas to allow geometry support. + + -- Joey Hess Sun, 8 Aug 1999 16:18:44 -0700 + +wmbattery (1.2) unstable; urgency=low + + * Patch from Edwin van Ouwerkerk Moria, may make the charging indicator + work better on thinkpads. + + -- Joey Hess Thu, 1 Jul 1999 09:58:04 -0700 + +wmbattery (1.1) unstable; urgency=low + + * Fixed man page location. + + -- Joey Hess Thu, 4 Feb 1999 14:33:58 -0800 + +wmbattery (1.0) unstable; urgency=low + + * First release. + . + * Started with wmapm 1.2 sources. Gutted it and cleaned it up extensively + and turned it into wmbattery. + * Drew new faceplate and graphics. + * Converted manpage to refer to new program name. + * Reorganized source tree. + * Split single xpm up into lots of small xpms, loaded seperately. + * Cleaned up Makefile. + * Removed README, TODO, INSTALL, etc; I'll write my own. + * Parse command line with getopt. + * Made -d work to set the display. + + -- Joey Hess Fri, 25 Dec 1998 18:03:21 -0500 diff --git a/wmbattery/debian/compat b/wmbattery/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/wmbattery/debian/compat @@ -0,0 +1 @@ +9 diff --git a/wmbattery/debian/control b/wmbattery/debian/control new file mode 100644 index 0000000..e80a680 --- /dev/null +++ b/wmbattery/debian/control @@ -0,0 +1,24 @@ +Source: wmbattery +Section: x11 +Priority: extra +Build-Depends: debhelper (>= 9), libxext-dev, libxpm-dev, autoconf, libapm-dev, dpkg-dev (>= 1.9.0), libxt-dev, libupower-glib-dev +Maintainer: Debian QA Group +Standards-Version: 3.9.3 +Vcs-Git: git://git.kitenet.net/wmbattery +Homepage: http://kitenet.net/~joey/code/wmbattery/ + +Package: wmbattery +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, upower +Suggests: wmaker +Description: display laptop battery info, dockable in WindowMaker + wmbattery displays the status of your laptop's battery in a small icon. + This includes if it is plugged in, if the battery is charging, how many + minutes of battery life remain, and battery status (high - green, low - + yellow, or critical - red). + . + There's nothing in the program that makes it require WindowMaker, except + maybe the look. It can be docked in WindowMaker or AfterStep's dock. + . + wmbattery supports multi-battery machines, and can estimate how long + it will take the battery to finish charging or discharging. diff --git a/wmbattery/debian/copyright b/wmbattery/debian/copyright new file mode 100644 index 0000000..94b6057 --- /dev/null +++ b/wmbattery/debian/copyright @@ -0,0 +1,12 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Source: derived from wmapm + +Files: * +Copyright: 1998-2008 Joey Hess + 1998 Chris D. Faulhaber + Martijm Pieterse and + Antoine Nulle +Note: I would also like to thank Anna Hess for artistic guidance. +License: GPL-2 + On Debian systems, the complete text of the GPL can be found in + /usr/share/common-licenses/GPL. diff --git a/wmbattery/debian/docs b/wmbattery/debian/docs new file mode 100644 index 0000000..2bb19c3 --- /dev/null +++ b/wmbattery/debian/docs @@ -0,0 +1,2 @@ +TODO +README diff --git a/wmbattery/debian/menu b/wmbattery/debian/menu new file mode 100644 index 0000000..62d4a19 --- /dev/null +++ b/wmbattery/debian/menu @@ -0,0 +1,2 @@ +?package(wmbattery):needs="x11" section="Applications/System/Monitoring" \ + title="wmbattery" longtitle="wmbattery" command="wmbattery" diff --git a/wmbattery/debian/rules b/wmbattery/debian/rules new file mode 100755 index 0000000..d20e7bc --- /dev/null +++ b/wmbattery/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f +%: + dh $@ + +override_dh_auto_configure: + autoconf + dh_auto_configure + +# Not intended for use by anyone except the author. +announcedir: + @echo ${HOME}/src/joeywiki/code/wmbattery/news diff --git a/wmbattery/dial_bright.xpm b/wmbattery/dial_bright.xpm new file mode 100644 index 0000000..3361348 --- /dev/null +++ b/wmbattery/dial_bright.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * dial_bright_xpm[] = { +"56 31 9 1", +" c #00000000FFFF", +". c #000000000000", +"X c #2081B2CAAEBA", +"o c #FFFFFFFFFFFF", +"O c #38E341034103", +"+ c #C71BC30BC71B", +"@ c #965896589658", +"# c #208120812081", +"$ c #000049244103", +" .......... ", +" ....XXXXXXXXXX.... ", +" ...XXXXXXXXXXXXXXXXXX... ", +" ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", +" .XXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", +" ..XXXXXXXXXXooooooooooXXXXXXXXXX.O ", +" .XXXXXXXXXooo oo+XXXXXXXXXO ", +" .XXXXXXXXoo ++XXXXXXXX@ ", +" .XXXXXXXoo @@XXXXXXX@ ", +" .XXXXXXoo @XXXXXXX+ ", +" .XXXXXXo OOXXXXXX+ ", +" .XXXXXXo OXXXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXo .................................... .XXXXo ", +" .XXXXo .##################################o .XXXXo ", +" .XXXXXo .##$$$$###$$$$#######$$$$###$$$$###o .XXXXXo ", +" .XXXXo .#$####$#$####$##X##$####$#$####$##o .XXXXo ", +" .XXXXo .#$####$#$####$##X##$####$#$####$##o .XXXXXo", +".XXXXXo .#$####$#$####$#####$####$#$####$##o .XXXXXo", +".XXXXo .##$$$$###$$$$#######$$$$###$$$$###o .XXXXo", +".XXXXo .#$####$#$####$#####$####$#$####$##o .XXXXo", +".XXXXo .#$####$#$####$##X##$####$#$####$##o .XXXXo", +".XXXXo .#$####$#$####$##X##$####$#$####$##o .XXXXo", +".XXXXo .##$$$$###$$$$#######$$$$###$$$$###o .XXXXo", +".XXXXo .##################################o .XXXXo", +".XXXXo .##################################o .XXXXo", +".ooooo .ooooooooooooooooooooooooooooooooooo .ooooo"}; diff --git a/wmbattery/dial_dim.xpm b/wmbattery/dial_dim.xpm new file mode 100644 index 0000000..08e6efa --- /dev/null +++ b/wmbattery/dial_dim.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * dial_dim_xpm[] = { +"56 31 9 1", +" c #00000000FFFF", +". c #000000000000", +"X c #000049244103", +"o c #FFFFFFFFFFFF", +"O c #38E341034103", +"+ c #C71BC30BC71B", +"@ c #965896589658", +"# c #208120812081", +"$ c #2081B2CAAEBA", +" .......... ", +" ....XXXXXXXXXX.... ", +" ...XXXXXXXXXXXXXXXXXX... ", +" ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", +" .XXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", +" ..XXXXXXXXXXooooooooooXXXXXXXXXX.. ", +" .XXXXXXXXXooo oooXXXXXXXXXO ", +" .XXXXXXXXoo ++XXXXXXXXO ", +" .XXXXXXXoo @@XXXXXXX@ ", +" .XXXXXXoo @XXXXXXX@ ", +" .XXXXXXo OOXXXXXX+ ", +" .XXXXXXo OXXXXXX+ ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXo .................................... .XXXXo ", +" .XXXXo .##################################o .XXXXo ", +" .XXXXXo .##XXXX###XXXX#######XXXX###XXXX###o .XXXXXo ", +" .XXXXo .#X####X#X####X##$##X####X#X####X##o .XXXXo ", +" .XXXXo .#X####X#X####X##$##X####X#X####X##o .XXXXXo", +".XXXXXo .#X####X#X####X#####X####X#X####X##o .XXXXXo", +".XXXXo .##XXXX###XXXX#######XXXX###XXXX###o .XXXXo", +".XXXXo .#X####X#X####X#####X####X#X####X##o .XXXXo", +".XXXXo .#X####X#X####X##$##X####X#X####X##o .XXXXo", +".XXXXo .#X####X#X####X##$##X####X#X####X##o .XXXXo", +".XXXXo .##XXXX###XXXX#######XXXX###XXXX###o .XXXXo", +".XXXXo .##################################o .XXXXo", +".XXXXo .##################################o .XXXXo", +".ooooo .ooooooooooooooooooooooooooooooooooo .ooooo"}; diff --git a/wmbattery/face.xpm b/wmbattery/face.xpm new file mode 100644 index 0000000..5704fa7 --- /dev/null +++ b/wmbattery/face.xpm @@ -0,0 +1,74 @@ +/* XPM */ +static char * face_xpm[] = { +"64 64 7 1", +" c #00000000FFFF", +". c #000000000000", +"X c #000049244103", +"o c #FFFFFFFFFFFF", +"O c #C71BC30BC71B", +"+ c #965896589658", +"@ c #208120812081", +" ", +" ", +" ", +" ", +" .......... ", +" ....XXXXXXXXXX.... ", +" ...XXXXXXXXXXXXXXXXXX... ", +" ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", +" .XXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", +" ..XXXXXXXXXXooooooooooXXXXXXXXXX.. ", +" .XXXXXXXXXooo ooOXXXXXXXXX. ", +" .XXXXXXXXoo OOXXXXXXXX+ ", +" .XXXXXXXoo ++XXXXXXX+ ", +" .XXXXXXoo +.XXXXXXO ", +" .XXXXXXo .XXXXXXO ", +" .XXXXXXo .XXXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXXo .XXXXXo ", +" .XXXXo .................................... .XXXXo ", +" .XXXXo .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o .XXXXo ", +" .XXXXXo .@@XXXX@@@XXXX@@@@@@@XXXX@@@XXXX@@@o .XXXXXo ", +" .XXXXo .@X@@@@X@X@@@@X@@X@@X@@@@X@X@@@@X@@o .XXXXo ", +" .XXXXo .@X@@@@X@X@@@@X@@X@@X@@@@X@X@@@@X@@o .XXXXXo ", +" .XXXXXo .@X@@@@X@X@@@@X@@@@@X@@@@X@X@@@@X@@o .XXXXXo ", +" .XXXXo .@@XXXX@@@XXXX@@@@@@@XXXX@@@XXXX@@@o .XXXXo ", +" .XXXXo .@X@@@@X@X@@@@X@@@@@X@@@@X@X@@@@X@@o .XXXXo ", +" .XXXXo .@X@@@@X@X@@@@X@@X@@X@@@@X@X@@@@X@@o .XXXXo ", +" .XXXXo .@X@@@@X@X@@@@X@@X@@X@@@@X@X@@@@X@@o .XXXXo ", +" .XXXXo .@@XXXX@@@XXXX@@@@@@@XXXX@@@XXXX@@@o .XXXXo ", +" .XXXXo .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o .XXXXo ", +" .XXXXo .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o .XXXXo ", +" .ooooo .ooooooooooooooooooooooooooooooooooo .ooooo ", +" ", +" ", +" ", +" ", +" ........................................................ ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXXXXXXXXXXX@@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@X@@@@@@X@@@@@@@@@@@@@@@@@@@@@X@@@o ", +" .@@@@@@@@@@@@@@@@@@@@XXX@@@@@X@@@@@@@@@@@@@@@@@@@@@X@@@o ", +" .@@@@@XXXX@@@@@@@@@@XXX@XX@@@X@@@@XXX@@@XXX@@@X@@@@X@@@o ", +" .@@@@X@@@XXX@@@@@@@@XX@@@@XX@X@X@X@@@X@X@@@X@X@X@X@XXX@o ", +" .@@@@X@@@X@@@@@@@@@XXX@@@@@@@X@X@X@@@X@X@@@X@@X@X@@XXX@o ", +" .@@XXX@@@X@@@XX@@@@XX@@@@@@@@X@@@@XXX@@@XXX@@@@X@@@XXX@o ", +" .@X@@X@@@XXX@@@XX@XXX@@@@@@@@X@X@X@@@X@X@@@X@@X@X@@XXX@o ", +" .@X@@@XXXX@@@@@@@XXX@@@@@@@@@X@X@X@@@X@X@@@X@X@X@X@XXX@o ", +" .@X@@@@@@@@@@@@@@@X@@@@@@@@@@X@@@@XXX@@@XXX@@@@@X@@X@@@o ", +" .@X@@@@@@@@@@@@@@@@@@@@@@@@@@X@@@@@@@@@@@@@@@@@@@@@X@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@X@@@@@@@@@@@@@@@@@@@@@X@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXXXXXXXXXXX@@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o ", +" .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@o ", +" .ooooooooooooooooooooooooooooooooooooooooooooooooooooooo ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmbattery/mask.xbm b/wmbattery/mask.xbm new file mode 100644 index 0000000..1722641 --- /dev/null +++ b/wmbattery/mask.xbm @@ -0,0 +1,46 @@ +#define mask_width 64 +#define mask_height 64 +static char mask_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, + 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xff, 0x07, + 0xe0, 0xff, 0x03, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0xff, 0x07, 0x00, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00, + 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xc0, 0x3f, 0x00, + 0x00, 0xfe, 0x01, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, + 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x80, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x01, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, + 0xc0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x03, 0xc0, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xf3, 0x03, 0xe0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x07, + 0xe0, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x07, 0xe0, 0xc7, 0xff, 0xff, + 0xff, 0xff, 0xe3, 0x0f, 0xf0, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x0f, + 0xf0, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0f, 0xf0, 0xc3, 0xff, 0xff, + 0xff, 0xff, 0xc3, 0x0f, 0xf0, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0f, + 0xf0, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0f, 0xf0, 0xc3, 0xff, 0xff, + 0xff, 0xff, 0xc3, 0x0f, 0xf0, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0f, + 0xf0, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x0f, 0xf0, 0xc3, 0xff, 0xff, + 0xff, 0xff, 0xc3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; diff --git a/wmbattery/nocharging.xpm b/wmbattery/nocharging.xpm new file mode 100644 index 0000000..29c8838 --- /dev/null +++ b/wmbattery/nocharging.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char *nocharging[] = { +/* width height num_colors chars_per_pixel */ +" 15 9 2 1", +/* colors */ +". c #202020", +"# c #004941", +/* pixels */ +".........#.....", +"........###....", +".......###.##..", +".......##....##", +"......###......", +"##....##.......", +"..##.###.......", +"....###........", +".....#........." +}; diff --git a/wmbattery/plugged.xpm b/wmbattery/plugged.xpm new file mode 100644 index 0000000..e62a263 --- /dev/null +++ b/wmbattery/plugged.xpm @@ -0,0 +1,17 @@ +/* XPM */ +static char *plugged[] = { +/* width height num_colors chars_per_pixel */ +" 10 8 2 1", +/* colors */ +". c #202020", +"# c #20b2ae", +/* pixels */ +"....####..", +"...#...###", +"...#...#..", +".###...#..", +"#..#...###", +"#...####..", +"#.........", +"#........." +}; diff --git a/wmbattery/simplehal.c b/wmbattery/simplehal.c new file mode 100644 index 0000000..f6379cd --- /dev/null +++ b/wmbattery/simplehal.c @@ -0,0 +1,223 @@ +/* Not particularly good interface to hal, for programs that used to use + * apm. + */ + +#include +#include +#include +#include +#include +#include "apm.h" + +static DBusConnection *dbus_ctx = NULL; +static LibHalContext *hal_ctx = NULL; + +int num_ac_adapters = 0; +int num_batteries = 0; +char **ac_adapters = NULL; +char **batteries = NULL; + +int connect_hal (void) { + DBusError error; + + dbus_error_init(&error); + dbus_ctx = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (dbus_ctx == NULL) { + fprintf(stderr, "error: dbus_bus_get: %s: %s\n", + error.name, error.message); + LIBHAL_FREE_DBUS_ERROR(&error); + return 0; + } + if ((hal_ctx = libhal_ctx_new()) == NULL) { + fprintf(stderr, "error: libhal_ctx_new\n"); + LIBHAL_FREE_DBUS_ERROR(&error); + return 0; + } + if (!libhal_ctx_set_dbus_connection(hal_ctx, dbus_ctx)) { + fprintf(stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", + error.name, error.message); + LIBHAL_FREE_DBUS_ERROR(&error); + return 0; + } + if (!libhal_ctx_init(hal_ctx, &error)) { + if (dbus_error_is_set(&error)) { + fprintf(stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message); + LIBHAL_FREE_DBUS_ERROR(&error); + } + fprintf(stderr, "Could not initialise connection to hald.\n" + "Normally this means the HAL daemon (hald) is not running or not ready.\n"); + return 0; + } + + return 1; +} + +int hal_ready (void) { + if (hal_ctx && dbus_connection_get_is_connected(dbus_ctx)) { + return 1; + } + else { + /* The messy business of reconnecting. + * dbus's design is crap when it comes to reconnecting. + * If dbus is down, can't actually close the connection to hal, + * since libhal wants to use dbus to do it. */ + if (dbus_ctx) { + dbus_connection_close(dbus_ctx); + dbus_connection_unref(dbus_ctx); + } + dbus_ctx = NULL; + hal_ctx = NULL; + + return connect_hal(); + } +} + +signed int get_hal_int (const char *udi, const char *key, int optional) { + int ret; + DBusError error; + + if (! hal_ready()) { + return -1; + } + + dbus_error_init(&error); + + ret = libhal_device_get_property_int (hal_ctx, udi, key, &error); + + if (! dbus_error_is_set (&error)) { + return ret; + } + else { + if (! optional) { + fprintf(stderr, "error: libhal_device_get_property_int: %s: %s\n", + error.name, error.message); + } + dbus_error_free (&error); + return -1; + } +} + +signed int get_hal_bool (const char *udi, const char *key, int optional) { + int ret; + DBusError error; + + if (! hal_ready()) { + return -1; + } + + dbus_error_init(&error); + + ret = libhal_device_get_property_bool (hal_ctx, udi, key, &error); + + if (! dbus_error_is_set (&error)) { + return ret; + } + else { + if (! optional) { + fprintf(stderr, "error: libhal_device_get_property_bool: %s: %s\n", + error.name, error.message); + } + dbus_error_free (&error); + return -1; + } +} + +void find_devices (void) { + DBusError error; + + dbus_error_init(&error); + + if (ac_adapters) + libhal_free_string_array(ac_adapters); + ac_adapters = libhal_find_device_by_capability(hal_ctx, "ac_adapter", + &num_ac_adapters, &error); + if (dbus_error_is_set (&error)) { + fprintf (stderr, "error: %s: %s\n", error.name, error.message); + LIBHAL_FREE_DBUS_ERROR (&error); + } + + if (batteries) + libhal_free_string_array(batteries); + batteries = libhal_find_device_by_capability(hal_ctx, "battery", + &num_batteries, &error); + if (dbus_error_is_set (&error)) { + fprintf (stderr, "error: %s: %s\n", error.name, error.message); + LIBHAL_FREE_DBUS_ERROR (&error); + } +} + +int simplehal_supported (void) { + if (! connect_hal()) { + return 0; + } + else { + find_devices(); + return 1; + } +} + +/* Fill the passed apm_info struct. */ +int simplehal_read (int battery, apm_info *info) { + char *device; + int i; + + /* Allow a battery that was not present before to appear. */ + if (battery > num_batteries) { + find_devices(); + } + + info->battery_flags = 0; + info->using_minutes = 0; + + info->ac_line_status=0; + for (i = 0 ; i < num_ac_adapters && ! info->ac_line_status ; i++) { + info->ac_line_status = (get_hal_bool(ac_adapters[i], "ac_adapter.present", 0) == 1); + } + + if (battery > num_batteries) { + info->battery_percentage = 0; + info->battery_time = 0; + info->battery_status = BATTERY_STATUS_ABSENT; + return 0; + } + else { + device=batteries[battery-1]; + } + + if (get_hal_bool(device, "battery.present", 0) != 1) { + info->battery_percentage = 0; + info->battery_time = 0; + info->battery_status = BATTERY_STATUS_ABSENT; + return 0; + } + + /* remaining_time and charge_level.percentage are not a mandatory + * keys, so if not present, -1 will be returned */ + info->battery_time = get_hal_int(device, "battery.remaining_time", 1); + info->battery_percentage = get_hal_int(device, "battery.charge_level.percentage", 1); + if (get_hal_bool(device, "battery.rechargeable.is_discharging", 0) == 1) { + info->battery_status = BATTERY_STATUS_CHARGING; + /* charge_level.warning and charge_level.low are not + * required to be available; this is good enough */ + if (info->battery_percentage < 1) { + info->battery_status = BATTERY_STATUS_CRITICAL; + } + else if (info->battery_percentage < 10) { + info->battery_status = BATTERY_STATUS_LOW; + } + } + else if (info->ac_line_status && + get_hal_bool(device, "battery.rechargeable.is_charging", 0) == 1) { + info->battery_status = BATTERY_STATUS_CHARGING; + info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING; + } + else if (info->ac_line_status) { + /* Must be fully charged. */ + info->battery_status = BATTERY_STATUS_HIGH; + } + else { + fprintf(stderr, "unknown battery state\n"); + } + + return 0; +} diff --git a/wmbattery/simplehal.h b/wmbattery/simplehal.h new file mode 100644 index 0000000..1f4cd2a --- /dev/null +++ b/wmbattery/simplehal.h @@ -0,0 +1,2 @@ +int simplehal_supported (void); +int simplehal_read (int battery, apm_info *info); diff --git a/wmbattery/smallfont.xpm b/wmbattery/smallfont.xpm new file mode 100644 index 0000000..52077af --- /dev/null +++ b/wmbattery/smallfont.xpm @@ -0,0 +1,16 @@ +/* XPM */ +static char * smallfont_xpm[] = { +"67 7 6 1", +" c #208120812081", +". c #2081B2CAAEBA", +"X c #000049244103", +"o c #18618A288617", +"O c #000079E771C6", +"+ c #104079E779E7", +" ... XXXo o...o o...o oXXXo o...o o...o o...o o...o o...o X o", +". . X . X . X . . . . X . X X . . . . . X X X .", +". . X . X . X . . . . X . X X . . . . . X X .", +"oXXXo XXXo o...o ...o o...o O...o o...o XXXo o...o +...o X o", +". . X . . X X . X . X . . . X . . . X . X X .", +". . X . . X X . X . X . . . X . . . X . X X X .", +" ... XXX. o...o o...o XXXo o...o o...o XXXO o...o o...o X ."}; diff --git a/wmbattery/sonypi.c b/wmbattery/sonypi.c new file mode 100644 index 0000000..71ff9b1 --- /dev/null +++ b/wmbattery/sonypi.c @@ -0,0 +1,74 @@ +#include +#include +#include "apm.h" +#include +#include +#include + +#include "sonypi.h" + +signed int spicfd = -1; + +int sonypi_supported (void) { + if ((spicfd = open("/dev/sonypi", O_RDWR)) == -1) + return 0; + else + return 1; +} + +inline int sonypi_ioctl(int ioctlno, void *param) { + if (ioctl(spicfd, ioctlno, param) < 0) + return 0; + else + return 1; +} + +/* Read battery info from sonypi device and shove it into an apm_info + * struct. */ +int sonypi_read (apm_info *info) { + __u8 batflags; + __u16 cap, rem; + int havebatt = 0; + + info->using_minutes = info->battery_flags = 0; + + if (! sonypi_ioctl(SONYPI_IOCGBATFLAGS, &batflags)) { + return 1; + } + + info->ac_line_status = (batflags & SONYPI_BFLAGS_AC) != 0; + if (batflags & SONYPI_BFLAGS_B1) { + if (! sonypi_ioctl(SONYPI_IOCGBAT1CAP, &cap)) + return 1; + if (! sonypi_ioctl(SONYPI_IOCGBAT1REM, &rem)) + return 1; + havebatt = 1; + } + else if (batflags & SONYPI_BFLAGS_B2) { + /* Not quite right, if there is a second battery I should + * probably merge the two somehow.. */ + if (! sonypi_ioctl(SONYPI_IOCGBAT2CAP, &cap)) + return 1; + if (! sonypi_ioctl(SONYPI_IOCGBAT2REM, &rem)) + return 1; + havebatt = 1; + } + else { + info->battery_percentage = 0; + info->battery_status = BATTERY_STATUS_ABSENT; + } + + if (havebatt) { + info->battery_percentage = 100 * rem / cap; + /* Guess at whether the battery is charging. */ + if (info->battery_percentage < 99 && info->ac_line_status == 1) { + info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING; + info->battery_status = BATTERY_STATUS_CHARGING; + } + } + + /* Sadly, there is no way to estimate this. */ + info->battery_time = 0; + + return 0; +} diff --git a/wmbattery/sonypi.h b/wmbattery/sonypi.h new file mode 100644 index 0000000..03650af --- /dev/null +++ b/wmbattery/sonypi.h @@ -0,0 +1,19 @@ +int sonypi_supported (void); +int sonypi_read (apm_info *info); + +/* There's no good place to get these constants, so I must define them + * myself. */ + +#include + +/* get battery full capacity/remaining capacity */ +#define SONYPI_IOCGBAT1CAP _IOR('v', 2, __u16) +#define SONYPI_IOCGBAT1REM _IOR('v', 3, __u16) +#define SONYPI_IOCGBAT2CAP _IOR('v', 4, __u16) +#define SONYPI_IOCGBAT2REM _IOR('v', 5, __u16) + +/* get battery flags: battery1/battery2/ac adapter present */ +#define SONYPI_BFLAGS_B1 0x01 +#define SONYPI_BFLAGS_B2 0x02 +#define SONYPI_BFLAGS_AC 0x04 +#define SONYPI_IOCGBATFLAGS _IOR('v', 7, __u8) diff --git a/wmbattery/unplugged.xpm b/wmbattery/unplugged.xpm new file mode 100644 index 0000000..7b74879 --- /dev/null +++ b/wmbattery/unplugged.xpm @@ -0,0 +1,17 @@ +/* XPM */ +static char *unplugged[] = { +/* width height num_colors chars_per_pixel */ +" 10 8 2 1", +/* colors */ +". c #202020", +"# c #004941", +/* pixels */ +"....####..", +"...#...###", +"...#...#..", +".###...#..", +"#..#...###", +"#...####..", +"#.........", +"#........." +}; diff --git a/wmbattery/upower.c b/wmbattery/upower.c new file mode 100644 index 0000000..0890908 --- /dev/null +++ b/wmbattery/upower.c @@ -0,0 +1,151 @@ +/* Not particularly good interface to hal, for programs that used to use + * apm. + */ + +#include +#include +#include +#include +#include +#include "apm.h" + +int num_batteries = 0; + +struct context { + int current; + int needed; + guint state; + int percentage; + gboolean ac; + int time; +}; + +static void get_devinfo(gpointer device, gpointer result) +{ + gboolean online; + gdouble percentage; + guint state; + guint kind; + gint64 time_to_empty; + gint64 time_to_full; + struct context * ctx = result; + + g_object_get(G_OBJECT(device), "percentage", &percentage, + "online", &online, + "state", &state, + "kind", &kind, + "time-to-empty", &time_to_empty, + "time-to-full", &time_to_full, + NULL); + if (kind == UP_DEVICE_KIND_BATTERY) { + if (ctx->current == ctx->needed) { + ctx->percentage = (int)percentage; + ctx->state = state; + if (time_to_empty) { + ctx->time = time_to_empty; + } else { + ctx->time = time_to_full; + } + } + ctx->current++; + } else if (kind == UP_DEVICE_KIND_LINE_POWER) { + ctx->ac |= online; + } +} + +int upower_supported (void) { + UpClient * up; + up = up_client_new(); + + if (!up) { + return 0; + } + else { + GPtrArray * devices = up_client_get_devices(up); + + if (!devices) { + g_object_unref(up); + return 0; + } else { + g_ptr_array_unref(devices); + g_object_unref(up); + return 1; + } + } +} + +/* Fill the passed apm_info struct. */ +int upower_read(int battery, apm_info *info) { + UpClient * up; + GPtrArray * devices = NULL; + + up = up_client_new(); + + if (!up) { + return -1; + } + + #if !UP_CHECK_VERSION(0, 9, 99) + /* Allow a battery that was not present before to appear. */ + up_client_enumerate_devices_sync(up, NULL, NULL); + #endif + + devices = up_client_get_devices(up); + + if (!devices) { + return -1; + } + + info->battery_flags = 0; + info->using_minutes = 0; + + struct context ctx = { + .current = 0, + .needed = battery - 1, + .state = UP_DEVICE_STATE_UNKNOWN, + .percentage = -1, + .ac = FALSE, + .time = -1 + }; + + g_ptr_array_foreach(devices, &get_devinfo, &ctx); + + info->ac_line_status = ctx.ac; + + /* remaining_time and charge_level.percentage are not a mandatory + * keys, so if not present, -1 will be returned */ + info->battery_time = ctx.time; + info->battery_percentage = ctx.percentage; + if (ctx.state == UP_DEVICE_STATE_DISCHARGING) { + info->battery_status = BATTERY_STATUS_CHARGING; + /* charge_level.warning and charge_level.low are not + * required to be available; this is good enough */ + if (info->battery_percentage < 1) { + info->battery_status = BATTERY_STATUS_CRITICAL; + } + else if (info->battery_percentage < 10) { + info->battery_status = BATTERY_STATUS_LOW; + } + } + else if (info->ac_line_status && ctx.state == UP_DEVICE_STATE_CHARGING) { + info->battery_status = BATTERY_STATUS_CHARGING; + info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING; + } + else if (info->ac_line_status) { + /* Must be fully charged. */ + info->battery_status = BATTERY_STATUS_HIGH; + } + else { + fprintf(stderr, "unknown battery state\n"); + } + + if (ctx.percentage < 0) { + info->battery_percentage = 0; + info->battery_time = 0; + info->battery_status = BATTERY_STATUS_ABSENT; + } + + g_ptr_array_free(devices, TRUE); + g_object_unref(up); + return 0; +} diff --git a/wmbattery/upower.h b/wmbattery/upower.h new file mode 100644 index 0000000..94c5eb6 --- /dev/null +++ b/wmbattery/upower.h @@ -0,0 +1,2 @@ +int upower_supported(void); +int upower_read(int battery, apm_info *info); diff --git a/wmbattery/wmbattery.1x b/wmbattery/wmbattery.1x new file mode 100644 index 0000000..c2bb88c --- /dev/null +++ b/wmbattery/wmbattery.1x @@ -0,0 +1,110 @@ +.TH WMBATTERY 1x +.SH NAME +wmbattery \- dockable battery monitor +.SH SYNOPSIS +.B wmbattery +[options] +.SH DESCRIPTION +.PP +.B wmbattery +is a battery monitor. It is used to visually display the system's battery +status. +.PP +.B wmbattery +can get battery information using upower, HAL, APM, ACPI, or +the SPIC controller in some Sony laptops. +.B wmbattery +is dockable using WindowMaker and AfterStep window managers; under +other window managers +.B wmbattery +appears as a nicely-sized 64x64 application. +.PP +.B wmbattery +displays the status of your laptop's battery in a small icon. This +includes if it is plugged in, if the battery is charging, how many +minutes of battery life remain, battery life remaining (with both a +percentage and a graph), and battery status (high - green, low - +yellow, or critical - red). +.SH "ELEMENTS OF THE DISPLAY" +The +.B wmbattery +display consists of these elements: +.TP +.B dial +The large dial at the top of the display shows battery life remaining. +.TP +.B time display +The time display, right under and in the middle of the dial, shows how +many hours and minutes of battery life is estimated to remain at the +current rate of use. +.P +.RS +If ACPI is used and battery is charging, the time display will instead show +a countdown (starting with a minus sign) of how many hours and minutes it is +estimated to take until the battery is fully charged. +.RE +.TP +.B power cord +The small icon of a power cord plug, in the bottom left, tells if the +laptop is plugged into wall power. If so, it will be lit. +.TP +.B charging indicator +The lightning bolt icon, to the right of the plug, tells if the +battery is being charged. If so it will be lit and will connect the +plug to the battery. +.TP +.B battery icon +The battery icon, to the right of the lighting bolt, shows the +percentage of battery time. If the battery is removed the icon will be +dimmed. If the computer is low on power the battery will turn yellow; +if the computer is critically low on power and about to die because of +it, it will turn red. +.SH OPTIONS +.TP +.B \-h +Display list of command-line options. +.TP +.B \-w secs +Pause this many seconds between updates. +.TP +.B \-d display +Use the designated X display. +.TP +.B \-g +x+y +Specify geometry. This specifies position, not size. +.TP +.B \-b battnum +Display the given battery. Only of use with the HAL or ACPI interfaces on +systems with more than one battery. The default is to display the first +battery found. +.TP +.B \-l percent +Set the percentage at which the battery is considered to be running low. By +default, this percentage is determined automaticall, and you shouldn't +need to set it. If you set this, you should probably also set the \-c +switch. +.TP +.B \-c percent +Set the percentage at which the battery is considered to be critically low. +By default, this percentage is determined automatically, and you shouldn't +need to set it. If you set this, you should probably also set the \-l +switch. +.TP +.B \-e +wmbattery contains code for estimating the time remaining before discharge, +and until full charge, and this code is used if no other source of this +informaton is available. This switch makes wmbattery use its time +estimation code even if some other estimate is available. +.TP +.B \-s granularity +Ignore fluctuations less than the specified granularity percent when +estimating time. (Implies -e) +.TP +.B \-a file.au +Play the specified au file (by sending it to /dev/audio) when the battery +is low. +.TP +.B \-i +Display as icon. +.SH AUTHOR +Joey Hess diff --git a/wmbattery/wmbattery.c b/wmbattery/wmbattery.c new file mode 100644 index 0000000..91b98b8 --- /dev/null +++ b/wmbattery/wmbattery.c @@ -0,0 +1,653 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_GETOPT_H +#include +#endif + +#include "wmbattery.h" +#include "mask.xbm" +#include "sonypi.h" +#include "acpi.h" +#ifdef HAL +#include "simplehal.h" +#endif +#ifdef UPOWER +#include "upower.h" +#endif + +Pixmap images[NUM_IMAGES]; +Window root, iconwin, win; +int screen; +XpmIcon icon; +Display *display; +GC NormalGC; +int pos[2] = {0, 0}; + +char *crit_audio_fn = NULL; +char *crit_audio; +int crit_audio_size; + +int battnum = 1; +#ifdef HAL +int use_simplehal = 0; +#endif +#ifdef UPOWER +int use_upower = 0; +#endif +int use_sonypi = 0; +int use_acpi = 0; +int delay = 0; +int always_estimate_remaining = 0; +int granularity_estimate_remaining = 1; +int initial_state = WithdrawnState; + +signed int low_pct = -1; +signed int critical_pct = -1; + +void error(const char *fmt, ...) { + va_list arglist; + + va_start(arglist, fmt); + fprintf(stderr, "Error: "); + vfprintf(stderr, fmt, arglist); + fprintf(stderr, "\n"); + va_end(arglist); + + exit(1); +} + +int apm_change(apm_info *cur) { + static int ac_line_status = 0, battery_status = 0, battery_flags = 0, + battery_percentage = 0, battery_time = 0, using_minutes = 0; + + int i = cur->ac_line_status == ac_line_status && + cur->battery_status == battery_status && + cur->battery_flags == battery_flags && + cur->battery_percentage == battery_percentage && + cur->battery_time == battery_time && + cur->using_minutes == using_minutes; + + ac_line_status = cur->ac_line_status; + battery_status = cur->battery_status; + battery_flags = cur->battery_flags; + battery_percentage = cur->battery_percentage; + battery_time = cur->battery_time; + using_minutes = cur->using_minutes; + + return i; +} + +/* Calculate battery estimate */ +void estimate_timeleft(apm_info *cur_info) { + /* Time of the last estimate */ + static time_t estimate_time = 0; + /* Estimated time left */ + static time_t estimate = 0; + /* Time when we last noticed a battery level change */ + static time_t battery_change_time = 0; + /* The previous estimation we had before the battery level changed */ + static time_t prev_estimate = 0; + /* Percentage at the last estimate */ + static short percent = 0; + /* Where we charging or discharging the last time we were called? */ + static short was_charging = 1; + /* Have we made a guess lately? */ + static short guessed_lately = 0; + + time_t t; + int interval; + short is_charging = cur_info->battery_flags & BATTERY_FLAGS_CHARGING; + + errno = 0; + if (time(&t) == ((time_t)-1) && errno != 0) + goto estim_values; + + if (( + /* AC is on and battery is not charging anymore or ... */ + (cur_info->ac_line_status == AC_LINE_STATUS_ON) && !is_charging + ) || + ( + /* ... the charging state has changed */ + is_charging ^ was_charging + )) { + /* Reset counters */ + battery_change_time = t; + estimate = -1; + guessed_lately = 0; + estimate_time = t; + prev_estimate = 0; + goto estim_values; + } + + /* No change: decrease estimate */ + if ((percent - cur_info->battery_percentage) + / granularity_estimate_remaining == 0) { + estimate -= t - estimate_time; + estimate_time = t; + if (guessed_lately && estimate < 0) + estimate = 0; + goto estim_values; + } + + /* The battery level changed: calculate estimate based + * on change speed and previous estimate */ + guessed_lately = 1; + estimate_time = t; + interval = estimate_time - battery_change_time; + prev_estimate = estimate; + battery_change_time = estimate_time; + estimate = (is_charging + ? (cur_info->battery_percentage - 100) + : cur_info->battery_percentage) + * interval / (percent - cur_info->battery_percentage); + if (prev_estimate > 0) + estimate = (estimate * 2 + prev_estimate) / 3; + +estim_values: + percent = cur_info->battery_percentage; + was_charging = is_charging; + cur_info->battery_time = estimate; + if (estimate < 0) + estimate = 0; + cur_info->using_minutes = 0; +} + +/* Load up the images this program uses. */ +void load_images() { + int x; + char fn[128]; /* enough? */ + + for(x=0; x < NUM_IMAGES; x++) { + sprintf(fn, "%s/%s.xpm", ICONDIR, image_info[x].filename); + if (XpmReadFileToPixmap(display, root, fn, &images[x], NULL, NULL)) { + /* Check in current direcotry for fallback. */ + sprintf(fn, "%s.xpm", image_info[x].filename); + if (XpmReadFileToPixmap(display, root, fn, &images[x], NULL, NULL)) { + error("Failed to load %s\n",fn); + } + } + } +} + +void load_audio() { + int fd; + struct stat s; + + crit_audio = NULL; + if (crit_audio_fn == NULL) { + return; + } + fd = open(crit_audio_fn, 0); + if (fd == -1) { + error("unable to open audio file"); + } + if (fstat(fd, &s) == 0) { + crit_audio_size = s.st_size; + crit_audio = malloc(crit_audio_size); + /* XXX: make this more robust? (loop?) */ + if (read(fd, crit_audio, crit_audio_size) != crit_audio_size) { + free(crit_audio); + crit_audio = NULL; + error("unable to read audio file"); + } + } + close(fd); +} + +/* Returns the display to run on (or NULL for default). */ +char *parse_commandline(int argc, char *argv[]) { + int c=0; + char *ret=NULL; + char *s; + extern char *optarg; + + while (c != -1) { + c=getopt(argc, argv, "hd:g:if:b:w:c:l:es:a:"); + switch (c) { + case 'h': + printf("Usage: wmbattery [options]\n"); + printf("\t-d \tselects target display\n"); + printf("\t-h\t\tdisplay this help\n"); + printf("\t-g +x+y\t\tposition of the window\n"); + printf("\t-i start \n"); + printf("\t-b num\t\tnumber of battery to display\n"); + printf("\t-w secs\t\tseconds between updates\n"); + printf("\t-l percent\tlow percentage\n"); + printf("\t-c percent\tcritical percentage\n"); + printf("\t-e\t\tuse own time estimates\n"); + printf("\t-s granularity\tignore fluctuations less than granularity%% (implies -e)\n"); + printf("\t-a file\t\twhen critical send file to /dev/audio\n"); + exit(0); + break; + case 'd': + ret=strdup(optarg); + break; + case 'g': + s = strtok(optarg, "+"); + if (s) { + pos[0]=atoi(s); + if ((s = strtok(NULL, "+")) != NULL) { + pos[1]=atoi(s); + } + else { + pos[0]=0; + } + } + break; + case 'i': + initial_state = IconicState; + break; + case 'b': + battnum = atoi(optarg); + break; + case 'w': + delay = atoi(optarg); + break; + case 'l': + low_pct = atoi(optarg); + break; + case 'c': + critical_pct = atoi(optarg); + break; + case 'e': + always_estimate_remaining = 1; + break; + case 's': + always_estimate_remaining = 1; + granularity_estimate_remaining = atoi(optarg); + break; + case 'a': + crit_audio_fn = strdup(optarg); + break; + } + } + + return ret; +} + +/* Sets up the window and icon and all the nasty X stuff. */ +void make_window(char *display_name, int argc, char *argv[]) { + XClassHint classhint; + char *wname = argv[0]; + XTextProperty name; + XGCValues gcv; + int dummy=0, borderwidth = 1; + XSizeHints sizehints; + XWMHints wmhints; + Pixel back_pix, fore_pix; + Pixmap pixmask; + + if (!(display = XOpenDisplay(display_name))) + error("can't open display %s",XDisplayName(display_name)); + + screen=DefaultScreen(display); + root=RootWindow(display, screen); + + /* Create window. */ + sizehints.flags = USSize | USPosition; + sizehints.x = 0; + sizehints.y = 0; + XWMGeometry(display, screen, "", NULL, borderwidth, + &sizehints, &sizehints.x, &sizehints.y, + &sizehints.width, &sizehints.height, &dummy); + + sizehints.width = 64; + sizehints.height = 64; + sizehints.x = pos[0]; + sizehints.y = pos[1]; + back_pix = WhitePixel(display, screen); + fore_pix = BlackPixel(display, screen); + win = XCreateSimpleWindow(display, root, sizehints.x, sizehints.y, + sizehints.width, sizehints.height, + borderwidth, fore_pix, back_pix); + iconwin = XCreateSimpleWindow(display, win, sizehints.x, + sizehints.y, sizehints.width, + sizehints.height, borderwidth, + fore_pix, back_pix); + + /* Activate hints */ + XSetWMNormalHints(display, win, &sizehints); + classhint.res_name = wname; + classhint.res_class = wname; + XSetClassHint(display, win, &classhint); + + if (! XStringListToTextProperty(&wname, 1, &name)) + error("Can't allocate window name."); + + XSetWMName(display, win, &name); + + /* Create GC for drawing */ + gcv.foreground = fore_pix; + gcv.background = back_pix; + gcv.graphics_exposures = 0; + NormalGC = XCreateGC(display, root, + GCForeground | GCBackground | GCGraphicsExposures, + &gcv); + + pixmask = XCreateBitmapFromData(display, win, mask_bits, + mask_width,mask_height); + XShapeCombineMask(display, win, ShapeBounding, 0, 0, + pixmask, ShapeSet); + XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, + pixmask, ShapeSet); + + wmhints.initial_state = initial_state; + wmhints.icon_window = iconwin; + wmhints.icon_x = sizehints.x; + wmhints.icon_y = sizehints.y; + wmhints.window_group = win; + wmhints.flags = StateHint | IconWindowHint | + IconPositionHint | WindowGroupHint; + + XSetWMHints(display, win, &wmhints); + XSetCommand(display, win, argv, argc); + + XSelectInput(display, iconwin, ExposureMask); + XSelectInput(display, win, ExposureMask); + + XMapWindow(display, win); +} + +void flush_expose(Window w) { + XEvent dummy; + + while (XCheckTypedWindowEvent(display, w, Expose, &dummy)); +} + +void redraw_window() { + XCopyArea(display, images[FACE], iconwin, NormalGC, 0, 0, + image_info[FACE].width, image_info[FACE].height, 0,0); + flush_expose(iconwin); + XCopyArea(display, images[FACE], win, NormalGC, 0, 0, + image_info[FACE].width, image_info[FACE].height, 0,0); + flush_expose(win); +} + +/* + * Display an image, using XCopyArea. Can display only part of an image, + * located anywhere. + */ +void copy_image(int image, int xoffset, int yoffset, + int width, int height, int x, int y) { + XCopyArea(display, images[image], images[FACE], NormalGC, + xoffset, yoffset, width, height, x, y); +} + +/* + * Display a letter in one of two fonts, at the specified x position. + * Note that 10 is passed for special characters `:' or `1' at the + * end of the font. + */ +void draw_letter(int letter, int font, int x) { + copy_image(font, image_info[font].charwidth * letter, 0, + image_info[font].charwidth, image_info[font].height, + x, image_info[font].y); +} + +/* Display an image at its normal location. */ +void draw_image(int image) { + copy_image(image, 0, 0, + image_info[image].width, image_info[image].height, + image_info[image].x, image_info[image].y); +} + +void recalc_window(apm_info cur_info) { + int time_left, hour_left, min_left, digit, x; + static int blinked = 0; + + /* Display if it's plugged in. */ + switch (cur_info.ac_line_status) { + case AC_LINE_STATUS_ON: + draw_image(PLUGGED); + break; + default: + draw_image(UNPLUGGED); + } + + /* Display the appropriate color battery. */ + switch (cur_info.battery_status) { + case BATTERY_STATUS_HIGH: + case BATTERY_STATUS_CHARGING: + draw_image(BATTERY_HIGH); + break; + case BATTERY_STATUS_LOW: + draw_image(BATTERY_LOW); + break; + case BATTERY_STATUS_CRITICAL: /* blinking red battery */ + if (blinked) + draw_image(BATTERY_CRITICAL); + else + draw_image(BATTERY_BLINK); + blinked=!blinked; + break; + default: + draw_image(BATTERY_NONE); + } + + /* Show if the battery is charging. */ + if (cur_info.battery_flags & BATTERY_FLAGS_CHARGING) { + draw_image(CHARGING); + } + else { + draw_image(NOCHARGING); + } + + /* + * Display the percent left dial. This has the side effect of + * clearing the time left field. + */ + x=DIAL_MULTIPLIER * cur_info.battery_percentage; + if (x >= 0) { + /* Start by displaying bright on the dial. */ + copy_image(DIAL_BRIGHT, 0, 0, + x, image_info[DIAL_BRIGHT].height, + image_info[DIAL_BRIGHT].x, + image_info[DIAL_BRIGHT].y); + } + /* Now display dim on the remainder of the dial. */ + copy_image(DIAL_DIM, x, 0, + image_info[DIAL_DIM].width - x, + image_info[DIAL_DIM].height, + image_info[DIAL_DIM].x + x, + image_info[DIAL_DIM].y); + + /* Show percent remaining */ + if (cur_info.battery_percentage >= 0) { + digit = cur_info.battery_percentage / 10; + if (digit == 10) { + /* 11 is the `1' for the hundreds place. */ + draw_letter(11,SMALLFONT,HUNDREDS_OFFSET); + digit=0; + } + draw_letter(digit,SMALLFONT,TENS_OFFSET); + digit = cur_info.battery_percentage % 10; + draw_letter(digit,SMALLFONT,ONES_OFFSET); + } + else { + /* There is no battery, so we need to dim out the + * percent sign that is normally bright. */ + draw_letter(10,SMALLFONT,PERCENT_OFFSET); + } + + /* Show time left */ + + /* A negative number means that it is unknown. Dim the field. */ + if (cur_info.battery_time < 0) { + draw_letter(10, BIGFONT, COLON_OFFSET); + redraw_window(); + return; + } + + if (cur_info.using_minutes) + time_left = cur_info.battery_time; + else + time_left = cur_info.battery_time / 60; + hour_left = time_left / 60; + min_left = time_left % 60; + digit = hour_left / 10; + draw_letter(digit,BIGFONT,HOURS_TENS_OFFSET); + digit = hour_left % 10; + draw_letter(digit,BIGFONT,HOURS_ONES_OFFSET); + digit = min_left / 10; + draw_letter(digit,BIGFONT,MINUTES_TENS_OFFSET); + digit = min_left % 10; + draw_letter(digit,BIGFONT,MINUTES_ONES_OFFSET); + + redraw_window(); +} + +void snd_crit() { + int audio, n; + + if (crit_audio) { + audio = open("/dev/audio", O_WRONLY); + if (audio >= 0) { + n = write(audio, crit_audio, crit_audio_size); + if (n != crit_audio_size) { + fprintf(stderr, "write failed (%d/%d bytes)\n", n, crit_audio_size); + } + close(audio); + } + } +} + +void alarmhandler(int sig) { + apm_info cur_info; + int old_status; + + old_status = cur_info.battery_status; +#ifdef UPOWER + if (use_upower) { + if (upower_read(1, &cur_info) != 0) + error("Cannot read upower information."); + } + else if (use_acpi) { +#else + if (use_acpi) { +#endif + if (acpi_read(battnum, &cur_info) != 0) + error("Cannot read ACPI information."); + } +#ifdef HAL + else if (use_simplehal) { + if (simplehal_read(battnum, &cur_info) != 0) + error("Cannot read HAL information."); + } +#endif + else if (! use_sonypi) { + if (apm_read(&cur_info) != 0) + error("Cannot read APM information."); + } + else { + if (sonypi_read(&cur_info) != 0) + error("Cannot read sonypi information."); + } + + /* Always calculate remaining lifetime? apm and acpi both use a + * negative number here to indicate error, missing battery, or + * cannot determine time. */ + if (always_estimate_remaining || cur_info.battery_time < 0) + estimate_timeleft(&cur_info); + + /* Override the battery status? */ + if ((low_pct > -1 || critical_pct > -1) && + cur_info.ac_line_status != AC_LINE_STATUS_ON) { + if (cur_info.battery_percentage <= critical_pct) + cur_info.battery_status = BATTERY_STATUS_CRITICAL; + else if (cur_info.battery_percentage <= low_pct) + cur_info.battery_status = BATTERY_STATUS_LOW; + else + cur_info.battery_status = BATTERY_STATUS_HIGH; + } + + /* If APM data changes redraw and wait for next update */ + /* Always redraw if the status is critical, to make it blink. */ + if (!apm_change(&cur_info) || cur_info.battery_status == BATTERY_STATUS_CRITICAL) + recalc_window(cur_info); + + if ((old_status == BATTERY_STATUS_HIGH) && + (cur_info.battery_status == BATTERY_STATUS_LOW)) { + snd_crit(); + } + else if (cur_info.battery_status == BATTERY_STATUS_CRITICAL) { + snd_crit(); + } + + alarm(delay); +} + +void check_battery_num(int real, int requested) { + if (requested > real || requested < 1) { + error("There %s only %i batter%s, and you asked for number %i.", + real == 1 ? "is" : "are", + real, + real == 1 ? "y" : "ies", + requested); + } +} + +int main(int argc, char *argv[]) { + make_window(parse_commandline(argc, argv), argc ,argv); + + /* Check for APM support (returns 0 on success). */ + if (apm_exists() == 0) { + if (! delay) + delay = 1; + } +#ifdef HAL + /* Check for hal support. */ + else if (simplehal_supported()) { + use_simplehal = 1; + if (! delay) + delay = 2; + } +#endif +#ifdef UPOWER + else if (upower_supported()) { + use_upower = 1; + } +#endif + /* Check for ACPI support. */ + else if (acpi_supported() && acpi_batt_count > 0) { + check_battery_num(acpi_batt_count, battnum); + use_acpi = 1; + if (! delay) + delay = 3; /* slow interface! */ + } + else if (sonypi_supported()) { + use_sonypi = 1; + low_pct = 10; + critical_pct = 5; + if (! delay) + delay = 1; + } + else { + error("No APM, ACPI, UPOWER, HAL or SPIC support detected."); + } + + load_images(); + load_audio(); + + signal(SIGALRM, alarmhandler); + alarmhandler(SIGALRM); + + while (1) { + XEvent ev; + XNextEvent(display, &ev); + if (ev.type == Expose) + redraw_window(); + } +} diff --git a/wmbattery/wmbattery.h b/wmbattery/wmbattery.h new file mode 100644 index 0000000..4936957 --- /dev/null +++ b/wmbattery/wmbattery.h @@ -0,0 +1,70 @@ +#include "apm.h" + +typedef struct { + Pixmap pixmap; + Pixmap mask; + XpmAttributes attributes; +} XpmIcon; + +typedef struct image_info_type { + const char* filename; + const int width; + const int height; + const int x; + const int y; + const int charwidth; +} image_info_type; + +/* Assign reference numbers to all images that are loaded. */ +#define SMALLFONT 0 +#define BIGFONT 1 +#define BATTERY_HIGH 2 +#define BATTERY_LOW 3 +#define BATTERY_CRITICAL 4 +#define BATTERY_NONE 5 +#define BATTERY_BLINK 6 +#define UNPLUGGED 7 +#define PLUGGED 8 +#define NOCHARGING 9 +#define CHARGING 10 +#define DIAL_BRIGHT 11 +#define DIAL_DIM 12 +#define FACE 13 + +#define NUM_IMAGES 14 + +/* + * An array of the filenames of all images to load (minus .xpm extention), + * plus the size of the image, where to draw it on the icon, etc + */ +static struct image_info_type image_info[] = { + {"smallfont",7,67,0,45,6}, + {"bigfont",9,73,0,23,7}, + {"battery_high",25,13,33,42,0}, + {"battery_medium",25,13,33,42,0}, + {"battery_low",25,13,33,42,0}, + {"battery_none",25,13,33,42,0}, + {"battery_blink",25,13,33,42,0}, + {"unplugged",10,8,6,45,0}, + {"plugged",10,8,6,45,0}, + {"nocharging",15,9,17,43,0}, + {"charging",15,9,17,43,0}, + {"dial_bright",56,31,4,4,0}, + {"dial_dim",56,31,4,4,0}, + {"face",64,64,0,0,0}, +}; + +#define DIAL_MULTIPLIER 0.56 + +/* Locations of letters in the percent remaining display. */ +#define HUNDREDS_OFFSET 35 +#define TENS_OFFSET 37 +#define ONES_OFFSET 43 +#define PERCENT_OFFSET 49 + +/* Locations of letters in the time remaining display. */ +#define HOURS_TENS_OFFSET 15 +#define HOURS_ONES_OFFSET 23 +#define COLON_OFFSET 30 +#define MINUTES_TENS_OFFSET 34 +#define MINUTES_ONES_OFFSET 41