pax_global_header00006660000000000000000000000064131773535270014527gustar00rootroot0000000000000052 comment=acef3cde0b53e46e00cc53c170602d7ee04788ba xosview-1.20/000077500000000000000000000000001317735352700131555ustar00rootroot00000000000000xosview-1.20/.gitignore000066400000000000000000000001231317735352700151410ustar00rootroot00000000000000.config xosview *.d *.o dist ## Auto-generated stuff: defaultstring.cc Xdefaults xosview-1.20/CHANGES000066400000000000000000000207631317735352700141600ustar00rootroot00000000000000For changes since xosview-1.9.1, see the source code history in Git. Changes since xosview-1.9.0 - Fix a bug where battery meter was not redrawn Changes since xosview-1.8.3 - Modify linux serialmeter startup to allow for a port number instead of True/False. Patch provided by Horst Wente. - netIface support for NetBSD. Patch from Bernd Ernesti. - Move repository to Git - Merged patches from Debian distribution - Several bugfixes - Improvements to defaults Changes since xosview-1.8.2 - NFSDStats ans NFSStats Graph, Decay and UsedMode are now configurable - SunOS updates, compiles now cleanly with gcc 3.3.2 - Fix for linux intmeter for interrupts > 16 thanks to John Adams - Small patch from Gunnar Wolf for lmstemp (change int to double) - Fix battery meter for case where lack of APM report -1%. Thanks to Gunnar Wolf. - Allow netmeter to specify, via the Xresource xosview*netIface, which network interface it will monitor. Patch thanks to Gunnar Wolf. - Add patch for additional cpu fields in linux for 2.6 kernel. Patch thanks to Hendrik Fehr. - Add various pathes from the NetBSD project. Pathes contributed by Roland Illig. - Fix bug 854215 (-v and --version still needed to connect to X server) Changes since xosview-1.8.1 - Applied sourceforge patch 927112 from Russell Reed which fixes the swapmeter when USESYSCALLS is defined. - Applied sourceforge patch 959433 which adds acpi support to the linux battery meter. - Applied a patch similar to the sourceforge patch 586184 submitted by Mark Guertin. - Linux diskmeter now uses vmstat and thus works with 2.6. But the units problem (block size) probably still remains. - Linux pagemeter should now work with 2.6 kernels - Merge in the fedora-2 nfs patch. - Merge in the fedora-2 strip patch. - Merge in the fedora-2 proc patch. - Merge in the fedora-2 s390 patch. - Merge in the fedora-2 non-i386 patch. - Merge in the fedora-2 linux-2.6 kernel (related) patch. - Add an autogen.sh script. This script runs autoconf to create the configure script. Changes since xosview-1.8.0 - Update linux port to build with gcc 3.2 and 3.3 (should still work with 2.95. - Add -Wno-deprecated for gcc builds. This avoids warnings about the new C++ header files. This should be fixed for the next release. - Change MAX_PROC_LENGTH in linux/cpumeter to 4096 to avoid an infinite loop with redhat 7.3 Changes since xosview-1.7.3 - Add Mike Butler's patch which fixes an infinite loop in the linux netmeter when a pcmcia card is ejected. - Add Leopold Toetsch's linux lmstemp meter. - Linux port (and maybe others) now works with gcc-3.0.4 - added IRIX 6.5 support - Updated NetBSD support, based on patches from Bernd Ernesti, to use new CPU meter sysctl interface. Changes since xosview-1.7.2 - IRQ rate meter for BSDs added. - FreeBSD 4.* fixes by David O'Brien Changes since xosview-1.7.1 - Linux now has a RAID meter. See README.linux for how to set it up. BSDI support, courtesy of Tomer Klainer. Fixed memstat module for linux-2.2 Changes from Thomas Waldmann (ThomasWaldmann@gmx.de) - Fixed cosmetical bug in xosview: if you tried to make the xosview window height too small, it looked quite strange (because the height value for the meters got negative) - Fixed cosmetical bug in disk meter: at first call, it displayed negative values, overwriting the "DISK" label - Cosmetical fix: The titles were at x=0 - directly at the window border. Fixed it to show 1 pixel background between window border and title texts. Also moved "used" displays 2 pixels to the right, so that there is also 1 pixel between the titles and the used display texts. - Cosmetical fix: Xdefaults and Xdefaults.stipple file now looks nicer. - Cosmetical fix: load meter sometimes went beyond the right border (I think when showing values >>20). Changed load meter scaling to be really dynamic (no upper bound for total, but total doesn't become less than 1.0). Changed "used" display to show load relative to 1.0 (so it now just shows the load value ;-). - New feature: load meter now has not only a warning color (and threshold), but also a (higher) critical color (and threshold). - Added info to disk meter problem documentation (see source): on my system, it showed only the half of the correct values, factor for SW-RAID5 md devices seems to be 2048 (md0), while standard ext2fs factor is 1024 on my system, too (hda). So there is a problem. Solution ??? - Fixed bitmeter to calculate graphics coordinates like fieldmeter - MemMeter showed strange values when starting vmware (and having memstat module loaded): "used" memory got negative !! Looking at the values, I had the impression that "shared" memory is also counted as cache memory. I hopefully fixed that by subtracting shared from cache - looks better now. Changes since xosview-1.7.0 Optimised scrolling graph to use XCopyArea. Fixes to linux diskmeter. Fixed all (I hope) linux code which parsed /proc/stat with too small a buffer. Changes since xosview-1.6.2 Added a linux diskmeter which *should* be similar to the BSD version but which also differentiates between reading and writing. Linux looks like it actually has more stats (per disk input/output) so this could be expanded upon. Better *BSD support: OpenBSD intmeter, FreeBSD diskmeter, NetBSD battery meter. Some Solaris support. Changes since xosview-1.6.1 Check for and set -D__SMP__ if the linux memstat module is built on a SMP system. New option to omit the meter captions (+-captions) added by Christian 'Dr. Disk' Hechelmann New graphing meter display mode added. Fixes to work with linux/alpha. BSD directories merged -- now a single bsd subdir shared by NetBSD, FreeBSD, and OpenBSD. Changes since xosview-1.6.0: Linux netmeter for kernels 1.1 and above no longer hangs after the packet count gets too high. Interrupt meter now supports priority settings under *BSD and Linux. Better UVM detection for *BSD. Code cleanup/removal of unneeded #include's for *BSD. Changes since xosview-1.5.1, in no particular order: Linux netmeter does not need IPACCOUNTING for 1.1 kernels. Much better support for FreeBSD, thanks to Tom Pavel! Check for invalid meter priority of 0 added. NetBSD now supports the interrupt meter. Finally found the missing 'else' that was causing the net meter in particular to occasionally overwrite the label. Found 32-bit-wrap case that was also causing the netmeter grief. Bitmeter class drawing routine tweaked, usedLabel color changed to be the same as the `on' color for the bits. Changes since xosview-1.5.0, in no particular order: On Linux the cpu meters will now show a seperate meter per cpu if Jerome Forissier's kernel patch has been applied. Linux should now work out of the box with GNU libc (untested). The autoscale labels now work under Linux and HPUX. Early support for FreeBSD: load, cpu, mem, and page meters. Now compiles with either BSD or GNU make (BSD make can not handle auto-depend with the current Makefile structure). Man page source code now uses lots of macros to make modifications easier. Changes since xosview-1.4.*, in no particular order: Linux memory and swap meters now will work with linux 2.0 or 2.1 They will no longer work for pre 2.0 kernels. All meters can now be disabled individually. The overloaded 'network' resource has been deprecated, and replaced by 'net' to enable/disable the NetMeter, and 'netBandwidth', which sets the initial maximum value for the meter. Initial support for stipple masks has been added, primarily for users stuck with 1-bit monitors/display cards. Try setting enableStipple true. Please give us feedback on this, if you use it. It needs some more work. Initial support for the -name option for specifying an X resource `instance name' other than the default of `xosview'. With the following .Xdefaults file: xosview*background: blue xosviewFoo*background: black the command 'xosview' will have a blue background, and the command 'xosview -name xosviewFoo' will have a black background, but all other resources will be from the default xosview resources. New meters: PageMeter for Linux BatteryMeter for Linux DiskMeter for NetBSD Improved drawing. Improved usedLabels -- now the autoscale format can be used to automatically print a value in K, M, or G, as appropriate. (Before, most displays showed percent use, instead of absolute values.) xosview-1.20/COPYING000066400000000000000000000022301317735352700142050ustar00rootroot00000000000000 The majority of the xosview source code is covered by the GNU General Public License (GPL), which is presented in the file COPYING.GPL. In addition, a portion of the NetBSD port's code is covered under the traditional BSD copyright, which is presented in COPYING.BSD. If you plan on modifying or distributing any portion of this code, make sure that you agree to the terms in the BSD copyright (which in general is less restrictive than the GPL, from what I've seen, but I'm not a lawyer-type). These files are: netbsd/swapinternal.cc Lastly, various portions of the xosview source code were developed by various authors who have intentionally chosen to allow the user to choose between the BSD copyright or the GPL copyright. These files are: fieldmeterdecay.h fieldmeterdecay.cc general.h netbsd/MeterMaker.h netbsd/MeterMaker.cc netbsd/cpumeter.h netbsd/cpumeter.cc netbsd/diskmeter.h netbsd/diskmeter.cc netbsd/loadmeter.h netbsd/loadmeter.cc netbsd/memmeter.h netbsd/memmeter.cc netbsd/netbsd.h netbsd/netbsd.cc netbsd/netmeter.h netbsd/netmeter.cc netbsd/swapmeter.h netbsd/swapmeter.cc Brian Grayson, Feb. 1997 xosview-1.20/COPYING.BSD000066400000000000000000000034441317735352700146240ustar00rootroot00000000000000/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ xosview-1.20/COPYING.GPL000066400000000000000000000430701317735352700146350ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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. xosview-1.20/Host.cc000066400000000000000000000103051317735352700144000ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include #include #include "Host.h" #if defined(__hpux__) || defined(__hpux) extern int h_errno; #endif Host::Host(const char *hostname){ struct hostent *hent = gethostbyname(hostname); check(hent); copy(hent); } Host::Host(const struct in_addr *address){ constuct(address); } Host::Host(unsigned int addr){ struct in_addr ia; ia.s_addr = htonl(addr); constuct(&ia); } bool Host::constuct(const struct in_addr *address){ struct hostent *hent = gethostbyaddr((char *)address, sizeof(in_addr), AF_INET); bool tmp = check(hent); copy(hent); return tmp; } void Host::copy(const struct hostent *hent){ _hent.h_name = NULL; _hent.h_aliases = NULL; _numAliases = 0; _hent.h_addrtype = -1; _hent.h_length = -1; _numAddresses = 0; _hent.h_addr_list = NULL; _valid = false; if (hent != NULL){ // Then it is valid. _valid = true; // find the number of aliases. char **tmp = hent->h_aliases; while (*tmp != NULL){ _numAliases++; tmp++; } // copy the official name. int hnamelen = strlen(hent->h_name) + 1; _hent.h_name = new char[hnamelen]; strncpy((char *)_hent.h_name, hent->h_name, hnamelen); // copy the aliases. _hent.h_aliases = new char *[_numAliases + 1]; for (int i = 0 ; i < _numAliases ; i++){ int len = strlen(hent->h_aliases[i]) + 1; _hent.h_aliases[i] = new char[len + 1]; strncpy(_hent.h_aliases[i], hent->h_aliases[i], len); } _hent.h_aliases[_numAliases] = NULL; // copy the address type and length. _hent.h_addrtype = hent->h_addrtype; _hent.h_length = hent->h_length; // find the number of addresses. char **taddr = hent->h_addr_list; while (*taddr != NULL){ _numAddresses++; taddr++; } // copy the addresses. _hent.h_addr_list = new char *[_numAddresses + 1]; for (int j = 0 ; j < _numAddresses ; j++){ _hent.h_addr_list[j] = (char *)new in_addr; memcpy(_hent.h_addr_list[j], hent->h_addr_list[j], sizeof(in_addr)); } _hent.h_addr_list[_numAddresses] = NULL; } } Host::~Host(void){ clear(); } void Host::clear(void){ _valid = false; delete[] _hent.h_name; _hent.h_name = NULL; for (int i = 0 ; i < _numAliases ; i++) delete[] _hent.h_aliases[i]; delete[] _hent.h_aliases; _hent.h_aliases = NULL; for (int j = 0 ; j < _numAddresses ; j++) delete _hent.h_addr_list[j]; delete[] _hent.h_addr_list; _hent.h_addr_list = NULL; _numAliases = 0; _hent.h_addrtype = -1; _hent.h_length = -1; _numAddresses = 0; } bool Host::check(const struct hostent *hent) { if (hent != NULL) // all is well return true; _valid = false; _failure = h_errno; return false; } int Host::reasonForFailure(void) const{ if (_valid) return 0; //NETDB_SUCCESS; return _failure; } bool Host::tryAgain(void) const { if (reasonForFailure() == TRY_AGAIN) return true; return false; } bool Host::operator==(const Host& host) const { if (valid() != host.valid()) return false; if (!valid()) // they are both invalid return true; // now check all of the addresses for each host. for (int i = 0 ; i < _numAddresses ; i++) for (int j = 0 ; j < host.numAddresses() ; j++) if (address(i)->s_addr == host.address(j)->s_addr) return true; return false; } std::ostream &Host::print(std::ostream& os) const { /* Cast 'this' to a char*, so we don't need to create a Host::! operator.*/ if (!*((char*)this)) return os <<"Invalid Host. h_errno was = " <<_failure <<"\n"; os <<"---- Host ----\n" <<"Official Name = " < #include #include #include #include #include class Host { public: Host(const char *hostname); Host(const struct in_addr *address); Host(unsigned int addr); Host(const Host& host) { copy(host); _failure = host._failure; } virtual ~Host(void); Host &operator=(const Host& host) { clear(); copy(host); _failure = host._failure; return *this; } bool operator==(const Host& host) const; bool operator!=(const Host& host) const { return !(*this == host); } // indicates a valid Host. bool valid(void) const { return _valid; } operator bool(void) const { return _valid; } int reasonForFailure(void) const; // returns h_errno at time of failure bool tryAgain(void) const; // Ok to try again? const char *officialName(void) const { return _hent.h_name; } int numAliases(void) const { return _numAliases; } const char *alias(int num) const { return _hent.h_aliases[num]; } int addrType(void) const { return _hent.h_addrtype; } int addrLength(void) const { return _hent.h_length; } int numAddresses(void) const { return _numAddresses; } struct in_addr *address(int num) const { return (in_addr *)_hent.h_addr_list[num]; } // Linux will choke and die inside of inet_ntoa() when // this function is called. The Host class has been run // through purify and the problem is not in it. Must be // another linux library problem :(. const char *strAddress(int num) const { return inet_ntoa(*address(num)); } // Should not use this under linux for the same reashon as the above // function. std::ostream &print(std::ostream &os) const; protected: private: struct hostent _hent; int _numAliases; int _numAddresses; bool _valid; int _failure; void copy(const Host& host) { copy(&host._hent); } void copy(const struct hostent *hent); void clear(void); bool check(const struct hostent *hent); bool constuct(const struct in_addr *address); }; // Do not use this under linux until inet_ntoa() is fixed. inline std::ostream &operator<<(std::ostream &os, const Host& host) { return host.print(os); } #endif xosview-1.20/Makefile000066400000000000000000000063421317735352700146220ustar00rootroot00000000000000-include .config AWK ?= awk INSTALL ?= install PLATFORM ?= linux # Installation paths PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man XDGAPPSDIR ?= $(PREFIX)/share/applications ICONDIR ?= $(PREFIX)/share/icons/hicolor # Optional build arguments; user may wish to override OPTFLAGS ?= -Wall -O3 # Required build arguments CPPFLAGS += $(OPTFLAGS) -I. -MMD LDLIBS += -lX11 -lXpm OBJS = Host.o \ Xrm.o \ bitfieldmeter.o \ bitmeter.o \ defaultstring.o \ fieldmeter.o \ fieldmeterdecay.o \ fieldmetergraph.o \ llist.o \ main.o \ meter.o \ xosview.o \ xwin.o # Optional platform type ifeq ($(PLATFORM), linux) ARCH = $(shell uname -m) OBJS += sensorfieldmeter.o \ linux/MeterMaker.o \ linux/btrymeter.o \ linux/cpumeter.o \ linux/diskmeter.o \ linux/intmeter.o \ linux/intratemeter.o \ linux/lmstemp.o \ linux/loadmeter.o \ linux/memmeter.o \ linux/netmeter.o \ linux/nfsmeter.o \ linux/pagemeter.o \ linux/raidmeter.o \ linux/serialmeter.o \ linux/swapmeter.o \ linux/wirelessmeter.o \ linux/acpitemp.o ifeq ($(findstring 86,$(ARCH)),86) OBJS += linux/coretemp.o endif CPPFLAGS += -Ilinux/ LDLIBS += -lm endif ifeq ($(PLATFORM), bsd) ARCH = $(shell uname -m) OBJS += sensorfieldmeter.o \ bsd/MeterMaker.o \ bsd/btrymeter.o \ bsd/cpumeter.o \ bsd/diskmeter.o \ bsd/intmeter.o \ bsd/intratemeter.o \ bsd/kernel.o \ bsd/loadmeter.o \ bsd/memmeter.o \ bsd/netmeter.o \ bsd/pagemeter.o \ bsd/swapmeter.o \ bsd/sensor.o ifeq ($(ARCH),$(filter $(ARCH),i386 amd64 x86_64)) OBJS += bsd/coretemp.o endif CPPFLAGS += -Ibsd/ LDLIBS += -lm endif ifeq ($(PLATFORM), irix65) OBJS += irix65/MeterMaker.o \ irix65/cpumeter.o \ irix65/diskmeter.o \ irix65/gfxmeter.o \ irix65/loadmeter.o \ irix65/memmeter.o \ irix65/sarmeter.o CPPFLAGS += -Iirix65/ endif ifeq ($(PLATFORM), sunos5) OBJS += sunos5/MeterMaker.o \ sunos5/cpumeter.o \ sunos5/diskmeter.o \ sunos5/loadmeter.o \ sunos5/memmeter.o \ sunos5/netmeter.o \ sunos5/pagemeter.o \ sunos5/swapmeter.o \ sunos5/intratemeter.o CPPFLAGS += -Isunos5/ -Wno-write-strings LDLIBS += -lkstat -lnsl -lsocket INSTALL = ginstall endif ifeq ($(PLATFORM), gnu) OBJS += gnu/get_def_pager.o \ gnu/loadmeter.o \ gnu/memmeter.o \ gnu/MeterMaker.o \ gnu/pagemeter.o \ gnu/swapmeter.o CPPFLAGS += -Ignu/ endif DEPS := $(OBJS:.o=.d) xosview: $(OBJS) $(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS) defaultstring.cc: Xdefaults defresources.awk $(AWK) -f defresources.awk Xdefaults > defaultstring.cc Xrm.o: CXXFLAGS += -Wno-write-strings .PHONY: dist install clean dist: ./mkdist $(VERSION) install: xosview $(INSTALL) -d $(DESTDIR)$(BINDIR) $(INSTALL) -d $(DESTDIR)$(MANDIR)/man1 $(INSTALL) -d $(DESTDIR)$(XDGAPPSDIR) $(INSTALL) -d $(DESTDIR)$(ICONDIR)/32x32/apps $(INSTALL) -m 755 xosview $(DESTDIR)$(BINDIR)/xosview $(INSTALL) -m 644 xosview.1 $(DESTDIR)$(MANDIR)/man1/xosview.1 $(INSTALL) -m 644 xosview.desktop $(DESTDIR)$(XDGAPPSDIR) $(INSTALL) -m 644 xosview.png $(DESTDIR)$(ICONDIR)/32x32/apps clean: rm -f xosview $(OBJS) $(DEPS) defaultstring.cc -include $(DEPS) xosview-1.20/README000066400000000000000000000021731317735352700140400ustar00rootroot00000000000000This version of xosview is distributed from the following sites: http://www.pogo.org.uk/~mark/xosview/ https://github.com/hills/xosview The build no longer uses GNU autoconfig. Control is via Makefile variables. In general, you should be able to build on Linux using: $ make $ make install To change the target prefix, use, for example: $ make install PREFIX=/usr For more fine-grained control, see the Makefile for available variables. To specify a particular platform, use one of: $ make PLATFORM=linux $ make PLATFORM=bsd $ make PLATFORM=irix65 $ make PLATFORM=sunos5 $ make PLATFORM=gnu Please see the README file for your platform for any special instructions for running xosview on that platform. The Makefile picks up additional variables from a .config file in the source code directory. You may prefer to use this if you are doing several builds for testing and debugging. Some platform variants require specific build flags; see the 'targets' directory for preset .config files. See the man page for information on the xosview display and how to customize it. See the COPYING file for licensing terms. xosview-1.20/README.dragonflybsd000066400000000000000000000014071317735352700165140ustar00rootroot00000000000000 Support for DragonflyBSD added by Tomi Tapper (tomi.o.tapper@jyu.fi). Tested on DragonflyBSD version 3.0, but may work on other versions (earlier or later) as well. Please test and report if possible. For building xosview by hand, add these lines into .config. CPPFLAGS += -I/usr/pkg/include LDLIBS += -lkvm -lkinfo -ldevstat -L/usr/pkg/lib ***************************************************************************** Note: xosview needs to run 'setgid kmem' in order to access some of the kernel information (at least until some more statistics are added to the /kern or /proc file systems). If you do not have root or kmem permission on the machine, xosview will not run. ***************************************************************************** xosview-1.20/README.freebsd000066400000000000000000000015341317735352700154510ustar00rootroot00000000000000 The FreeBSD port now has much better support, thanks to Tom Pavel. From within the ports system, xosview ought to build out of the box --- if not, it's a bug. This version of xosview no longer supports FreeBSD versions below 7.0. Users of older versions need xosview version below 1.9. For building xosview by hand, add these lines into .config. CPPFLAGS += -I/usr/local/include LDLIBS += -lkvm -ldevstat -L/usr/local/lib ***************************************************************************** Note: xosview needs to run 'setgid kmem' in order to access some of the kernel information (at least until some more statistics are added to the /kern or /proc file systems). If you do not have root or kmem permission on the machine, xosview will not run. ***************************************************************************** xosview-1.20/README.gnu000066400000000000000000000001211317735352700146170ustar00rootroot00000000000000 Support for GNU/Hurd added by Samuel Thibault (samuel.thibault@ens-lyon.org). xosview-1.20/README.irix000066400000000000000000000021171317735352700150100ustar00rootroot00000000000000 The IRIX port supports: - load meter - cpu meter: The cpu meter has a new X resource cpuFormat, with the possible values of single, all, auto or both. It determines how cpu meters are handled for multiprocessors: single displays only meters for each cpu, all displays only a cumulative meter for all cpus, both displays both and auto behaves like both on mp machines and single on up machines. - mem meter - gfx meter: Displays swapbuffers/second. Of course, you're welcome to send me patches. For the gfx meter, sadc is forked to read the activity. The sadc process is handled from the singleton SarMeter, which reads the binary data from sadc and converts it into structures. Currently, it parses gfxinfo and diskinfo data. The diskinfo can be used to create a disk meter, but I do not have the time currently. As said above, send me patches ;). It is tested on: IP20, IP22, IP27, IP30, IP32 and IP35. Stefan Eilemann, Apr 03 eilemann@gmail.com xosview-1.20/README.linux000066400000000000000000000206661317735352700152050ustar00rootroot00000000000000 To build xosview: Follow the instructions found in README. In addition please consider the following: - The memory meter can now display shared memory correctly. Unfortunatly, it needs more information than a "stock" linux kernel provides to do this. It can get this information with the help of a kernel module (memstat.o) which is provided with this release. If this module is not loaded, then xosview will not provide a "shared" memory field in the memory meter. The memstat module is now built by default if you are running a 2.0.x or 2.2.x kernel. Paal Beyer provided code to make it work under linux 2.1. At the moment it seems that 2.1 is in a bit of a transitory state as far as the proc filesystem goes. So, the memstat module is disabled by default for 2.1 kernels. It has been built under linux2.1.71. If you do not want to build the memstat module you can run configure with a '--disable-linux-memstat' switch. At the moment this module will not work for the 2.4 kernels. To install xosview: If one installs xosview via the 'make install' target it will place things in the following locations. The binary (xosview) will be copied to /usr/bin/X11/xosview and will be suid root. If you do not want to run xosview suid root (this will just disable the serial meters) you can change the permissions to whatever you like. The X defaults for xosview (Xdefaults) are copied to /usr/lib/X11/app-defaults/XOsview. To run xosview : - The network meter has been changed from the way it behaved in version 1.3.2. It now displays the network usage in bytes / sec. This is done by using the IP accounting features of the kernel. Newer 2.1 series kernels contain this information in /proc/net/dev. If you are running one of these kernels, xosview will use this information and you will not need to read further in this section. NOTE (2.1+ series kernels): /proc/net/dev has the downside of logging ANY packet passing on your interface, regardless of its destination/source. This causes the network meter to report non-zero traffic even if there are no in/outbound packets from the machine. Ipchains provides a way to solve this, but it requires xosview to access /proc/net/ip_fwchains, which requires root privileges (i.e. it's bad). If xosview is installed setuid root it can access the ip_fwchains file: it'll then scan it for two chains named "iacct" and "oacct" to determine traffic. The chains are created with the following commands (you must be root to execute this), where YOUR-IP is either your ip or your hostname: ipchains -N iacct ipchains -N oacct ipchains -A iacct -s \! YOUR-IP -d YOUR-IP ipchains -A oacct -s YOUR-IP -d \! YOUR-IP ipchains -A input -j iacct ipchains -A output -j oacct (these rules will also eliminate any traffic from your machine to your machine). If you are running an older 2.1 or 2.0 kernel then you must setup ipaccounting to get the information for xosview. In order for this new network meter to function you must do the following for older kernels: 1 Make sure that IP accounting is enabled in your kernel. This means you may need to rebuild it. 2 Enable IP accounting for all IP packets into and out of your machine. This is done by using a program called 'ipfwadm'. The example below is how I run ipfwadm to do this at boot time in my rc.local: /sbin/ipfwadm -A -a -P all -S 192.168.0.3 -D 0/0 /sbin/ipfwadm -A -a -P all -S 0/0 -D 192.168.0.3 If you do not do these steps, you will still be able to use xosview. You just will not be able to use the network meter. - The serial meter code in has been updated so that it displays more useful information. To do this xosview now looks directly at a couple of the serial registers. As a result of this, xosview now need to be suid root in order to use the serial meters. If you try to use xosview with a serial meter enabled and it is not suid root it will display a message to this effect and exit. A non suid version of xosview will still function normally. It just will not be able to run with the serial meters toggled on. I hope that at some point in the future the Linux /proc filesystem will provide some more useful serial stats and xosview will not have to be suid to get serial information. - The memory meter no longer displays shared memory by default. The information found in /proc/meminfo is not sufficient to figure out what percentage of real memory is being used for 'shared'. There is a kernel module which comes with xosview that provides this information. It is found in the linux/memstat directory. If this module is loaded into the kernel, a new entry will show up in /proc called /proc/memstat. Xosview will display a shared memory field if it finds this file (ie the memstat module is loaded). - If you have an SMP machine xosview will now show a seperate cpumeter for each processor provided your kernel has support for this. To get this to work you will need Jerome Forissier's kernel patch which modifies the proc filesystem to provide stats on a per processor basis. You can find this patch at the following URL: http://www-isia.cma.fr/~forissie/smp_kernel_patch/ These patches are only needed for 2.0 kernels. Newer kernels already have the patch. - Raidmeter notes from Thomas Waldmann: Linux now supports a RAID meter. This meter is disabled by default since a couple of kernel patches are currently required to get it working. It can be enabled via an X resource. You need a kernel patched with raid0145-19990824 stuff AND mdstat-tw1.diff. xosview RAID display won't work without mdstat-tw1.diff applied! Because I didn't find out the kernel variable which holds the md device count, you have to set it in the Xdefaults file (you don't need to change it if you have 1 md device). If you know how to modify the kernel to make this obsolete, please tell me! Also there might be some redundant values in /proc/mdstat - I just included everything that was there in old format. linux/mdstat-tw1.diff change /proc/mdstat to be more easily readable and parseable RAID1 and RAID5 arrays will give a nice "working disk map" and "resync status" display. When using a RAID1 or RAID5 array it is very important to NOTICE a disk failure. If you don't notice it because your system continues to work normally, you'll have a bad day if the next disk fails... RAID0 won't give a senseful display because there is no "working disk map" and there is no "resync status" at all. As RAID0 has no redundancy you will for sure notice a disk failure (that's the moment when all your data is gone and you need a backup tape), so you maybe won't need xosview for that. The usual disclaimer ==================== The patches work on my machine, but there's no guarantee at all. Use on your OWN risk. If it breaks your RAID array, you own the parts. What you need ============= kernel source 2.2.11 or 2.2.12 or 2.2.13 (ftp.kernel.org/pub/linux/kernel/...) kernel RAID patch raid0145-19990824-2.2.11 + corresponding raidtools (ftp.kernel.org/pub/linux/daemons/raid/alpha/...) Installation ============ Kernel ------ Unpack kernel source, patch it with the RAID patch (if you are using kernel 2.2.12 or 2.2.13 you will get some warnings. Answer "n" for any question. You can ignore the warnings safely, you get them because some stuff in the patch already IS in the kernel source). Patch your kernel source with the mdstat-tw1.diff: cd /usr/src/linux patch -p1 #include #include // For snprintf(). #include #include // for access(), etc. BCG #include extern char *defaultXResourceString; bool Xrm::_initialized = false; Xrm::Xrm(const char *instanceName, int argc, char **argv){ std::cerr << " Error: This constructor is not supported yet." << std::endl; exit (-1); _db = NULL; _class = _instance = NULLQUARK; getDisplayName(argc, argv); (void) instanceName; // End unsupported constructor. !!!!!!!! BCG } Xrm::Xrm(const char *className, const char *instanceName){ XrmInitialize (); // Initialize everything to NULL. _db = NULL; _class = _instance = NULLQUARK; // init the _instance and _class Quarks _instance = XrmStringToQuark(instanceName); initClassName(className); } const char* Xrm::getDisplayName (int argc, char** argv) { (void) argc; // Avoid gcc warnings. // See if '-display foo:0' is on the command line, and return it if it is. char** argp; for (argp = argv; (*argp != NULL) && (strncasecmp (*argp, "-display", 9)); argp++) ; // Don't do anything. // If we found -display and the next word exists... if (*argp && *(++argp)) _display_name = *argp; else _display_name = ""; return _display_name; // An empty display string means use the DISPLAY environment variable. } const char *Xrm::getResource(const char *rname) const{ char frn[1024], fcn[1024]; snprintf(frn, 1024, "%s.%s", instanceName(), rname); snprintf(fcn, 1024, "%s.%s", className(), rname); XrmValue val; val.addr = NULL; char *type; XrmGetResource(_db, frn, fcn, &type, &val); // This case here is a hack, because we are currently moving from // always making the instance name be "xosview" to allowing // user-specified ones. And unfortunately, the class name is // XOsview, and not xosview, so our old defaults (xosview.font) // will not be found when searching for XOsview.font. bgrayson Dec. 1996 if (!val.addr) { // Let's try with a non-uppercased class name. char fcn_lower[1024]; strncpy(fcn_lower, className(), 1024); char *p = fcn_lower; while (p && *p) { *p = tolower(*p); p++; } snprintf(fcn, 1024, "%s.%s", fcn_lower, rname); XrmGetResource(_db, frn, fcn, &type, &val); } return val.addr; } Xrm::~Xrm(){ XrmDestroyDatabase(_db); } //--------------------------------------------------------------------- // This function uses XrmParseCommand, and updates argc and argv through it. void Xrm::loadAndMergeResources(int& argc, char** argv, Display* display){ // init the database if it needs it if (!_initialized){ XrmInitialize(); _initialized = true; } else { std::cerr << "Error: Xrm:loadAndMergeResources() called twice!" << std::endl; exit (-1); } // This is ugly code. According to X and Xt rules, many files need // to be checked for resource settings. Since we aren't (yet) using // Xt or any other package, we need to do all of these checks // individually. BCG // =========== BEGIN X Resource lookup and merging ========== // This all needs to be done in the proper order: /* Listed from weakest to strongest: (from code-builtin-resources) (Stored in the string in defaultstring.h) app-defaults XOSView (from XAPPLRESDIR directory) from RESOURCE_MANAGER property on server (reads .Xdefaults if needed) from file specified in XENVIRONMENT from command line (i.e., handled with XrmParseCommand) */ // Get resources from the various resource files // Put the default, compile-time options as the lowest priority. _db = XrmGetStringDatabase (defaultXResourceString); // Merge in the system resource database. char rfilename[2048]; int result; const int rlen = sizeof rfilename; // Get the app-defaults result = snprintf(rfilename, sizeof rfilename, "/etc/X11/app-defaults/%s", XrmQuarkToString(_class)); if (result >= 0 && result < rlen) XrmCombineFileDatabase (rfilename, &_db, 1); result = snprintf(rfilename, sizeof rfilename, "/usr/lib/X11/app-defaults/%s", XrmQuarkToString(_class)); if (result >= 0 && result < rlen) XrmCombineFileDatabase (rfilename, &_db, 1); result = snprintf(rfilename, sizeof rfilename, "/usr/X11R6/lib/X11/app-defaults/%s", XrmQuarkToString(_class)); if (result >= 0 && result < rlen) XrmCombineFileDatabase (rfilename, &_db, 1); result = snprintf(rfilename, sizeof rfilename, "/usr/share/X11/app-defaults/%s", XrmQuarkToString(_class)); if (result >= 0 && result < rlen) XrmCombineFileDatabase (rfilename, &_db, 1); // Try a few more, for SunOS/Solaris folks. result = snprintf(rfilename, sizeof rfilename, "/usr/openwin/lib/X11/app-defaults/%s", XrmQuarkToString(_class)); if (result >= 0 && result < rlen) XrmCombineFileDatabase (rfilename, &_db, 1); result = snprintf(rfilename, sizeof rfilename, "/usr/local/X11R6/lib/X11/app-defaults/%s", XrmQuarkToString(_class)); if (result >= 0 && result < rlen) XrmCombineFileDatabase (rfilename, &_db, 1); // Now, check for an XOSView file in the XAPPLRESDIR directory... char* xappdir = getenv ("XAPPLRESDIR"); if (xappdir != NULL) { char xappfile[1024]; snprintf (xappfile, 1024, "%s/%s", xappdir, className()); // this did not work for XAPPLRESDIR //if (!access (xappfile, X_OK | R_OK)) if (!access (xappfile, R_OK)) { XrmCombineFileDatabase (xappfile, &_db, 1); } } // Now, check the display's RESOURCE_MANAGER property... char* displayString = XResourceManagerString (display); if (displayString != NULL) { XrmDatabase displayrdb = XrmGetStringDatabase (displayString); XrmMergeDatabases (displayrdb, &_db); // Destroys displayrdb when done. } // And check this screen of the display... char* screenString = XScreenResourceString (DefaultScreenOfDisplay(display)); if (screenString != NULL) { XrmDatabase screenrdb = XrmGetStringDatabase (screenString); XrmMergeDatabases (screenrdb, &_db); // Destroys screenrdb when done. } // Now, check for a user resource file, and merge it in if there is one... if ( getenv( "HOME" ) != NULL ){ char userrfilename[1024]; char *home = getenv("HOME"); snprintf(userrfilename, 1024, "%s/.Xdefaults", home); // User file overrides system (_db). XrmCombineFileDatabase (userrfilename, &_db, 1); } // Second-to-last, parse any resource file specified in the // environment variable XENVIRONMENT. char* xenvfile; if ((xenvfile = getenv ("XENVIRONMENT")) != NULL) { // The XENVIRONMENT file overrides all of the above. XrmCombineFileDatabase (xenvfile, &_db, 1); } // Command-line resources override system and user defaults. XrmDatabase cmdlineRdb_ = NULL; XrmParseCommand (&cmdlineRdb_, options, NUM_OPTIONS, instanceName(), &argc, argv); XrmCombineDatabase (cmdlineRdb_, &_db, 1); // Keeps cmdlineRdb_ around. // =========== END X Resource lookup and merging ========== } void Xrm::initClassName(const char* name){ char className[256]; strncpy(className, name, 255); // Avoid evil people out there... className[0] = toupper(className[0]); if (className[0] == 'X') className[1] = toupper(className[1]); _class = XrmStringToQuark(className); } //------------ Some debugging functions follow. ----------------------- inline std::ostream &operator<<(std::ostream &os, const XrmBinding &b){ switch (b){ case XrmBindTightly: return os << "."; case XrmBindLoosely: return os << "*"; default: std::cerr <<"std::ostream operator<<(std::ostream &, const XrmBinding &) : " <<"Unknown XrmBinding!"; return os; } return os; } std::ostream &Xrm::dump(std::ostream &os) const { os <<"--- Xrm --- class: " <addr <<"\n"; return False; } xosview-1.20/Xrm.h000066400000000000000000000024411317735352700140750ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _Xrm_h #define _Xrm_h #include #include #include class Xrm { public: Xrm(const char *className, const char *instanceName); Xrm(const char *instanceName, int argc, char **argv); ~Xrm(); const char *className(void) const { return XrmQuarkToString(_class); } const char *instanceName(void) const { return XrmQuarkToString(_instance); } const char *getResource(const char *rname) const; const char* getDisplayName (int argc, char** argv); void loadAndMergeResources(int& argc, char** argv, Display* display); std::ostream &dump(std::ostream &os) const; private: XrmDatabase _db; XrmClass _class, _instance; const char* _display_name; // Used solely for getting the display's resources. //void getArgs(int argc, char **argv); static Bool enumCB(XrmDatabase *, XrmBindingList bindings, XrmQuarkList quarks, XrmRepresentation *type, XrmValue *value, XPointer closure); void initClassName(const char* className); static bool _initialized; }; inline std::ostream &operator<<(std::ostream &os, const Xrm &xrm){ return xrm.dump(os); } #endif xosview-1.20/Xrmcommandline.h000066400000000000000000000105431317735352700163060ustar00rootroot00000000000000#ifndef _Xrmcommandline_h #define _Xrmcommandline_h #include static XrmOptionDescRec options[] = { // For these options, try to use '+' to turn them on, and '-' to turn them // off, even though this is different from the usual tradition of -foo // turning on 'foo', which is off by default. At least this way, // it is self-consistent, and self-explanatory. // General, X11 resources: { "-display", "*display", XrmoptionSepArg, (caddr_t) NULL }, { "-font", "*font", XrmoptionSepArg, (caddr_t) NULL }, { "-title", "*title", XrmoptionSepArg, (caddr_t) NULL }, { "-geometry", "*geometry", XrmoptionSepArg, (caddr_t) NULL }, { "-hmargin", "*horizontalMargin", XrmoptionSepArg, (caddr_t) NULL }, { "-vmargin", "*verticalMargin", XrmoptionSepArg, (caddr_t) NULL }, { "-vspacing", "*verticalSpacing", XrmoptionSepArg, (caddr_t) NULL }, // XOSView-specific resources: { "-labels", "*labels", XrmoptionNoArg, "False" }, { "+labels", "*labels", XrmoptionNoArg, "True" }, { "-captions", "*captions", XrmoptionNoArg, "False" }, { "+captions", "*captions", XrmoptionNoArg, "True" }, { "-usedlabels", "*usedlabels", XrmoptionNoArg, "False" }, { "+usedlabels", "*usedlabels", XrmoptionNoArg, "True" }, { "-samplesPerSec", "*samplesPerSec", XrmoptionSepArg, (caddr_t) NULL }, // CPU resources { "-cpu", "*cpu", XrmoptionNoArg, "False" }, { "+cpu", "*cpu", XrmoptionNoArg, "True" }, { "-cpus", "*cpuFormat", XrmoptionNoArg, "single" }, { "+cpus", "*cpuFormat", XrmoptionNoArg, "all" }, // Load resources { "-load", "*load", XrmoptionNoArg, "False" }, { "+load", "*load", XrmoptionNoArg, "True" }, // Memmeter resources { "-mem", "*mem", XrmoptionNoArg, "False" }, { "+mem", "*mem", XrmoptionNoArg, "True" }, // Swapmeter resources { "-swap", "*swap", XrmoptionNoArg, "False" }, { "+swap", "*swap", XrmoptionNoArg, "True" }, // Batterymeter resources { "-battery", "*battery", XrmoptionNoArg, "False" }, { "+battery", "*battery", XrmoptionNoArg, "True" }, // Wirelessmeter resources { "-wireless", "*wireless", XrmoptionNoArg, "False" }, { "+wireless", "*wireless", XrmoptionNoArg, "True" }, // GFX resources { "-gfx", "*gfx", XrmoptionNoArg, "False" }, { "+gfx", "*gfx", XrmoptionNoArg, "True" }, // Networkmeter resources { "-net", "*net", XrmoptionNoArg, "False" }, { "+net", "*net", XrmoptionNoArg, "True" }, // Previously, network was overloaded to be the bandwidth and the // on/off flag. Now, we have -net for on/off, and networkBandwidth // for bandwidth, with the alias networkBW, and network for backwards // compatibility. { "-network", "*netBandwidth", XrmoptionSepArg, (caddr_t) NULL }, { "-networkBW", "*netBandwidth", XrmoptionSepArg, (caddr_t) NULL }, { "-networkBandwidth", "*netBandwidth", XrmoptionSepArg, (caddr_t) NULL }, // Page Meter { "-page", "*page", XrmoptionNoArg, "False" }, { "+page", "*page", XrmoptionNoArg, "True" }, { "-pagespeed", "*pageBandWidth", XrmoptionSepArg, (caddr_t) NULL }, #if !defined(__hpux__) && !defined(__hpux) // Disk Meter Options { "-disk", "*disk", XrmoptionNoArg, "False" }, { "+disk", "*disk", XrmoptionNoArg, "True" }, #endif // Interrupt meter resources -- all sorts of aliases. { "-int", "*interrupts", XrmoptionNoArg, "False" }, { "+int", "*interrupts", XrmoptionNoArg, "True" }, { "-ints", "*interrupts", XrmoptionNoArg, "False" }, { "+ints", "*interrupts", XrmoptionNoArg, "True" }, { "-interrupts", "*interrupts", XrmoptionNoArg, "False" }, { "+interrupts", "*interrupts", XrmoptionNoArg, "True" }, // Intrate meter resources, for platforms that support it. { "-irqrate", "*irqrate", XrmoptionNoArg, "False" }, { "+irqrate", "*irqrate", XrmoptionNoArg, "True" }, { "-intrate", "*irqrate", XrmoptionNoArg, "False" }, { "+intrate", "*irqrate", XrmoptionNoArg, "True" }, // lmstemp resources { "-lmstemp", "*lmstemp", XrmoptionNoArg, "False" }, { "+lmstemp", "*lmstemp", XrmoptionNoArg, "True" }, // coretemp resources { "-coretemp", "*coretemp", XrmoptionNoArg, "False" }, { "+coretemp", "*coretemp", XrmoptionNoArg, "True" }, // acpitemp resources { "-acpitemp", "*acpitemp", XrmoptionNoArg, "False" }, { "+acpitemp", "*acpitemp", XrmoptionNoArg, "True" }, // Special, catch-all option here -- // xosview -xrm "*memFreeColor: purple" should work, for example. { "-xrm", "*xrm", XrmoptionResArg, (caddr_t) NULL }, }; // This auto-detects changes in the number of options. static const int NUM_OPTIONS = sizeof(options) / sizeof(options[0]); #endif xosview-1.20/bitfieldmeter.cc000066400000000000000000000243611317735352700163110ustar00rootroot00000000000000// // Copyright (c) 1999, 2006 Thomas Waldmann ( ThomasWaldmann@gmx.de ) // based on work of Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // // #include "bitfieldmeter.h" #include #include #include #include #include BitFieldMeter::BitFieldMeter( XOSView *parent, int numBits, int numfields, const char *title, const char *bitslegend, const char *FieldLegend, int docaptions, int dolegends, int dousedlegends ) : Meter(parent, title, bitslegend, docaptions, dolegends, dousedlegends){ /* We need to set print_ to something valid -- the meters * apparently get drawn before the meters have a chance to call * CheckResources() themselves. */ bits_ = NULL; lastbits_ = NULL; numWarnings_ = printedZeroTotalMesg_ = 0; print_ = PERCENT; metric_ = false; usedoffset_ = 0; used_ = 0; lastused_ = -1; fields_ = NULL; colors_ = NULL; lastvals_ = NULL; lastx_ = NULL; setNumBits(numBits); fieldLegend_ = NULL; setfieldlegend(FieldLegend); setNumFields(numfields); } void BitFieldMeter::disableMeter ( ) { setNumFields(1); setfieldcolor (0, "grey"); setfieldlegend ("Disabled"); total_ = fields_[0] = 1.0; setNumBits(1); offColor_ = onColor_ = parent_->allocColor("grey"); } BitFieldMeter::~BitFieldMeter( void ){ delete[] bits_; delete[] lastbits_; delete[] fields_; delete[] colors_; delete[] lastvals_; delete[] lastx_; } void BitFieldMeter::checkResources( void ){ Meter::checkResources(); usedcolor_ = parent_->allocColor( parent_->getResource( "usedLabelColor") ); } void BitFieldMeter::setNumBits(int n){ numbits_ = n; delete[] bits_; delete[] lastbits_; bits_ = new char[numbits_]; lastbits_ = new char[numbits_]; for ( int i = 0 ; i < numbits_ ; i++ ) bits_[i] = lastbits_[i] = 0; } void BitFieldMeter::SetUsedFormat ( const char * const fmt ) { /* Do case-insensitive compares. */ if (!strncasecmp (fmt, "percent", 8)) print_ = PERCENT; else if (!strncasecmp (fmt, "autoscale", 10)) print_ = AUTOSCALE; else if (!strncasecmp (fmt, "float", 6)) print_ = FLOAT; else { std::cerr << "Error: could not parse format of '" << fmt << "'.\n" << " I expected one of 'percent', 'autoscale', or 'float'" << " (Case-insensitive)." << std::endl; exit(1); } } void BitFieldMeter::setUsed (double val, double total) { if (print_ == FLOAT) used_ = val; else if (print_ == PERCENT) { if (total != 0.0) used_ = val / total * 100.0; else { if (!printedZeroTotalMesg_) { printedZeroTotalMesg_ = 1; std::cerr << "Warning: " << name() << " meter had a zero total field! " << "Would have caused a div-by-zero exception." << std::endl; } used_ = 0.0; } } else if (print_ == AUTOSCALE) used_ = val; else { std::cerr << "Error in " << name() << ": I can't handle a UsedType enum " << "value of " << print_ << "!" << std::endl; exit(1); } } void BitFieldMeter::reset( void ){ for ( int i = 0 ; i < numfields_ ; i++ ) lastvals_[i] = lastx_[i] = -1; } void BitFieldMeter::setfieldcolor( int field, const char *color ){ colors_[field] = parent_->allocColor( color ); } void BitFieldMeter::setfieldcolor( int field, unsigned long color ) { colors_[field] = color; } void BitFieldMeter::draw( void ){ /* Draw the outline for the fieldmeter. */ parent_->setForeground( parent_->foreground() ); parent_->lineWidth( 1 ); parent_->drawFilledRectangle( x_ - 1, y_ - 1, width_/2 + 2, height_ + 2 ); // ?? parent_->lineWidth( 0 ); parent_->drawRectangle( x_ + width_/2 +3, y_ - 1, width_/2 - 2, height_ + 2 ); if ( dolegends_ ){ parent_->setForeground( textcolor_ ); int offset; if ( dousedlegends_ ) offset = parent_->textWidth( "XXXXXXXXXX" ); else offset = parent_->textWidth( "XXXXXX" ); parent_->drawString( x_ - offset + 1, y_ + height_, title_ ); if(docaptions_){ parent_->setForeground( onColor_ ); parent_->drawString( x_, y_ - 5, legend_ ); drawfieldlegend(); } } drawBits( 1 ); drawfields( 1 ); } void BitFieldMeter::drawfieldlegend( void ){ char *tmp1, *tmp2, buff[100]; int n, x = x_ + width_/2 + 4; tmp1 = tmp2 = fieldLegend_; for ( int i = 0 ; i < numfields_ ; i++ ){ n = 0; while ( (*tmp2 != '/') && (*tmp2 != '\0') ){ if ( (*tmp2 == '\\') && (*(tmp2 + 1) == '/') ) // allow '/' in field as '\/' memmove( tmp2, tmp2 + 1, strlen(tmp2) ); tmp2++; n++; } tmp2++; strncpy( buff, tmp1, n ); buff[n] = '\0'; parent_->setStippleN(i%4); parent_->setForeground( colors_[i] ); parent_->drawString( x, y_ - 5, buff ); x += parent_->textWidth( buff, n ); parent_->setForeground( parent_->foreground() ); if ( i != numfields_ - 1 ) parent_->drawString( x, y_ - 5, "/" ); x += parent_->textWidth( "/", 1 ); tmp1 = tmp2; } parent_->setStippleN(0); /* Restore default all-bits stipple. */ } void BitFieldMeter::drawused( int mandatory ){ if ( !mandatory ) if ( lastused_ == used_ ) return; parent_->setStippleN(0); /* Use all-bits stipple. */ static const int onechar = parent_->textWidth( "X" ); if (!usedoffset_) // metric meters need extra space for '-' sign usedoffset_ = ( metric_ ? parent_->textWidth( "XXXXXX" ) : parent_->textWidth( "XXXXX" ) ); char buf[10]; if (print_ == PERCENT){ snprintf( buf, 10, "%d%%", (int)used_ ); } else if (print_ == AUTOSCALE){ char scale[2]; double scaled_used = scaleValue(used_, scale, metric_); /* For now, we can only print 3 characters, plus the optional sign and * suffix, without overprinting the legends. Thus, we can * print 965, or we can print 34, but we can't print 34.7 (the * decimal point takes up one character). bgrayson */ if (scaled_used == 0.0) snprintf (buf, 10, "0"); else { if (scaled_used < 0 && !metric_) snprintf (buf, 10, "-"); else if ( fabs(scaled_used) < 9.95 ) // 9.95 or above would get // rounded to 10.0, which is too wide. snprintf (buf, 10, "%.1f%s", scaled_used, scale); else snprintf (buf, 10, "%.0f%s", scaled_used, scale); } } else { if ( fabs(used_) < 99.95 ) snprintf( buf, 10, "%.1f", used_ ); else // drop the decimal if the string gets too long snprintf( buf, 10, "%.0f", used_ ); } parent_->clear( x_ - usedoffset_, y_ + height_ - parent_->textHeight(), usedoffset_ - onechar / 2, parent_->textHeight() + 1 ); parent_->setForeground( usedcolor_ ); parent_->drawString( x_ - (strlen( buf ) + 1 ) * onechar + 2, y_ + height_, buf ); lastused_ = used_; } void BitFieldMeter::drawBits( int mandatory ){ static int pass = 1; // pass = (pass + 1) % 2; int x1 = x_, w; w = (width_/2 - (numbits_+1)) / numbits_; for ( int i = 0 ; i < numbits_ ; i++ ){ if ( (bits_[i] != lastbits_[i]) || mandatory ){ if ( bits_[i] && pass ) parent_->setForeground( onColor_ ); else parent_->setForeground( offColor_ ); parent_->drawFilledRectangle( x1, y_, w, height_); } lastbits_[i] = bits_[i]; x1 += (w + 2); } } void BitFieldMeter::drawfields( int mandatory ){ int twidth, x = x_ + width_/2 + 4; if ( total_ == 0 ) return; for ( int i = 0 ; i < numfields_ ; i++ ){ /* Look for bogus values. */ if (fields_[i] < 0.0 && !metric_) { /* Only print a warning 5 times per meter, followed by a * message about no more warnings. */ numWarnings_ ++; if (numWarnings_ < 5) std::cerr << "Warning: meter " << name() << " had a negative value of " << fields_[i] << " for field " << i << std::endl; if (numWarnings_ == 5) std::cerr << "Future warnings from the " << name() << " meter will not " << "be displayed." << std::endl; } twidth = (int)fabs(((width_/2 - 3) * fields_[i]) / total_); if ( (i == numfields_ - 1) && ((x + twidth) != (x_ + width_)) ) twidth = width_ + x_ - x; if ( mandatory || (twidth != lastvals_[i]) || (x != lastx_[i]) ){ parent_->setForeground( colors_[i] ); parent_->setStippleN(i%4); parent_->drawFilledRectangle( x, y_, twidth, height_ ); parent_->setStippleN(0); /* Restore all-bits stipple. */ lastvals_[i] = twidth; lastx_[i] = x; if ( dousedlegends_ ) drawused( mandatory ); } x += twidth; } } void BitFieldMeter::checkevent( void ){ drawBits(); drawfields(); } void BitFieldMeter::setBits(int startbit, unsigned char values){ unsigned char mask = 1; for (int i = startbit ; i < startbit + 8 ; i++){ bits_[i] = values & mask; mask = mask << 1; } } void BitFieldMeter::setNumFields(int n){ numfields_ = n; delete[] fields_; delete[] colors_; delete[] lastvals_; delete[] lastx_; fields_ = new double[numfields_]; colors_ = new unsigned long[numfields_]; lastvals_ = new int[numfields_]; lastx_ = new int[numfields_]; total_ = 0; for ( int i = 0 ; i < numfields_ ; i++ ){ fields_[i] = 0.0; /* egcs 2.91.66 bug !? don't do this and */ lastvals_[i] = lastx_[i] = 0; /* that in a single statement or it'll */ /* overwrite too much with 0 ... */ /* Thomas Waldmann ( tw@com-ma.de ) */ } } bool BitFieldMeter::checkX(int x, int width) const { if ((x < x_) || (x + width < x_) || (x > x_ + width_) || (x + width > x_ + width_)){ std::cerr << "BitFieldMeter::checkX() : bad horiz values for meter : " << name() << std::endl; std::cerr <<"value "< len } xosview-1.20/bitfieldmeter.h000066400000000000000000000045201317735352700161460ustar00rootroot00000000000000// // Copyright (c) 1999, 2006 Thomas Waldmann (ThomasWaldmann@gmx.de) // based on work of Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // // #ifndef _BITFIELDMETER_H_ #define _BITFIELDMETER_H_ #include "meter.h" #include "xosview.h" #include "timer.h" class BitFieldMeter : public Meter { public: BitFieldMeter( XOSView *parent, int numBits = 1, int numfields = 1, const char *title = "", const char *bitlegend = "", const char *fieldlegend = "", int docaptions = 0, int dolegends = 0, int dousedlegends = 0 ); virtual ~BitFieldMeter( void ); virtual void drawfields( int mandatory = 0 ); void drawBits( int mandatory = 0 ); void setfieldcolor( int field, const char *color ); void setfieldcolor( int field, unsigned long color); void docaptions( int val ) { docaptions_ = val; } void dolegends( int val ) { dolegends_ = val; } void dousedlegends( int val ) { dousedlegends_ = val; } void reset( void ); void setUsed (double val, double total); void setBits(int startbit, unsigned char values); void draw( void ); void checkevent( void ); void disableMeter ( void ); virtual void checkResources( void ); protected: enum UsedType { INVALID_0, FLOAT, PERCENT, AUTOSCALE, INVALID_TAIL }; int numfields_; double *fields_; double total_, used_, lastused_; int *lastvals_, *lastx_; unsigned long *colors_; unsigned long usedcolor_; UsedType print_; int printedZeroTotalMesg_; int numWarnings_; bool metric_; int usedoffset_; unsigned long onColor_, offColor_; char *bits_, *lastbits_; int numbits_; void SetUsedFormat ( const char * const str ); void drawfieldlegend( void ); void drawused( int mandatory ); bool checkX(int x, int width) const; void setNumFields(int n); void setNumBits(int n); char *fieldLegend_; void setfieldlegend(const char *fieldlegend); private: Timer _timer; protected: void IntervalTimerStart() { _timer.start(); } void IntervalTimerStop() { _timer.stop(); } // Before, we simply called _timer.report(), which returns usecs. // However, it suffers from wrap/overflow/sign-bit problems, so // instead we use doubles for everything. double IntervalTimeInMicrosecs() { return _timer.report_usecs(); } double IntervalTimeInSecs() { return _timer.report_usecs()/1e6; } }; #endif xosview-1.20/bitmeter.cc000066400000000000000000000046471317735352700153120ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "bitmeter.h" BitMeter::BitMeter( XOSView *parent, const char *title, const char *legend, int numBits, int docaptions, int, int dousedlegends) : Meter( parent, title, legend, docaptions, dousedlegends, dousedlegends ), bits_(NULL), lastbits_(NULL), disabled_(false) { setNumBits(numBits); } BitMeter::~BitMeter( void ){ delete [] bits_; delete [] lastbits_; } void BitMeter::setNumBits(int n){ numbits_ = n; delete [] bits_; delete [] lastbits_; bits_ = new char[numbits_]; lastbits_ = new char[numbits_]; for ( int i = 0 ; i < numbits_ ; i++ ) bits_[i] = lastbits_[i] = 0; } void BitMeter::disableMeter ( void ) { disabled_ = true; onColor_ = parent_->allocColor ("gray"); offColor_ = onColor_; Meter::legend ("Disabled"); } void BitMeter::checkResources( void ){ Meter::checkResources(); } void BitMeter::checkevent( void ){ drawBits(); } void BitMeter::drawBits( int mandatory ){ static int pass = 1; // pass = (pass + 1) % 2; int x1 = x_ + 0, x2; for ( int i = 0 ; i < numbits_ ; i++ ){ if ( i != (numbits_ - 1) ) x2 = x_ + ((i + 1) * (width_+1)) / numbits_ - 1; else x2 = x_ + (width_+1) - 1; if ( (bits_[i] != lastbits_[i]) || mandatory ){ if ( bits_[i] && pass ) parent_->setForeground( onColor_ ); else parent_->setForeground( offColor_ ); parent_->drawFilledRectangle( x1, y_, x2 - x1, height_); } lastbits_[i] = bits_[i]; x1 = x2 + 2; } } void BitMeter::draw( void ){ parent_->lineWidth( 1 ); parent_->setForeground( parent_->foreground() ); parent_->drawFilledRectangle( x_ -1, y_ - 1, width_ + 2, height_ + 2 ); parent_->lineWidth( 0 ); if ( dolegends_ ){ parent_->setForeground( textcolor_ ); int offset; if ( dousedlegends_ ) offset = parent_->textWidth( "XXXXXXXXXX" ); else offset = parent_->textWidth( "XXXXXX" ); parent_->drawString( x_ - offset + 1, y_ + height_, title_ ); parent_->setForeground( onColor_ ); if(docaptions_) { parent_->drawString( x_, y_ - 5, legend_ ); } } drawBits( 1 ); } void BitMeter::setBits(int startbit, unsigned char values){ unsigned char mask = 1; for (int i = startbit ; i < startbit + 8 ; i++){ bits_[i] = values & mask; mask = mask << 1; } } xosview-1.20/bitmeter.h000066400000000000000000000015471317735352700151500ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _BITMETER_H_ #define _BITMETER_H_ #include "meter.h" #include "xosview.h" class BitMeter : public Meter { public: BitMeter( XOSView *parent, const char *title = "", const char *legend ="", int numBits = 1, int docaptions = 0, int dolegends = 0, int dousedlegends = 0 ); virtual ~BitMeter( void ); void checkevent( void ); void draw( void ); void disableMeter ( void ); int numBits(void) const { return numbits_; } void setNumBits(int n); void checkResources( void ); protected: unsigned long onColor_, offColor_; char *bits_, *lastbits_; int numbits_; bool disabled_; void setBits(int startbit, unsigned char values); void drawBits( int mandatory = 0 ); private: }; #endif xosview-1.20/bsd/000077500000000000000000000000001317735352700137255ustar00rootroot00000000000000xosview-1.20/bsd/MeterMaker.cc000066400000000000000000000102611317735352700162700ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "MeterMaker.h" #include "defines.h" #include "kernel.h" #include "loadmeter.h" #include "cpumeter.h" #include "memmeter.h" #include "swapmeter.h" #include "pagemeter.h" #include "netmeter.h" #include "diskmeter.h" #include "intmeter.h" #include "intratemeter.h" #include "btrymeter.h" #if defined(__i386__) || defined(__x86_64__) #include "coretemp.h" #endif #include "sensor.h" #include #include #include #include MeterMaker::MeterMaker(XOSView *xos) { _xos = xos; } void MeterMaker::makeMeters(void) { // Standard meters (usually added, but users could turn them off) if ( _xos->isResourceTrue("load") ) push(new LoadMeter(_xos)); if ( _xos->isResourceTrue("cpu") ) { bool single, both, all; unsigned int cpuCount = BSDCountCpus(); single = ( strncmp(_xos->getResource("cpuFormat"), "single", 2) == 0 ); both = ( strncmp(_xos->getResource("cpuFormat"), "both", 2) == 0 ); all = ( strncmp(_xos->getResource("cpuFormat"), "all", 2) == 0 ); if ( strncmp(_xos->getResource("cpuFormat"), "auto", 2) == 0 ) { if (cpuCount == 1 || cpuCount > 4) single = true; else all = true; } if (single || both) push(new CPUMeter(_xos, 0)); if (all || both) { for (unsigned int i = 1; i <= cpuCount; i++) push(new CPUMeter(_xos, i)); } } if ( _xos->isResourceTrue("mem") ) push(new MemMeter(_xos)); if ( _xos->isResourceTrue("swap") ) push(new SwapMeter(_xos)); if ( _xos->isResourceTrue("page") ) push(new PageMeter(_xos, atof(_xos->getResource("pageBandwidth")))); if ( _xos->isResourceTrue("net") ) push(new NetMeter(_xos, atof(_xos->getResource("netBandwidth")))); if ( _xos->isResourceTrue("disk") ) push(new DiskMeter(_xos, atof(_xos->getResource("diskBandwidth")))); if ( _xos->isResourceTrue("interrupts") ) push(new IntMeter(_xos)); if ( _xos->isResourceTrue("irqrate") ) push(new IrqRateMeter(_xos)); if ( _xos->isResourceTrue("battery") && BSDHasBattery() ) push(new BtryMeter(_xos)); #if defined(__i386__) || defined(__x86_64__) if ( _xos->isResourceTrue("coretemp") && CoreTemp::countCpus() > 0 ) { char caption[32]; snprintf(caption, 32, "ACT(\260C)/HIGH/%s", _xos->getResourceOrUseDefault( "coretempHighest", "100" ) ); const char *displayType = _xos->getResourceOrUseDefault("coretempDisplayType", "separate"); if (strncmp(displayType, "separate", 1) == 0) { char name[5]; for (uint i = 0; i < CoreTemp::countCpus(); i++) { snprintf(name, 5, "CPU%d", i); push(new CoreTemp(_xos, name, caption, i)); } } else if (strncmp(displayType, "average", 1) == 0) push(new CoreTemp(_xos, "CPU", caption, -1)); else if (strncmp(displayType, "maximum", 1) == 0) push(new CoreTemp(_xos, "CPU", caption, -2)); else { std::cerr << "Unknown value of coretempDisplayType: " << displayType << std::endl; _xos->done(1); } } #endif if ( _xos->isResourceTrue("bsdsensor") ) { char caption[16], l[8], s[16]; for (int i = 1 ; ; i++) { snprintf(s, 16, "bsdsensorHighest%d", i); float highest = atof( _xos->getResourceOrUseDefault(s, "100") ); snprintf(caption, 16, "ACT/HIGH/%f", highest); snprintf(s, 16, "bsdsensor%d", i); const char *name = _xos->getResourceOrUseDefault(s, NULL); if (!name || !*name) break; snprintf(s, 16, "bsdsensorHigh%d", i); const char *high = _xos->getResourceOrUseDefault(s, NULL); snprintf(s, 16, "bsdsensorLow%d", i); const char *low = _xos->getResourceOrUseDefault(s, NULL); snprintf(s, 16, "bsdsensorLabel%d", i); snprintf(l, 8, "SEN%d", i); const char *label = _xos->getResourceOrUseDefault(s, l); push(new BSDSensor(_xos, name, high, low, label, caption, i)); } } } xosview-1.20/bsd/MeterMaker.h000066400000000000000000000014241317735352700161330ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _MeterMaker_h #define _MeterMaker_h #include "pllist.h" #include "meter.h" #include "xosview.h" class MeterMaker : public PLList { public: MeterMaker(XOSView *xos); void makeMeters(void); private: XOSView *_xos; }; #endif xosview-1.20/bsd/btrymeter.cc000066400000000000000000000046411317735352700162560ustar00rootroot00000000000000// // Copyright (c) 2013 by Tomi Tapper ( tomi.o.tapper@student.jyu.fi ) // // Based on linux/btrymeter.cc: // Copyright (c) 1997, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "btrymeter.h" #include "kernel.h" #include BtryMeter::BtryMeter( XOSView *parent ) : FieldMeter( parent, 2, "BTRY", "CHRG/USED", 1, 1, 0 ) { old_state_ = 255; } BtryMeter::~BtryMeter( void ) { } void BtryMeter::checkResources( void ) { FieldMeter::checkResources(); leftcolor_ = parent_->allocColor( parent_->getResource("batteryLeftColor") ); usedcolor_ = parent_->allocColor( parent_->getResource("batteryUsedColor") ); chargecolor_ = parent_->allocColor( parent_->getResource("batteryChargeColor") ); fullcolor_ = parent_->allocColor( parent_->getResource("batteryFullColor") ); lowcolor_ = parent_->allocColor( parent_->getResource("batteryLowColor") ); critcolor_ = parent_->allocColor( parent_->getResource("batteryCritColor") ); nonecolor_ = parent_->allocColor( parent_->getResource("batteryNoneColor") ); setfieldcolor(0, leftcolor_); setfieldcolor(1, usedcolor_); priority_ = atoi( parent_->getResource("batteryPriority") ); SetUsedFormat( parent_->getResource("batteryUsedFormat") ); } void BtryMeter::checkevent( void ) { getstats(); drawfields(); } void BtryMeter::getstats( void ) { int remaining; unsigned int state; BSDGetBatteryInfo(&remaining, &state); if (state != old_state_) { if (state == XOSVIEW_BATT_NONE) { // no battery present setfieldcolor(0, nonecolor_); legend("NONE/NONE"); } else if (state & XOSVIEW_BATT_FULL) { // full battery setfieldcolor(0, fullcolor_); legend("CHRG/FULL"); } else { // present, not full if (state & XOSVIEW_BATT_CRITICAL) // critical charge setfieldcolor(0, critcolor_); else if (state & XOSVIEW_BATT_LOW) // low charge setfieldcolor(0, lowcolor_); else { // above low, below full if (state & XOSVIEW_BATT_CHARGING) // is charging setfieldcolor(0, chargecolor_); else setfieldcolor(0, leftcolor_); } // legend tells if charging or discharging if (state & XOSVIEW_BATT_CHARGING) legend("CHRG/AC"); else legend("CHRG/USED"); } drawlegend(); parent_->draw(); // make sure the field changes colour too old_state_ = state; } total_ = 100.0; fields_[0] = remaining; fields_[1] = total_ - remaining; setUsed(fields_[0], total_); } xosview-1.20/bsd/btrymeter.h000066400000000000000000000013601317735352700161130ustar00rootroot00000000000000// // Copyright (c) 2013 by Tomi Tapper ( tomi.o.tapper@student.jyu.fi ) // // Based on linux/btrymeter.h: // Copyright (c) 1997, 2005, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _BTRYMETER_H_ #define _BTRYMETER_H_ #include "fieldmeter.h" #include "xosview.h" class BtryMeter : public FieldMeter { public: BtryMeter( XOSView *parent ); ~BtryMeter( void ); const char *name( void ) const { return "BtryMeter"; } void checkevent( void ); void checkResources( void ); protected: void getstats( void ); private: unsigned long leftcolor_, usedcolor_, chargecolor_, fullcolor_, lowcolor_, critcolor_, nonecolor_; unsigned int old_state_; }; #endif xosview-1.20/bsd/coretemp.cc000066400000000000000000000063451317735352700160620ustar00rootroot00000000000000// // Copyright (c) 2008 by Tomi Tapper // // Read coretemp reading with sysctl and display actual temperature. // If actual >= high, actual temp changes color to indicate alarm. // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // // #include "coretemp.h" #include "kernel.h" #include #include #include CoreTemp::CoreTemp( XOSView *parent, const char *label, const char *caption, int cpu) : FieldMeter( parent, 3, label, caption, 1, 1, 1 ) { metric_ = true; cpu_ = cpu; cpucount_ = countCpus(); temps_ = (float *)calloc(cpucount_, sizeof(float)); } CoreTemp::~CoreTemp( void ) { free(temps_); } void CoreTemp::checkResources( void ) { FieldMeter::checkResources(); actcolor_ = parent_->allocColor( parent_->getResource( "coretempActColor" ) ); highcolor_ = parent_->allocColor( parent_->getResource( "coretempHighColor" ) ); setfieldcolor( 0, actcolor_ ); setfieldcolor( 1, parent_->getResource( "coretempIdleColor") ); setfieldcolor( 2, highcolor_ ); priority_ = atoi( parent_->getResource( "coretempPriority" ) ); const char *highest = parent_->getResourceOrUseDefault( "coretempHighest", "100" ); total_ = atoi( highest ); const char *high = parent_->getResourceOrUseDefault( "coretempHigh", NULL ); SetUsedFormat( parent_->getResource( "coretempUsedFormat" ) ); // Get tjMax here and use as total. float total = -300.0; float *tjmax = (float *)calloc(cpucount_, sizeof(float)); BSDGetCPUTemperature(temps_, tjmax); for (int i = 0; i < cpucount_; i++) { if (tjmax[i] > total) total = tjmax[i]; } free(tjmax); if (total > 0.0) total_ = total; char l[32]; if (!high) { high_ = total_; snprintf(l, 32, "ACT(\260C)/HIGH/%d", (int)total_); } else { high_ = atoi( high ); snprintf(l, 32, "ACT(\260C)/%d/%d", (int)high_, (int)total_); } legend(l); } unsigned int CoreTemp::countCpus( void ) { return BSDGetCPUTemperature(NULL, NULL); } void CoreTemp::checkevent( void ) { getcoretemp(); drawfields(); } void CoreTemp::getcoretemp( void ) { BSDGetCPUTemperature(temps_, NULL); fields_[0] = 0.0; if ( cpu_ >= 0 && cpu_ < cpucount_ ) { // one core fields_[0] = temps_[cpu_]; } else if ( cpu_ == -1 ) { // average float tempval = 0.0; for (int i = 0; i < cpucount_; i++) tempval += temps_[i]; fields_[0] = tempval / (float)cpucount_; } else if ( cpu_ == -2 ) { // maximum float tempval = -300.0; for (int i = 0; i < cpucount_; i++) { if (temps_[i] > tempval) tempval = temps_[i]; } fields_[0] = tempval; } else { // should not happen std::cerr << "Unknown CPU core number in coretemp." << std::endl; parent_->done(1); return; } setUsed(fields_[0], total_); if (fields_[0] < 0) fields_[0] = 0; fields_[1] = high_ - fields_[0]; fields_[2] = total_ - fields_[1] - fields_[0]; if (fields_[0] > total_) fields_[0] = total_; if (fields_[2] < 0) fields_[2] = 0; if (fields_[1] < 0) { // alarm: T > high fields_[1] = 0; if (colors_[0] != highcolor_) { setfieldcolor( 0, highcolor_ ); drawlegend(); } } else { if (colors_[0] != actcolor_) { setfieldcolor( 0, actcolor_ ); drawlegend(); } } } xosview-1.20/bsd/coretemp.h000066400000000000000000000014011317735352700157100ustar00rootroot00000000000000// // Copyright (c) 2008 by Tomi Tapper // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // // #ifndef _CORETEMP_H_ #define _CORETEMP_H_ #include "fieldmeter.h" #include "xosview.h" class CoreTemp : public FieldMeter { public: CoreTemp( XOSView *parent, const char *label, const char *caption, int cpu); ~CoreTemp( void ); const char *name( void ) const { return "CoreTemp"; } void checkevent( void ); void checkResources( void ); static unsigned int countCpus( void ); protected: void getcoretemp( void ); private: int cpu_, cpucount_; float high_, *temps_; unsigned long actcolor_, highcolor_; }; #endif xosview-1.20/bsd/cpumeter.cc000066400000000000000000000040331317735352700160600ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "cpumeter.h" #include "kernel.h" #include #include #include CPUMeter::CPUMeter( XOSView *parent, unsigned int nbr ) : FieldMeterGraph( parent, 5, "CPU", "USR/NICE/SYS/INT/FREE" ) { nbr_ = nbr; cpuindex_ = 0; bzero(cputime_, 10 * sizeof(cputime_[0][0])); BSDCPUInit(); char t[8] = "CPU"; if (nbr_ > 0) snprintf(t, 8, "CPU%d", nbr_ - 1); title(t); } CPUMeter::~CPUMeter( void ) { } void CPUMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("cpuUserColor") ); setfieldcolor( 1, parent_->getResource("cpuNiceColor") ); setfieldcolor( 2, parent_->getResource("cpuSystemColor") ); setfieldcolor( 3, parent_->getResource("cpuInterruptColor") ); setfieldcolor( 4, parent_->getResource("cpuFreeColor") ); priority_ = atoi( parent_->getResource("cpuPriority") ); dodecay_ = parent_->isResourceTrue("cpuDecay"); useGraph_ = parent_->isResourceTrue("cpuGraph"); SetUsedFormat( parent_->getResource("cpuUsedFormat") ); } void CPUMeter::checkevent( void ) { getcputime(); drawfields(); } void CPUMeter::getcputime( void ) { uint64_t tempCPU[CPUSTATES]; total_ = 0; BSDGetCPUTimes(tempCPU, nbr_); int oldindex = (cpuindex_ + 1) % 2; for (int i = 0; i < CPUSTATES; i++) { cputime_[cpuindex_][i] = tempCPU[i]; fields_[i] = cputime_[cpuindex_][i] - cputime_[oldindex][i]; total_ += fields_[i]; } if (total_) { setUsed(total_ - fields_[4], total_); cpuindex_ = (cpuindex_ + 1) % 2; } } xosview-1.20/bsd/cpumeter.h000066400000000000000000000022171317735352700157240ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _CPUMETER_H_ #define _CPUMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "defines.h" // for CPUSTATES #if defined(XOSVIEW_NETBSD) || defined(XOSVIEW_OPENBSD) #include #else #include #endif class CPUMeter : public FieldMeterGraph { public: CPUMeter( XOSView *parent, unsigned int nbr ); ~CPUMeter( void ); const char *name( void ) const { return "CPUMeter"; } void checkevent( void ); void checkResources( void ); protected: void getcputime( void ); private: uint64_t cputime_[2][CPUSTATES]; unsigned int cpuindex_, nbr_; }; #endif xosview-1.20/bsd/defines.h000066400000000000000000000027161317735352700155210ustar00rootroot00000000000000#ifndef __defines_h__ #define __defines_h__ #include /* The BSD variant. */ #if defined __FreeBSD__ #define XOSVIEW_FREEBSD #elif defined __NetBSD__ #define XOSVIEW_NETBSD #elif defined __OpenBSD__ #define XOSVIEW_OPENBSD #elif defined __DragonFly__ #define XOSVIEW_DFBSD #endif #if !( defined(XOSVIEW_FREEBSD) || \ defined(XOSVIEW_NETBSD) || \ defined(XOSVIEW_OPENBSD) || \ defined(XOSVIEW_DFBSD) ) #error "Unsupported BSD variant." #endif /* UVM appeared on NetBSD 1.4 and OpenBSD 2.9. */ #if ( defined(__NetBSD__) && __NetBSD_Version__ >= 104000000 ) || \ ( defined(__OpenBSD__) && OpenBSD >= 200105 ) #define HAVE_UVM 1 #endif /* swapctl appeared on NetBSD 1.3. and OpenBSD 2.6 */ #if ( defined(__NetBSD__) && __NetBSD_Version__ >= 103000000 ) || \ ( defined(__OpenBSD__) && OpenBSD >= 199912 ) #define HAVE_SWAPCTL 1 #endif /* devstat appeared on FreeBSD 3.0. */ #if ( defined(__FreeBSD__) && __FreeBSD_version >= 300005 ) || \ defined(__DragonFly__) #define HAVE_DEVSTAT 1 #endif /* kvm_getswapinfo appeared on FreeBSD 4.0 */ #if ( defined(__FreeBSD__) && __FreeBSD_version >= 400000 ) || \ defined(__DragonFly__) #define USE_KVM_GETSWAPINFO 1 #endif /* Helper defines for battery meter. */ #define XOSVIEW_BATT_NONE 0 #define XOSVIEW_BATT_CHARGING 1 #define XOSVIEW_BATT_DISCHARGING 2 #define XOSVIEW_BATT_FULL 4 #define XOSVIEW_BATT_LOW 8 #define XOSVIEW_BATT_CRITICAL 16 #endif xosview-1.20/bsd/diskmeter.cc000066400000000000000000000057321317735352700162320ustar00rootroot00000000000000// // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "diskmeter.h" #include "kernel.h" #include #include DiskMeter::DiskMeter( XOSView *parent, double max ) : FieldMeterGraph( parent, 3, "DISK", "READ/WRITE/IDLE" ) { dodecay_ = 0; maxBandwidth_ = max; total_ = max; if (!BSDDiskInit()) disableMeter(); /* Since at the first call, it will look like we transferred a * gazillion bytes, let's reset total_ again and do another * call. This will force total_ to be something reasonable. */ getstats(); total_ = max; getstats(); IntervalTimerStart(); /* By doing this check, we eliminate the startup situation where * all fields are 0, and total is 0, leading to nothing being drawn * on the meter. So, make it look like nothing was transferred, * out of a total of 1 bytes. */ fields_[0] = fields_[1] = 0.0; total_ = 1.0; fields_[2] = total_; } DiskMeter::~DiskMeter( void ) { } void DiskMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("diskReadColor") ); setfieldcolor( 1, parent_->getResource("diskWriteColor") ); setfieldcolor( 2, parent_->getResource("diskIdleColor") ); priority_ = atoi( parent_->getResource("diskPriority") ); dodecay_ = parent_->isResourceTrue("diskDecay"); useGraph_ = parent_->isResourceTrue("diskGraph"); SetUsedFormat( parent_->getResource("diskUsedFormat") ); } void DiskMeter::checkevent( void ) { getstats(); drawfields(); } void DiskMeter::getstats( void ) { uint64_t reads = 0, writes = 0; // Reset to desired full-scale settings. total_ = maxBandwidth_; IntervalTimerStop(); BSDGetDiskXFerBytes(&reads, &writes); /* Adjust this to bytes/second. */ #if defined(HAVE_DEVSTAT) fields_[0] = reads / IntervalTimeInSecs(); fields_[1] = writes / IntervalTimeInSecs(); #else fields_[0] = (reads - prevreads_) / IntervalTimeInSecs(); fields_[1] = (writes - prevwrites_) / IntervalTimeInSecs(); prevreads_ = reads; prevwrites_ = writes; #endif IntervalTimerStart(); /* Adjust in case of first call. */ if (fields_[0] < 0.0) fields_[0] = 0.0; if (fields_[1] < 0.0) fields_[1] = 0.0; /* Adjust total_ if needed. */ if (fields_[0] + fields_[1] > total_) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - (fields_[0] + fields_[1]); if (fields_[0] < 0.0) warnx("diskmeter: fields[0] of %f is < 0!", fields_[0]); if (fields_[1] < 0.0) warnx("diskmeter: fields[1] of %f is < 0!", fields_[1]); if (fields_[2] < 0.0) warnx("diskmeter: fields[2] of %f is < 0!", fields_[2]); setUsed(fields_[0] + fields_[1], total_); } xosview-1.20/bsd/diskmeter.h000066400000000000000000000017061317735352700160710ustar00rootroot00000000000000// // NetBSD port: // Copyright (c) 1995,1996,1997 Brian Grayson(bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _DISKMETER_H_ #define _DISKMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "defines.h" class DiskMeter : public FieldMeterGraph { public: DiskMeter( XOSView *parent, double max ); ~DiskMeter( void ); const char *name( void ) const { return "DiskMeter"; } void checkevent( void ); void checkResources( void ); protected: void getstats( void ); private: #ifndef HAVE_DEVSTAT uint64_t prevreads_, prevwrites_; #endif double maxBandwidth_; }; #endif xosview-1.20/bsd/intmeter.cc000066400000000000000000000051021317735352700160610ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #include "intmeter.h" #include "kernel.h" #include #include #include IntMeter::IntMeter( XOSView *parent, const char *, const char *, int dolegends, int dousedlegends ) : BitMeter( parent, "INTS", "IRQs", 1, dolegends, dousedlegends ) { if (!BSDIntrInit()) disableMeter(); irqcount_ = BSDNumInts(); irqs_ = (uint64_t *)calloc(irqcount_ + 1, sizeof(uint64_t)); lastirqs_ = (uint64_t *)calloc(irqcount_ + 1, sizeof(uint64_t)); inbrs_ = (unsigned int *)calloc(irqcount_ + 1, sizeof(int)); updateirqcount(true); } IntMeter::~IntMeter( void ) { free(irqs_); free(lastirqs_); free(inbrs_); } void IntMeter::checkevent( void ) { getirqs(); for (uint i = 0 ; i <= irqcount_ ; i++) { if (inbrs_[i] != 0) { if (realintnum_.find(i) == realintnum_.end()) { // new interrupt number updateirqcount(); return; } bits_[realintnum_[i]] = ((irqs_[i] - lastirqs_[i]) != 0); lastirqs_[i] = irqs_[i]; } } bzero(inbrs_, (irqcount_ + 1) * sizeof(inbrs_[0])); bzero(irqs_, (irqcount_ + 1) * sizeof(irqs_[0])); BitMeter::checkevent(); } void IntMeter::checkResources( void ) { BitMeter::checkResources(); onColor_ = parent_->allocColor( parent_->getResource( "intOnColor" ) ); offColor_ = parent_->allocColor( parent_->getResource( "intOffColor" ) ); priority_ = atoi( parent_->getResource( "intPriority" ) ); } void IntMeter::getirqs( void ) { BSDGetIntrStats(irqs_, inbrs_); } void IntMeter::updateirqcount( bool init ) { int count = 16; if (init) { getirqs(); for (int i = 0; i < 16; i++) realintnum_[i] = i; } for (uint i = 16; i <= irqcount_; i++) { if (inbrs_[i] != 0) { realintnum_[i] = count++; inbrs_[i] = 0; } } setNumBits(count); // Build the legend. std::ostringstream os; os << "0"; if (realintnum_.upper_bound(15) == realintnum_.end()) // only 16 ints os << "-15"; else { int prev = 15, prev2 = 14; for (std::map::const_iterator it = realintnum_.upper_bound(15), end = realintnum_.end(); it != end; ++it) { if ( &*it == &*realintnum_.rbegin() ) { // last element if (it->first == prev + 1) os << "-" ; else { if (prev == prev2 + 1) os << "-" << prev; os << "," ; } os << it->first; } else { if (it->first != prev + 1) { if (prev == prev2 + 1) os << "-" << prev; os << "," << it->first ; } } prev2 = prev; prev = it->first; } os << std::ends; } legend(os.str().c_str()); } xosview-1.20/bsd/intmeter.h000066400000000000000000000013641317735352700157310ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _INTMETER_H_ #define _INTMETER_H_ #include "bitmeter.h" #include "xosview.h" #include class IntMeter : public BitMeter { public: IntMeter( XOSView *parent, const char *title = "", const char *legend = "", int dolegends = 0, int dousedlegends = 0 ); ~IntMeter( void ); const char *name( void ) const { return "IntMeter"; } void checkevent( void ); void checkResources( void ); private: uint64_t *irqs_, *lastirqs_; unsigned int *inbrs_; unsigned int irqcount_; std::map realintnum_; protected: void getirqs( void ); void updateirqcount( bool init = false ); }; #endif xosview-1.20/bsd/intratemeter.cc000066400000000000000000000037751317735352700167530ustar00rootroot00000000000000// // Copyright (c) 1999 by Brian Grayson (bgrayson@netbsd.org) // // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "intratemeter.h" #include "kernel.h" #include #include #include IrqRateMeter::IrqRateMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "IRQs", "IRQs per sec/IDLE", 1, 1, 0 ) { if (!BSDIntrInit()) { warnx("The kernel does not seem to have the symbols needed for the IrqRateMeter."); warnx("The IrqRateMeter has been disabled."); disableMeter(); } irqcount_ = BSDNumInts(); irqs_ = (uint64_t *)calloc(irqcount_ + 1, sizeof(uint64_t)); lastirqs_ = (uint64_t *)calloc(irqcount_ + 1, sizeof(uint64_t)); } IrqRateMeter::~IrqRateMeter( void ) { free(irqs_); free(lastirqs_); } void IrqRateMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("irqrateUsedColor") ); setfieldcolor( 1, parent_->getResource("irqrateIdleColor") ); priority_ = atoi( parent_->getResource("irqratePriority") ); dodecay_ = parent_->isResourceTrue("irqrateDecay"); useGraph_ = parent_->isResourceTrue("irqrateGraph"); SetUsedFormat( parent_->getResource("irqrateUsedFormat") ); total_ = 2000; BSDGetIntrStats(lastirqs_, NULL); } void IrqRateMeter::checkevent( void ) { getinfo(); drawfields(); } void IrqRateMeter::getinfo( void ) { int delta = 0; IntervalTimerStop(); BSDGetIntrStats(irqs_, NULL); for (uint i = 0; i <= irqcount_; i++) { delta += irqs_[i] - lastirqs_[i]; lastirqs_[i] = irqs_[i]; } bzero(irqs_, (irqcount_ + 1) * sizeof(irqs_[0])); /* Scale delta by the priority. */ fields_[0] = delta / IntervalTimeInSecs(); // Bump total_, if needed. if (fields_[0] > total_) total_ = fields_[0]; setUsed(fields_[0], total_); IntervalTimerStart(); } xosview-1.20/bsd/intratemeter.h000066400000000000000000000014521317735352700166030ustar00rootroot00000000000000// // Copyright (c) 1999 by Brian Grayson (bgrayson@netbsd.org) // // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _IRQRATEMETER_H_ #define _IRQRATEMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class IrqRateMeter : public FieldMeterGraph { public: IrqRateMeter( XOSView *parent ); ~IrqRateMeter( void ); const char *name( void ) const { return "IrqRateMeter"; } void checkevent( void ); void checkResources( void ); private: uint64_t *irqs_, *lastirqs_; unsigned int irqcount_; protected: void getinfo( void ); }; #endif xosview-1.20/bsd/kernel.cc000066400000000000000000001476471317735352700155370ustar00rootroot00000000000000// // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file contains code from the NetBSD project, which is covered // by the standard BSD license. // Dummy device ignore code by : David Cuka (dcuka@intgp1.ih.att.com) // The OpenBSD interrupt meter code was written by Oleg Safiullin // (form@vs.itam.nsc.ru). // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "kernel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(XOSVIEW_DFBSD) #define _KERNEL_STRUCTURES #include #endif #if defined(XOSVIEW_FREEBSD) || defined(XOSVIEW_DFBSD) static const char ACPIDEV[] = "/dev/acpi"; static const char APMDEV[] = "/dev/apm"; static int maxcpus = 1; #include #include #include #include #endif #if defined(XOSVIEW_NETBSD) #include #include #include #include #include static int mib_cpt[2] = { CTL_KERN, KERN_CP_TIME }; static int mib_dsk[3] = { CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl) }; #endif #if defined(XOSVIEW_OPENBSD) #include #include #include #include #include static int mib_spd[2] = { CTL_HW, HW_CPUSPEED }; static int mib_cpt[2] = { CTL_KERN, KERN_CPTIME }; static int mib_cpt2[3] = { CTL_KERN, KERN_CPTIME2, 0 }; static int mib_ifl[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; #endif #if defined(XOSVIEW_OPENBSD) || defined(XOSVIEW_DFBSD) #include static int mib_sen[5] = { CTL_HW, HW_SENSORS }; #endif #if defined(HAVE_DEVSTAT) #include #endif #if defined(HAVE_UVM) #include #include #include #include #ifdef VM_UVMEXP2 static int mib_uvm[2] = { CTL_VM, VM_UVMEXP2 }; #else static int mib_uvm[2] = { CTL_VM, VM_UVMEXP }; #endif #else #include #endif #if defined(HAVE_SWAPCTL) #include #endif // ------------------------ local variables ---------------------------------- // This single kvm_t is shared by all of the kvm routines. kvm_t* kd = NULL; // This struct has the list of all the symbols we want from the kernel. static struct nlist nlst[] = { // We put a dummy symbol for a don't care, and ignore warnings about // this later on. This keeps the indices within the nlist constant. #define DUMMY_SYM "dummy_sym" #if defined(XOSVIEW_OPENBSD) { "_disklist" }, #define DISKLIST_SYM_INDEX 0 #else { DUMMY_SYM }, #define DUMMY_0 #endif #if defined(XOSVIEW_NETBSD) { "_allevents" }, #define ALLEVENTS_SYM_INDEX 1 { "_bufmem" }, #define BUFMEM_SYM_INDEX 2 #else { DUMMY_SYM }, #define DUMMY_1 { DUMMY_SYM }, #define DUMMY_2 #endif #if defined(XOSVIEW_FREEBSD) { "_intrnames" }, #define INTRNAMES_SYM_INDEX 3 # if __FreeBSD_version >= 900040 { "_sintrnames" }, # else { "_eintrnames" }, # endif #define EINTRNAMES_SYM_INDEX 4 { "_intrcnt" }, #define INTRCNT_SYM_INDEX 5 # if __FreeBSD_version >= 900040 { "_sintrcnt" }, # else { "_eintrcnt" }, # endif #define EINTRCNT_SYM_INDEX 6 #endif { NULL } }; static char kernelFileName[_POSIX2_LINE_MAX]; // ------------------------ utility functions -------------------------------- // The following is an error-checking form of kvm_read. In addition // it uses kd as the implicit kernel-file to read. Saves typing. // Since this is C++, it's an inline function rather than a macro. static inline void safe_kvm_read(unsigned long kernel_addr, void* user_addr, size_t nbytes) { /* Check for obvious bad symbols (i.e., from /netbsd when we * booted off of /netbsd.old), such as symbols that reference * 0x00000000 (or anywhere in the first 256 bytes of memory). */ int retval = 0; if ( (kernel_addr & 0xffffff00) == 0 ) errx(EX_SOFTWARE, "safe_kvm_read() was attempted on EA %#lx.", kernel_addr); if ( (retval = kvm_read(kd, kernel_addr, user_addr, nbytes)) == -1 ) err(EX_SOFTWARE, "kvm_read() of kernel address %#lx", kernel_addr); if (retval != (int)nbytes) warn("safe_kvm_read(%#lx) returned %d bytes, not %d", kernel_addr, retval, (int)nbytes); } // This version uses the symbol offset in the nlst variable, to make it // a little more convenient. BCG static inline void safe_kvm_read_symbol(int nlstOffset, void* user_addr, size_t nbytes) { safe_kvm_read(nlst[nlstOffset].n_value, user_addr, nbytes); } int ValidSymbol(int index) { return ( (nlst[index].n_value & 0xffffff00) != 0 ); } int SymbolValue(int index) { return nlst[index].n_value; } void BSDInit() { kernelFileName[0] = '\0'; } void SetKernelName(const char* kernelName) { if (strlen(kernelName) >= _POSIX2_LINE_MAX) errx(EX_OSFILE, "Kernel file name of '%s' is too long.", kernelName); strncpy(kernelFileName, kernelName, _POSIX2_LINE_MAX); } void OpenKDIfNeeded() { char errstring[_POSIX2_LINE_MAX]; if (kd) return; // kd is non-NULL, so it has been initialized. BCG /* Open it read-only, for a little added safety. */ /* If the first character of kernelFileName is not '\0', then use * that kernel file. Otherwise, use the default kernel, by * specifying NULL. */ if ((kd = kvm_openfiles((kernelFileName[0] ? kernelFileName : NULL), NULL, NULL, O_RDONLY, errstring)) == NULL) err(EX_OSFILE, "OpenKDIfNeeded(): %s", errstring); // Parenthetical note: FreeBSD kvm_openfiles() uses getbootfile() to get // the correct kernel file if the 1st arg is NULL. As far as I can see, // one should always use NULL in FreeBSD, but I suppose control is never a // bad thing... (pavel 21-Jan-1998) /* Now grab the symbol offsets for the symbols that we want. */ if (kvm_nlist(kd, nlst) < 0) err(EX_OSERR, "Could not get kvm symbols"); // Look at all of the returned symbols, and check for bad lookups. // (This may be unnecessary, but better to check than not to... ) struct nlist *nlp = nlst; while (nlp && nlp->n_name) { if ( strncmp(nlp->n_name, DUMMY_SYM, strlen(DUMMY_SYM))) { if ( nlp->n_type == 0 || nlp->n_value == 0 ) #if defined(XOSVIEW_FREEBSD) && defined(__alpha__) /* XXX: this should be properly fixed. */ ; #else warnx("kvm_nlist() lookup failed for symbol '%s'.", nlp->n_name); #endif } nlp++; } } int BSDGetCPUSpeed() { size_t size; int cpu_speed = 0; #if defined(XOSVIEW_FREEBSD) char name[25]; int speed = 0, cpus = BSDCountCpus(), avail_cpus = 0; size = sizeof(speed); for (int i = 0; i < cpus; i++) { snprintf(name, 25, "dev.cpu.%d.freq", i); if ( sysctlbyname(name, &speed, &size, NULL, 0) == 0 ) { // count only cpus with individual freq available cpu_speed += speed; avail_cpus++; } } if (avail_cpus > 1) cpu_speed /= avail_cpus; #elif defined(XOSVIEW_OPENBSD) size = sizeof(cpu_speed); if ( sysctl(mib_spd, 2, &cpu_speed, &size, NULL, 0) < 0 ) err(EX_OSERR, "syscl hw.cpuspeed failed"); #else /* XOSVIEW_NETBSD || XOSVIEW_DFBSD */ uint64_t speed = 0; size = sizeof(speed); #if defined(XOSVIEW_NETBSD) if ( sysctlbyname("machdep.tsc_freq", &speed, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl machdep.tsc_freq failed"); #else /* XOSVIEW_DFBSD */ if ( sysctlbyname("hw.tsc_frequency", &speed, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl hw.tsc_frequency failed"); #endif cpu_speed = speed / 1000000; #endif return cpu_speed; } // -------------------- PageMeter & MemMeter functions ----------------------- void BSDPageInit() { OpenKDIfNeeded(); } /* meminfo[5] = { active, inactive, wired, cached, free } */ /* pageinfo[2] = { pages_in, pages_out } */ void BSDGetPageStats(uint64_t *meminfo, uint64_t *pageinfo) { #if defined(HAVE_UVM) #ifdef VM_UVMEXP2 struct uvmexp_sysctl uvm; #else struct uvmexp uvm; #endif size_t size = sizeof(uvm); if ( sysctl(mib_uvm, 2, &uvm, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl vm.uvmexp failed"); if (meminfo) { // UVM excludes kernel memory -> assume it is active mem meminfo[0] = (uint64_t)(uvm.npages - uvm.inactive - uvm.wired - uvm.free) * uvm.pagesize; meminfo[1] = (uint64_t)uvm.inactive * uvm.pagesize; meminfo[2] = (uint64_t)uvm.wired * uvm.pagesize; // cache is already included in active and inactive memory and // there's no way to know how much is in which -> disable cache meminfo[3] = 0; meminfo[4] = (uint64_t)uvm.free * uvm.pagesize; } if (pageinfo) { pageinfo[0] = (uint64_t)uvm.pgswapin; pageinfo[1] = (uint64_t)uvm.pgswapout; } #else /* HAVE_UVM */ struct vmmeter vm; #if defined(XOSVIEW_FREEBSD) size_t size = sizeof(unsigned int); #define GET_VM_STATS(name) \ sysctlbyname("vm.stats.vm." #name, &vm.name, &size, NULL, 0) GET_VM_STATS(v_active_count); GET_VM_STATS(v_inactive_count); GET_VM_STATS(v_wire_count); GET_VM_STATS(v_cache_count); GET_VM_STATS(v_free_count); GET_VM_STATS(v_page_size); GET_VM_STATS(v_vnodepgsin); GET_VM_STATS(v_vnodepgsout); GET_VM_STATS(v_swappgsin); GET_VM_STATS(v_swappgsout); #undef GET_VM_STATS #else /* XOSVIEW_DFBSD */ struct vmstats vms; size_t size = sizeof(vms); if ( sysctlbyname("vm.vmstats", &vms, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl vm.vmstats failed"); size = sizeof(vm); if ( sysctlbyname("vm.vmmeter", &vm, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl vm.vmmeter failed"); #endif if (meminfo) { #if defined(XOSVIEW_FREEBSD) meminfo[0] = (uint64_t)vm.v_active_count * vm.v_page_size; meminfo[1] = (uint64_t)vm.v_inactive_count * vm.v_page_size; meminfo[2] = (uint64_t)vm.v_wire_count * vm.v_page_size; meminfo[3] = (uint64_t)vm.v_cache_count * vm.v_page_size; meminfo[4] = (uint64_t)vm.v_free_count * vm.v_page_size; #else /* XOSVIEW_DFBSD */ meminfo[0] = (uint64_t)vms.v_active_count * vms.v_page_size; meminfo[1] = (uint64_t)vms.v_inactive_count * vms.v_page_size; meminfo[2] = (uint64_t)vms.v_wire_count * vms.v_page_size; meminfo[3] = (uint64_t)vms.v_cache_count * vms.v_page_size; meminfo[4] = (uint64_t)vms.v_free_count * vms.v_page_size; #endif } if (pageinfo) { pageinfo[0] = (uint64_t)vm.v_vnodepgsin + (uint64_t)vm.v_swappgsin; pageinfo[1] = (uint64_t)vm.v_vnodepgsout + (uint64_t)vm.v_swappgsout; } #endif } // ------------------------ CPUMeter functions ------------------------------- void BSDCPUInit() { OpenKDIfNeeded(); #if defined(XOSVIEW_FREEBSD) size_t size = sizeof(maxcpus); if ( sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl kern.smp.maxcpus failed"); #elif defined(XOSVIEW_DFBSD) if ( kinfo_get_cpus(&maxcpus) ) err(EX_OSERR, "kinfo_get_cpus() failed"); #endif } void BSDGetCPUTimes(uint64_t *timeArray, unsigned int cpu) { // timeArray is CPUSTATES long. // cpu is the number of CPU to return, starting from 1. If cpu == 0, // return aggregate times for all CPUs. // All BSDs have separate calls for aggregate and separate times. Only // OpenBSD returns one CPU per call, others return all at once. if (!timeArray) err(EX_SOFTWARE, "BSDGetCPUTimes(): passed pointer was null."); size_t size; #if defined(XOSVIEW_DFBSD) size = sizeof(struct kinfo_cputime); struct kinfo_cputime *times = (struct kinfo_cputime *)calloc(maxcpus + 1, size); #elif defined(XOSVIEW_NETBSD) size = CPUSTATES * sizeof(uint64_t); uint64_t *times = (uint64_t*)calloc(BSDCountCpus() + 1, size); #elif defined(XOSVIEW_FREEBSD) size = CPUSTATES * sizeof(long); long *times = (long*)calloc(maxcpus + 1, size); #else // XOSVIEW_OPENBSD uint64_t *times = (uint64_t*)calloc(CPUSTATES, sizeof(uint64_t)); #endif // this array will have aggregate values at 0, then each CPU (except on // OpenBSD), so that cpu can be used as index if (!times) err(EX_OSERR, "BSDGetCPUTimes(): malloc failed"); #if defined(XOSVIEW_DFBSD) if (cpu == 0) { if (kinfo_get_sched_cputime(times)) err(EX_OSERR, "kinfo_get_sched_cputime() failed"); } else { size = maxcpus * sizeof(times[0]); if ( sysctlbyname("kern.cputime", times + 1, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl kern.cputime failed"); } timeArray[0] = times[cpu].cp_user; timeArray[1] = times[cpu].cp_nice; timeArray[2] = times[cpu].cp_sys; timeArray[3] = times[cpu].cp_intr; timeArray[4] = times[cpu].cp_idle; #else // !XOSVIEW_DFBSD size = CPUSTATES * sizeof(times[0]); if (cpu == 0) { // aggregate times #if defined(XOSVIEW_FREEBSD) if ( sysctlbyname("kern.cp_time", times, &size, NULL, 0) < 0 ) #else // XOSVIEW_NETBSD || XOSVIEW_OPENBSD if ( sysctl(mib_cpt, 2, times, &size, NULL, 0) < 0 ) #endif err(EX_OSERR, "sysctl kern.cp_time failed"); } else { // separate times #if defined(XOSVIEW_FREEBSD) size *= maxcpus; if ( sysctlbyname("kern.cp_times", times + CPUSTATES, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl kern.cp_times failed"); #elif defined(XOSVIEW_NETBSD) size *= BSDCountCpus(); if ( sysctl(mib_cpt, 2, times + CPUSTATES, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl kern.cp_time failed"); #else // XOSVIEW_OPENBSD mib_cpt2[2] = cpu - 1; if ( sysctl(mib_cpt2, 3, times, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl kern.cp_time2 failed"); #endif } for (int i = 0; i < CPUSTATES; i++) #if defined(XOSVIEW_OPENBSD) // aggregates are long, singles uint64_t timeArray[i] = ( cpu ? times[i] : ((long*)(times))[i] ); #else // XOSVIEW_FREEBSD || XOSVIEW_NETBSD timeArray[i] = times[cpu * CPUSTATES + i]; #endif #endif free(times); } // ------------------------ NetMeter functions ------------------------------- int BSDNetInit() { OpenKDIfNeeded(); return 1; } void BSDGetNetInOut(uint64_t *inbytes, uint64_t *outbytes, const char *netIface, bool ignored) { struct ifaddrs *ifap, *ifa; *inbytes = 0; *outbytes = 0; if (getifaddrs(&ifap) != 0) return; for (ifa = ifap; ifa; ifa = ifa->ifa_next) { bool skipif = false; if (ifa->ifa_addr->sa_family != AF_LINK) continue; if ( strncmp(netIface, "False", 5) != 0 ) { if ( (!ignored && strncmp(ifa->ifa_name, netIface, 256) != 0) || ( ignored && strncmp(ifa->ifa_name, netIface, 256) == 0) ) skipif = true; } #define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s) if (!skipif) { *inbytes += IFA_STAT(ibytes); *outbytes += IFA_STAT(obytes); } #undef IFA_STAT } freeifaddrs(ifap); } // ---------------------- Swap Meter stuff ----------------------------------- int BSDSwapInit() { OpenKDIfNeeded(); return 1; } void BSDGetSwapInfo(uint64_t *total, uint64_t *used) { #if defined(HAVE_SWAPCTL) // This code is based on a patch sent in by Scott Stevens // (s.k.stevens@ic.ac.uk, at the time). struct swapent *sep, *swapiter; int bsize, rnswap, nswap = swapctl(SWAP_NSWAP, 0, 0); *total = *used = 0; if (nswap < 1) // no swap devices on return; if ( (sep = (struct swapent *)malloc(nswap* sizeof(struct swapent))) == NULL ) err(EX_OSERR, "BSDGetSwapInfo(): malloc failed"); rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); if (rnswap < 0) err(EX_OSERR, "BSDGetSwapInfo(): getting SWAP_STATS failed"); if (nswap != rnswap) warnx("SWAP_STATS gave different value than SWAP_NSWAP " "(nswap=%d versus rnswap=%d).", nswap, rnswap); swapiter = sep; bsize = 512; // block size is that of underlying device, *usually* 512 bytes for ( ; rnswap-- > 0; swapiter++) { *total += (uint64_t)swapiter->se_nblks * bsize; *used += (uint64_t)swapiter->se_inuse * bsize; } free(sep); #else struct kvm_swap kswap; OpenKDIfNeeded(); int pgsize = getpagesize(); if ( kvm_getswapinfo(kd, &kswap, 1, 0) ) err(EX_OSERR, "BSDGetSwapInfo(): kvm_getswapinfo failed"); *total = (uint64_t)kswap.ksw_total * pgsize; *used = (uint64_t)kswap.ksw_used * pgsize; #endif } // ----------------------- Disk Meter stuff ----------------------------------- #ifdef HAVE_DEVSTAT /* * Make use of the new FreeBSD kernel device statistics library using * code shamelessly borrowed from xsysinfo, which borrowed shamelessly * from FreeBSD's iostat(8). */ long generation; devstat_select_mode select_mode; struct devstat_match *matches; int num_matches = 0; int num_selected, num_selections; long select_generation; static struct statinfo cur, last; int num_devices; struct device_selection *dev_select; int nodisk = 0; void DevStat_Init(void) { /* * Make sure that the userland devstat version matches the kernel * devstat version. */ #if defined(XOSVIEW_FREEBSD) if (devstat_checkversion(NULL) < 0) { #else if (checkversion() < 0) { #endif nodisk++; warn("%s\n", devstat_errbuf); return; } /* find out how many devices we have */ #if defined(XOSVIEW_FREEBSD) if ( (num_devices = devstat_getnumdevs(NULL)) < 0 ) { #else if ( (num_devices = getnumdevs()) < 0 ) { #endif nodisk++; warn("%s\n", devstat_errbuf); return; } cur.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); last.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); /* * Grab all the devices. We don't look to see if the list has * changed here, since it almost certainly has. We only look for * errors. */ #if defined(XOSVIEW_FREEBSD) if (devstat_getdevs(NULL, &cur) == -1) { #else if (getdevs(&cur) == -1) { #endif nodisk++; warn("%s\n", devstat_errbuf); return; } num_devices = cur.dinfo->numdevs; generation = cur.dinfo->generation; dev_select = NULL; /* only interested in disks */ matches = NULL; char da[3] = "da"; #if defined(XOSVIEW_FREEBSD) if (devstat_buildmatch(da, &matches, &num_matches) != 0) { #else if (buildmatch(da, &matches, &num_matches) != 0) { #endif nodisk++; warn("%s\n", devstat_errbuf); return; } if (num_matches == 0) select_mode = DS_SELECT_ADD; else select_mode = DS_SELECT_ONLY; /* * At this point, selectdevs will almost surely indicate that the * device list has changed, so we don't look for return values of 0 * or 1. If we get back -1, though, there is an error. */ #if defined(XOSVIEW_FREEBSD) if (devstat_selectdevs(&dev_select, &num_selected, #else if (selectdevs(&dev_select, &num_selected, #endif &num_selections, &select_generation, generation, cur.dinfo->devices, num_devices, matches, num_matches, NULL, 0, select_mode, 10, 0) == -1) { nodisk++; warn("%s\n", devstat_errbuf); } } uint64_t DevStat_Get(uint64_t *read_bytes, uint64_t *write_bytes) { register int dn; long double busy_seconds; uint64_t reads, writes, total_bytes = 0; struct devinfo *tmp_dinfo; if (nodisk > 0) /* Diskless system or some error happened. */ return 0; /* * Here what we want to do is refresh our device stats. * getdevs() returns 1 when the device list has changed. * If the device list has changed, we want to go through * the selection process again, in case a device that we * were previously displaying has gone away. */ #if defined(XOSVIEW_FREEBSD) switch (devstat_getdevs(NULL, &cur)) { #else switch (getdevs(&cur)) { #endif case -1: return (0); case 1: int retval; num_devices = cur.dinfo->numdevs; generation = cur.dinfo->generation; #if defined(XOSVIEW_FREEBSD) retval = devstat_selectdevs(&dev_select, &num_selected, #else retval = selectdevs(&dev_select, &num_selected, #endif &num_selections, &select_generation, generation, cur.dinfo->devices, num_devices, matches, num_matches, NULL, 0, select_mode, 10, 0); switch(retval) { case -1: return (0); case 1: break; default: break; break; } default: break; } /* * Calculate elapsed time up front, since it's the same for all * devices. */ #if defined(XOSVIEW_FREEBSD) busy_seconds = cur.snap_time - last.snap_time; #else busy_seconds = compute_etime(cur.busy_time, last.busy_time); #endif /* this is the first time thru so just copy cur to last */ if (last.dinfo->numdevs == 0) { tmp_dinfo = last.dinfo; last.dinfo = cur.dinfo; cur.dinfo = tmp_dinfo; #if defined(XOSVIEW_FREEBSD) last.snap_time = cur.snap_time; #else last.busy_time = cur.busy_time; #endif return (0); } for (dn = 0; dn < num_devices; dn++) { int di; if ( (dev_select[dn].selected == 0) || (dev_select[dn].selected > 10) ) continue; di = dev_select[dn].position; #if defined(XOSVIEW_FREEBSD) if (devstat_compute_statistics(&cur.dinfo->devices[di], &last.dinfo->devices[di], busy_seconds, DSM_TOTAL_BYTES_READ, &reads, DSM_TOTAL_BYTES_WRITE, &writes, DSM_NONE) != 0) { #else if (compute_stats_read(&cur.dinfo->devices[di], &last.dinfo->devices[di], busy_seconds, &reads, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != 0) { warn("%s\n", devstat_errbuf); break; } if (compute_stats_write(&cur.dinfo->devices[di], &last.dinfo->devices[di], busy_seconds, &writes, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != 0) { #endif warn("%s\n", devstat_errbuf); break; } *read_bytes += reads; *write_bytes += writes; total_bytes += reads + writes; } tmp_dinfo = last.dinfo; last.dinfo = cur.dinfo; cur.dinfo = tmp_dinfo; #if defined(XOSVIEW_FREEBSD) last.snap_time = cur.snap_time; #else last.busy_time = cur.busy_time; #endif return total_bytes; } #endif int BSDDiskInit() { OpenKDIfNeeded(); #if defined(HAVE_DEVSTAT) DevStat_Init(); #endif return 1; } uint64_t BSDGetDiskXFerBytes(uint64_t *read_bytes, uint64_t *write_bytes) { #if defined(HAVE_DEVSTAT) return DevStat_Get(read_bytes, write_bytes); #else *read_bytes = *write_bytes = 0; # if defined(XOSVIEW_NETBSD) size_t size; // Do a sysctl with a NULL data pointer to get the size that would // have been returned, and use that to figure out # drives. if ( sysctl(mib_dsk, 3, NULL, &size, NULL, 0) < 0 ) err(EX_OSERR, "BSDGetDiskXFerBytes(): sysctl hw.iostats #1 failed"); unsigned int ndrives = size / mib_dsk[2]; struct io_sysctl drive_stats[ndrives]; // Get the stats. if ( sysctl(mib_dsk, 3, drive_stats, &size, NULL, 0) < 0 ) err(EX_OSERR, "BSDGetDiskXFerBytes(): sysctl hw.iostats #2 failed"); // Now accumulate the total. for (uint i = 0; i < ndrives; i++) { *read_bytes += drive_stats[i].rbytes; *write_bytes += drive_stats[i].wbytes; } # else /* XOSVIEW_OPENBSD */ /* This function is a little tricky -- we have to iterate over a * list in kernel land. To make things simpler, data structures * and pointers for objects in kernel-land have kvm tacked on front * of their names. Thus, kvmdiskptr points to a disk struct in * kernel memory. kvmcurrdisk is a copy of the kernel's struct, * and it has pointers in it to other structs, so it also is * prefixed with kvm. */ struct disklist_head kvmdisklist; struct disk *kvmdiskptr; struct disk kvmcurrdisk; safe_kvm_read_symbol(DISKLIST_SYM_INDEX, &kvmdisklist, sizeof(kvmdisklist)); kvmdiskptr = TAILQ_FIRST(&kvmdisklist); while (kvmdiskptr != NULL) { safe_kvm_read((unsigned long)kvmdiskptr, &kvmcurrdisk, sizeof(kvmcurrdisk)); *read_bytes += kvmcurrdisk.dk_rbytes; *write_bytes += kvmcurrdisk.dk_wbytes; kvmdiskptr = TAILQ_NEXT(&kvmcurrdisk, dk_link); } # endif #endif return (*read_bytes + *write_bytes); } // ---------------------- Interrupt Meter stuff ------------------------------ int BSDIntrInit() { OpenKDIfNeeded(); // Make sure the intr counter array is nonzero in size. #if defined(XOSVIEW_FREEBSD) # if __FreeBSD_version >= 900040 size_t nintr; safe_kvm_read(nlst[EINTRCNT_SYM_INDEX].n_value, &nintr, sizeof(nintr)); return ValidSymbol(INTRCNT_SYM_INDEX) && ValidSymbol(EINTRCNT_SYM_INDEX) && (nintr > 0); # else return ValidSymbol(INTRCNT_SYM_INDEX) && ValidSymbol(EINTRCNT_SYM_INDEX) && ((SymbolValue(EINTRCNT_SYM_INDEX) - SymbolValue(INTRCNT_SYM_INDEX)) > 0); # endif #elif defined(XOSVIEW_NETBSD) return ValidSymbol(ALLEVENTS_SYM_INDEX); #endif return 1; } int BSDNumInts() { /* This code is stolen from vmstat. */ int count = 0, nbr = 0; #if defined(XOSVIEW_FREEBSD) size_t inamlen, nintr; char *intrnames, *intrs; # if __FreeBSD_version >= 900040 safe_kvm_read(nlst[EINTRCNT_SYM_INDEX].n_value, &nintr, sizeof(nintr)); safe_kvm_read(nlst[EINTRNAMES_SYM_INDEX].n_value, &inamlen, sizeof(inamlen)); # else nintr = nlst[EINTRCNT_SYM_INDEX].n_value - nlst[INTRCNT_SYM_INDEX].n_value; inamlen = nlst[EINTRNAMES_SYM_INDEX].n_value - nlst[INTRNAMES_SYM_INDEX].n_value; # endif if (nintr == 0 || inamlen == 0) { warnx("Could not get interrupt numbers."); return 0; } intrnames = intrs = (char *)malloc(inamlen); if (!intrs) err(EX_OSERR, "BSDNumInts(): malloc failed"); safe_kvm_read(nlst[INTRNAMES_SYM_INDEX].n_value, intrs, inamlen); nintr /= sizeof(long); for (uint i = 0; i < nintr; i++) { if ( intrnames[0] && sscanf(intrnames, "irq%d", &nbr) == 1 && nbr > count ) count = nbr; intrnames += strlen(intrnames) + 1; } free(intrs); #elif defined(XOSVIEW_NETBSD) struct evcntlist events; struct evcnt evcnt, *evptr; char dummy[30]; char *name; safe_kvm_read(nlst[ALLEVENTS_SYM_INDEX].n_value, &events, sizeof(events)); evptr = TAILQ_FIRST(&events); while (evptr) { safe_kvm_read((unsigned long)evptr, &evcnt, sizeof(evcnt)); if (evcnt.ev_type == EVCNT_TYPE_INTR) { if ( !(name = (char *)malloc(evcnt.ev_namelen + 1)) ) err(EX_OSERR, "BSDNumInts(): malloc failed"); safe_kvm_read((unsigned long)evcnt.ev_name, name, evcnt.ev_namelen + 1); if ( sscanf(name, "%s%d", dummy, &nbr) == 2 && nbr > count ) count = nbr; free(name); } evptr = TAILQ_NEXT(&evcnt, ev_list); } #elif defined(XOSVIEW_OPENBSD) int nintr = 0; int mib_int[4] = { CTL_KERN, KERN_INTRCNT, KERN_INTRCNT_NUM }; size_t size = sizeof(nintr); if ( sysctl(mib_int, 3, &nintr, &size, NULL, 0) < 0 ) { warn("Could not get interrupt count"); return 0; } for (int i = 0; i < nintr; i++) { mib_int[2] = KERN_INTRCNT_VECTOR; mib_int[3] = i; size = sizeof(nbr); if ( sysctl(mib_int, 4, &nbr, &size, NULL, 0) < 0 ) warn("Could not get name of interrupt %d", i); else if ( nbr > count ) count = nbr; } #else // XOSVIEW_DFBSD int nintr = 0; size_t inamlen; char *intrnames, *intrs; if ( sysctlbyname("hw.intrnames", NULL, &inamlen, NULL, 0) != 0 ) { warn("sysctl hw.intrnames failed"); return 0; } intrnames = intrs = (char *)malloc(inamlen); if (!intrs) err(EX_OSERR, "BSDNumInts(): malloc failed"); if ( sysctlbyname("hw.intrnames", intrs, &inamlen, NULL, 0) < 0 ) { warn("sysctl hw.intrnames failed"); free(intrs); return 0; } for (uint i = 0; i < inamlen; i++) { if (intrs[i] == '\0') // count end-of-strings nintr++; } for (int i = 0; i < nintr; i++) { if ( sscanf(intrnames, "irq%d", &nbr) == 0 ) { if ( ++nbr > count ) // unused ints are named irqn where count = nbr; // 0<=n<=255, used ones have device name } intrnames += strlen(intrnames) + 1; } free(intrs); #endif return count; // this is the highest numbered interrupt } void BSDGetIntrStats(uint64_t *intrCount, unsigned int *intrNbrs) { /* This code is stolen from vmstat */ int nbr = 0; #if defined(XOSVIEW_FREEBSD) unsigned long *kvm_intrcnt, *intrcnt; char *kvm_intrnames, *intrnames; size_t inamlen, nintr; # if __FreeBSD_version >= 900040 safe_kvm_read(nlst[EINTRCNT_SYM_INDEX].n_value, &nintr, sizeof(nintr)); safe_kvm_read(nlst[EINTRNAMES_SYM_INDEX].n_value, &inamlen, sizeof(inamlen)); # else nintr = nlst[EINTRCNT_SYM_INDEX].n_value - nlst[INTRCNT_SYM_INDEX].n_value; inamlen = nlst[EINTRNAMES_SYM_INDEX].n_value - nlst[INTRNAMES_SYM_INDEX].n_value; # endif if (nintr == 0 || inamlen == 0) { warnx("Could not get interrupt numbers."); return; } if ( ((kvm_intrcnt = (unsigned long *)malloc(nintr)) == NULL) || ((kvm_intrnames = (char *)malloc(inamlen)) == NULL) ) err(EX_OSERR, "BSDGetIntrStats(): malloc failed"); // keep track of the mem we're given: intrcnt = kvm_intrcnt; intrnames = kvm_intrnames; safe_kvm_read(nlst[INTRCNT_SYM_INDEX].n_value, kvm_intrcnt, nintr); safe_kvm_read(nlst[INTRNAMES_SYM_INDEX].n_value, kvm_intrnames, inamlen); nintr /= sizeof(long); /* kvm_intrname has the ASCII names of the IRQs, every null-terminated * string corresponds to a value in the kvm_intrcnt array * e.g. irq1: atkbd0 */ for (uint i = 0; i < nintr; i++) { /* Figure out which irq we have here */ if ( kvm_intrnames[0] && sscanf(kvm_intrnames, "irq%d", &nbr) == 1 ) { intrCount[nbr] = *kvm_intrcnt; if (intrNbrs) intrNbrs[nbr] = 1; } kvm_intrcnt++; kvm_intrnames += strlen(kvm_intrnames) + 1; } free(intrcnt); free(intrnames); #elif defined(XOSVIEW_NETBSD) struct evcntlist events; struct evcnt evcnt, *evptr; char dummy[30]; char *name; safe_kvm_read(nlst[ALLEVENTS_SYM_INDEX].n_value, &events, sizeof(events)); evptr = TAILQ_FIRST(&events); while (evptr) { safe_kvm_read((unsigned long)evptr, &evcnt, sizeof(evcnt)); if (evcnt.ev_type == EVCNT_TYPE_INTR) { if ( !(name = (char *)malloc(evcnt.ev_namelen + 1)) ) err(EX_OSERR, "BSDGetIntrStats(): malloc failed"); safe_kvm_read((unsigned long)evcnt.ev_name, name, evcnt.ev_namelen + 1); if ( sscanf(name, "%s%d", dummy, &nbr) == 2 ) { intrCount[nbr] = evcnt.ev_count; if (intrNbrs) intrNbrs[nbr] = 1; } free(name); } evptr = TAILQ_NEXT(&evcnt, ev_list); } #elif defined(XOSVIEW_OPENBSD) int nintr = 0; uint64_t count = 0; size_t size = sizeof(nintr); int mib_int[4] = { CTL_KERN, KERN_INTRCNT, KERN_INTRCNT_NUM }; if ( sysctl(mib_int, 3, &nintr, &size, NULL, 0) < 0 ) { warn("Could not get interrupt count"); return; } for (int i = 0; i < nintr; i++) { mib_int[2] = KERN_INTRCNT_VECTOR; mib_int[3] = i; size = sizeof(nbr); if ( sysctl(mib_int, 4, &nbr, &size, NULL, 0) < 0 ) continue; // not active mib_int[2] = KERN_INTRCNT_CNT; size = sizeof(count); if ( sysctl(mib_int, 4, &count, &size, NULL, 0) < 0 ) { warn("sysctl kern.intrcnt.cnt.%d failed", i); count = 0; } intrCount[nbr] += count; // += because ints can share number if (intrNbrs) intrNbrs[nbr] = 1; } #else // XOSVIEW_DFBSD int nintr = 0; size_t inamlen; unsigned long *intrcnt; char *dummy, *intrs, **intrnames; if ( sysctlbyname("hw.intrnames", NULL, &inamlen, NULL, 0) != 0 ) { warn("sysctl hw.intrnames failed"); return; } dummy = intrs = (char *)malloc(inamlen); if (!intrs) err(EX_OSERR, "BSDGetIntrStats(): malloc failed"); if ( sysctlbyname("hw.intrnames", intrs, &inamlen, NULL, 0) < 0 ) { warn("sysctl hw.intrnames failed"); free(intrs); return; } for (uint i = 0; i < inamlen; i++) { if (intrs[i] == '\0') // count end-of-strings nintr++; } if ( !(intrnames = (char **)malloc(nintr * sizeof(char *))) ) err(EX_OSERR, "BSDGetIntrStats(): malloc failed"); for (int i = 0; i < nintr; i++) { intrnames[i] = intrs; intrs += strlen(intrs) + 1; } if ( !(intrcnt = (unsigned long *)calloc(nintr, sizeof(long))) ) err(EX_OSERR, "BSDGetIntrStats(): malloc failed"); inamlen = nintr * sizeof(long); if ( sysctlbyname("hw.intrcnt", intrcnt, &inamlen, NULL, 0) < 0 ) err(EX_OSERR, "sysctl hw.intrcnt failed"); for (int i = 0; i < nintr; i++) { if ( sscanf(intrnames[i], "irq%d", &nbr) == 0 ) { nbr++; intrCount[nbr] += intrcnt[i]; if (intrNbrs) intrNbrs[nbr] = 1; } } free(dummy); free(intrnames); free(intrcnt); #endif } // ---------------------- Sensor Meter stuff --------------------------------- static int mib_cpu[2] = { CTL_HW, HW_NCPU }; int BSDCountCpus(void) { int cpus = 0; size_t size = sizeof(cpus); if ( sysctl(mib_cpu, 2, &cpus, &size, NULL, 0) < 0 ) warn("sysctl hw.ncpu failed."); return cpus; } #if defined(__i386__) || defined(__x86_64__) unsigned int BSDGetCPUTemperature(float *temps, float *tjmax) { unsigned int nbr = 0; #if defined(XOSVIEW_NETBSD) // All kinds of sensors are read with libprop. We have to go through them // to find either Intel Core 2 or AMD ones. Actual temperature is in // cur-value and TjMax, if present, in critical-max. // Values are in microdegrees Kelvin. int fd; const char *name = NULL; char dummy[20]; prop_dictionary_t pdict; prop_object_t pobj, pobj1, pobj2; prop_object_iterator_t piter, piter2; prop_array_t parray; if ( (fd = open(_PATH_SYSMON, O_RDONLY)) == -1 ) { warn("Could not open %s", _PATH_SYSMON); return 0; // this seems to happen occasionally, so only warn } if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &pdict)) err(EX_OSERR, "Could not get sensor dictionary"); if (close(fd) == -1) err(EX_OSERR, "Could not close %s", _PATH_SYSMON); if (prop_dictionary_count(pdict) == 0) { warn("No sensors found"); return 0; } if ( !(piter = prop_dictionary_iterator(pdict)) ) err(EX_OSERR, "Could not get sensor iterator"); while ( (pobj = prop_object_iterator_next(piter)) ) { parray = (prop_array_t)prop_dictionary_get_keysym(pdict, (prop_dictionary_keysym_t)pobj); if (prop_object_type(parray) != PROP_TYPE_ARRAY) continue; name = prop_dictionary_keysym_cstring_nocopy((prop_dictionary_keysym_t)pobj); if ( strncmp(name, "coretemp", 8) && strncmp(name, "amdtemp", 7) ) continue; if ( !(piter2 = prop_array_iterator(parray)) ) err(EX_OSERR, "Could not get sensor iterator"); int i = 0; sscanf(name, "%[^0-9]%d", dummy, &i); while ( (pobj = prop_object_iterator_next(piter2)) ) { if ( !(pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "type")) ) continue; if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "cur-value")) ) { if (temps) temps[i] = (prop_number_integer_value((prop_number_t)pobj1) / 1000000.0) - 273.15; nbr++; } if ( (pobj2 = prop_dictionary_get((prop_dictionary_t)pobj, "critical-max")) && tjmax ) tjmax[i] = (prop_number_integer_value((prop_number_t)pobj2) / 1000000.0) - 273.15; } prop_object_iterator_release(piter2); } prop_object_iterator_release(piter); prop_object_release(pdict); #else /* XOSVIEW_NETBSD */ int val = 0; size_t size = sizeof(val); #if defined(XOSVIEW_OPENBSD) || defined(XOSVIEW_DFBSD) // All kinds of sensors are read with sysctl. We have to go through them // to find either Intel Core 2 or AMD ones. // Values are in microdegrees Kelvin. struct sensordev sd; struct sensor s; int cpu = 0; char dummy[10]; for (int dev = 0; dev < 1024; dev++) { // go through all sensor devices mib_sen[2] = dev; size = sizeof(sd); if ( sysctl(mib_sen, 3, &sd, &size, NULL, 0) < 0 ) { if (errno == ENOENT) break; // no more sensors if (errno == ENXIO) continue; // no sensor with this mib err(EX_OSERR, "sysctl hw.sensors.%d failed", dev); } if ( strncmp(sd.xname, "cpu", 3) ) continue; // not CPU sensor sscanf(sd.xname, "%[^0-9]%d", dummy, &cpu); mib_sen[3] = SENSOR_TEMP; // for each device, get temperature sensors for (int i = 0; i < sd.maxnumt[SENSOR_TEMP]; i++) { mib_sen[4] = i; size = sizeof(s); if ( sysctl(mib_sen, 5, &s, &size, NULL, 0) < 0 ) continue; // no sensor on this core? if (s.flags & SENSOR_FINVALID) continue; if (temps) temps[cpu] = (float)(s.value - 273150000) / 1000000.0; nbr++; } } #else /* XOSVIEW_FREEBSD */ // Temperatures can be read with sysctl dev.cpu.%d.temperature on both // Intel Core 2 and AMD K8+ processors. // Values are in degrees Celsius (FreeBSD < 7.2) or in // 10*degrees Kelvin (FreeBSD >= 7.3). char name[25]; int cpus = BSDCountCpus(); for (int i = 0; i < cpus; i++) { snprintf(name, 25, "dev.cpu.%d.temperature", i); if ( sysctlbyname(name, &val, &size, NULL, 0) == 0) { nbr++; if (temps) #if __FreeBSD_version >= 702106 temps[i] = ((float)val - 2732.0) / 10.0; #else temps[i] = (float)val; #endif } else warn("sysctl %s failed", name); if (tjmax) { snprintf(name, 25, "dev.cpu.%d.coretemp.tjmax", i); if ( sysctlbyname(name, &val, &size, NULL, 0) == 0 ) #if __FreeBSD_version >= 702106 tjmax[i] = ((float)val - 2732.0) / 10.0; #else tjmax[i] = (float)val; #endif else warn("sysctl %s failed", name); } } #endif #endif return nbr; } #endif void BSDGetSensor(const char *name, const char *valname, float *value, char *unit) { if (!name || !valname || !value) errx(EX_SOFTWARE, "NULL pointer passed to BSDGetSensor()."); #if defined(XOSVIEW_NETBSD) /* Adapted from envstat. */ // All kinds of sensors are read with libprop. Specific device and value // can be asked for. Values are transformed to suitable units. int fd, val = 0; char type[20]; prop_dictionary_t pdict; prop_object_t pobj, pobj1; prop_object_iterator_t piter; if ( (fd = open(_PATH_SYSMON, O_RDONLY)) == -1 ) { warn("Could not open %s", _PATH_SYSMON); return; // this seems to happen occasionally, so only warn } if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &pdict)) err(EX_OSERR, "Could not get sensor dictionary"); if (close(fd) == -1) err(EX_OSERR, "Could not close %s", _PATH_SYSMON); if (prop_dictionary_count(pdict) == 0) { warn("No sensors found"); return; } pobj = prop_dictionary_get(pdict, name); if (prop_object_type(pobj) != PROP_TYPE_ARRAY) err(EX_USAGE, "Device %s does not exist", name); if ( !(piter = prop_array_iterator((prop_array_t)pobj)) ) err(EX_OSERR, "Could not get sensor iterator"); while ( (pobj = prop_object_iterator_next(piter)) ) { if ( !(pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "type")) ) continue; strlcpy(type, prop_string_cstring_nocopy((prop_string_t)pobj1), 20); if ( strncmp(type, "Indicator", 3) == 0 || strncmp(type, "Battery", 3) == 0 || strncmp(type, "Drive", 3) == 0 ) continue; // these are string values if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, valname)) ) val = prop_number_integer_value((prop_number_t)pobj1); else err(EX_USAGE, "Value %s does not exist", valname); if ( strncmp(type, "Temperature", 4) == 0 ) { *value = (val / 1000000.0) - 273.15; // temperatures are in microkelvins if (unit) strcpy(unit, "\260C"); } else if ( strncmp(type, "Fan", 3) == 0 ) { *value = (float)val; // plain integer value if (unit) strcpy(unit, "RPM"); } else if ( strncmp(type, "Integer", 3) == 0 ) *value = (float)val; // plain integer value else if ( strncmp(type, "Voltage", 4) == 0 ) { *value = (float)val / 1000000.0; // electrical units are in micro{V,A,W,Ohm} if (unit) strcpy(unit, "V"); } else if ( strncmp(type, "Ampere hour", 7) == 0 ) { *value = (float)val / 1000000.0; // electrical units are in micro{V,A,W,Ohm} if (unit) strcpy(unit, "Ah"); } else if ( strncmp(type, "Ampere", 7) == 0 ) { *value = (float)val / 1000000.0; // electrical units are in micro{V,A,W,Ohm} if (unit) strcpy(unit, "A"); } else if ( strncmp(type, "Watt hour", 5) == 0 ) { *value = (float)val / 1000000.0; // electrical units are in micro{V,A,W,Ohm} if (unit) strcpy(unit, "Wh"); } else if ( strncmp(type, "Watts", 5) == 0 ) { *value = (float)val / 1000000.0; // electrical units are in micro{V,A,W,Ohm} if (unit) strcpy(unit, "W"); } else if ( strncmp(type, "Ohms", 4) == 0 ) { *value = (float)val / 1000000.0; // electrical units are in micro{V,A,W,Ohm} if (unit) strcpy(unit, "Ohm"); } } prop_object_iterator_release(piter); prop_object_release(pdict); #else /* XOSVIEW_NETBSD */ size_t size; char dummy[50]; #if defined(XOSVIEW_FREEBSD) || defined(XOSVIEW_DFBSD) // FreeBSD has no sensor framework, but ACPI thermal zones might work. // They are readable through sysctl (also works in Dragonfly). // Values are in 10 * degrees Kelvin. if ( strncmp(name, "tz", 2) == 0 ) { int val = 0; size = sizeof(val); snprintf(dummy, 50, "hw.acpi.thermal.%s.%s", name, valname); if ( sysctlbyname(dummy, &val, &size, NULL, 0) < 0 ) err(EX_OSERR, "sysctl %s failed", dummy); *value = ((float)val - 2732.0) / 10.0; if (unit) strcpy(unit, "\260C"); return; } // If Dragonfly and tzN specified, return. Otherwise, fall through. #endif #if defined(XOSVIEW_OPENBSD) || defined(XOSVIEW_DFBSD) /* Adapted from systat. */ // All kinds of sensors are read with sysctl. We have to go through them // to find the required device and value. Parameter 'name' is the device // name and 'valname' consists of type and sensor index (e.g. it0.temp1). // Values are transformed to suitable units. int index = -1; struct sensordev sd; struct sensor s; for (int dev = 0; dev < 1024; dev++) { // go through all sensor devices mib_sen[2] = dev; size = sizeof(sd); if ( sysctl(mib_sen, 3, &sd, &size, NULL, 0) < 0 ) { if (errno == ENOENT) break; // no more devices if (errno == ENXIO) continue; // no device with this mib err(EX_OSERR, "sysctl hw.sensors.%d failed", dev); } if ( strncmp(sd.xname, name, sizeof(name)) ) continue; // sensor name does not match for (int t = 0; t < SENSOR_MAX_TYPES; t++) { if ( strncmp(sensor_type_s[t], valname, strlen(sensor_type_s[t])) ) continue; // wrong type mib_sen[3] = t; sscanf(valname, "%[^0-9]%d", dummy, &index); if (index < sd.maxnumt[t]) { mib_sen[4] = index; size = sizeof(s); if ( sysctl(mib_sen, 5, &s, &size, NULL, 0) < 0 ) { if (errno != ENOENT) err(EX_OSERR, "sysctl hw.sensors.%d.%d.%d failed", dev, t, index); continue; // no more sensors } if (s.flags & SENSOR_FINVALID) continue; switch (t) { case SENSOR_TEMP: *value = (float)(s.value - 273150000) / 1000000.0; if (unit) strcpy(unit, "\260C"); break; case SENSOR_FANRPM: *value = (float)s.value; if (unit) strcpy(unit, "RPM"); break; case SENSOR_VOLTS_DC: case SENSOR_VOLTS_AC: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "V"); break; case SENSOR_OHMS: *value = (float)s.value; if (unit) strcpy(unit, "Ohm"); break; case SENSOR_WATTS: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "W"); break; case SENSOR_AMPS: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "A"); break; case SENSOR_WATTHOUR: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "Wh"); break; case SENSOR_AMPHOUR: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "Ah"); break; case SENSOR_PERCENT: *value = (float)s.value / 1000.0; if (unit) strcpy(unit, "%"); break; case SENSOR_LUX: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "lx"); break; case SENSOR_TIMEDELTA: *value = (float)s.value / 1000000000.0; if (unit) strcpy(unit, "s"); break; #if defined(XOSVIEW_OPENBSD) case SENSOR_HUMIDITY: *value = (float)s.value / 1000.0; if (unit) strcpy(unit, "%"); break; case SENSOR_FREQ: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "Hz"); break; case SENSOR_ANGLE: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "\260"); break; #if OpenBSD > 201211 case SENSOR_DISTANCE: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "m"); break; case SENSOR_PRESSURE: *value = (float)s.value / 1000.0; if (unit) strcpy(unit, "Pa"); break; case SENSOR_ACCEL: *value = (float)s.value / 1000000.0; if (unit) strcpy(unit, "m\\/s\262"); // m/s² break; #endif #endif case SENSOR_INDICATOR: case SENSOR_INTEGER: case SENSOR_DRIVE: default: *value = (float)s.value; break; } } } } #endif #endif } // ---------------------- Battery Meter stuff --------------------------------- bool BSDHasBattery() { #if defined(XOSVIEW_NETBSD) int fd; prop_dictionary_t pdict; prop_object_t pobj; if ( (fd = open(_PATH_SYSMON, O_RDONLY)) == -1 ) return false; if ( prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &pdict) ) err(EX_OSERR, "Could not get sensor dictionary"); if ( close(fd) == -1 ) err(EX_OSERR, "Could not close %s", _PATH_SYSMON); if ( prop_dictionary_count(pdict) == 0 ) return false; pobj = prop_dictionary_get(pdict, "acpibat0"); // just check for 1st battery if ( prop_object_type(pobj) != PROP_TYPE_ARRAY ) return false; return true; #elif defined(XOSVIEW_OPENBSD) // check if we can get full capacity of the 1st battery float val = -1.0; BSDGetSensor("acpibat0", "amphour0", &val); if (val < 0) return false; return true; #else // XOSVIEW_FREEBSD || XOSVIEW_DFBSD int fd; if ( (fd = open(ACPIDEV, O_RDONLY)) == -1 ) { // No ACPI -> try APM if ( (fd = open(APMDEV, O_RDONLY)) == -1 ) return false; struct apm_info aip; if ( ioctl(fd, APMIO_GETINFO, &aip) == -1 ) return false; if ( close(fd) == -1 ) err(EX_OSERR, "Could not close %s", APMDEV); if (aip.ai_batt_stat == 0xff || aip.ai_batt_life == 0xff) return false; return true; } union acpi_battery_ioctl_arg battio; battio.unit = ACPI_BATTERY_ALL_UNITS; if ( ioctl(fd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1 ) return false; if ( close(fd) == -1 ) err(EX_OSERR, "Could not close %s", ACPIDEV); return ( battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT ); #endif } void BSDGetBatteryInfo(int *remaining, unsigned int *state) { *state = XOSVIEW_BATT_NONE; #if defined(XOSVIEW_NETBSD) || defined(XOSVIEW_OPENBSD) int batteries = 0; #if defined(XOSVIEW_NETBSD) /* Again adapted from envstat. */ // All kinds of sensors are read with libprop. We have to go through them // to find the batteries. We need capacity, charge, presence, charging // status and discharge rate for each battery for the calculations. // For simplicity, assume all batteries have the same // charge/discharge status. int fd; int total_capacity = 0, total_charge = 0, total_low = 0, total_crit = 0; const char *name = NULL; prop_dictionary_t pdict; prop_object_t pobj, pobj1; prop_object_iterator_t piter, piter2; prop_array_t parray; if ( (fd = open(_PATH_SYSMON, O_RDONLY)) == -1 ) { warn("Could not open %s", _PATH_SYSMON); return; // this seems to happen occasionally, so only warn } if ( prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &pdict) ) err(EX_OSERR, "Could not get sensor dictionary"); if ( close(fd) == -1 ) err(EX_OSERR, "Could not close %s", _PATH_SYSMON); if ( prop_dictionary_count(pdict) == 0 ) { warn("No sensors found"); return; } if ( !(piter = prop_dictionary_iterator(pdict)) ) err(EX_OSERR, "Could not get sensor iterator"); while ( (pobj = prop_object_iterator_next(piter)) ) { int present = 0, capacity = 0, charge = 0, low = 0, crit = 0; name = prop_dictionary_keysym_cstring_nocopy((prop_dictionary_keysym_t)pobj); if ( strncmp(name, "acpibat", 7) ) continue; parray = (prop_array_t)prop_dictionary_get_keysym(pdict, (prop_dictionary_keysym_t)pobj); if ( prop_object_type(parray) != PROP_TYPE_ARRAY ) continue; if ( !(piter2 = prop_array_iterator(parray)) ) err(EX_OSERR, "Could not get sensor iterator"); while ( (pobj = prop_object_iterator_next(piter2)) ) { if ( !(pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "state")) ) continue; if ( prop_string_equals_cstring((prop_string_t)pobj1, "invalid") || prop_string_equals_cstring((prop_string_t)pobj1, "unknown") ) continue; // skip sensors without valid data if ( !(pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "description")) ) continue; name = prop_string_cstring_nocopy((prop_string_t)pobj1); if ( strncmp(name, "present", 7) == 0 ) { // is battery present if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "cur-value")) ) present = prop_number_integer_value((prop_number_t)pobj1); } else if ( strncmp(name, "design cap", 10) == 0 ) { // get full capacity if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "cur-value")) ) capacity = prop_number_integer_value((prop_number_t)pobj1); } else if ( strncmp(name, "charge", 7) == 0 ) { // get present charge, low and critical levels if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "cur-value")) ) charge = prop_number_integer_value((prop_number_t)pobj1); if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "warning-capacity")) ) low = prop_number_integer_value((prop_number_t)pobj1); if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "critical-capacity")) ) crit = prop_number_integer_value((prop_number_t)pobj1); } else if ( strncmp(name, "charging", 8) == 0 ) { // charging or not? if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "cur-value")) ) if ( prop_number_integer_value((prop_number_t)pobj1) ) *state |= XOSVIEW_BATT_CHARGING; } else if ( strncmp(name, "discharge rate", 14) == 0 ) { // discharging or not? if ( (pobj1 = prop_dictionary_get((prop_dictionary_t)pobj, "cur-value")) ) if ( prop_number_integer_value((prop_number_t)pobj1) ) *state |= XOSVIEW_BATT_DISCHARGING; } } if (present) { total_capacity += capacity; total_charge += charge; total_low += low; total_crit += crit; batteries++; } prop_object_iterator_release(piter2); } prop_object_iterator_release(piter); prop_object_release(pdict); #else // XOSVIEW_OPENBSD float total_capacity = 0, total_charge = 0, total_low = 0, total_crit = 0; char battery[16]; while (batteries < 1024) { float val = -1.0; snprintf(battery, 15, "acpibat%d", batteries); BSDGetSensor(battery, "amphour0", &val); // full capacity if (val < 0) // no more batteries break; batteries++; total_capacity += val; BSDGetSensor(battery, "amphour1", &val); // warning capacity total_low += val; BSDGetSensor(battery, "amphour2", &val); // low capacity total_crit += val; BSDGetSensor(battery, "amphour3", &val); // remaining total_charge += val; BSDGetSensor(battery, "raw0", &val); // state if ((int)val == 1) *state |= XOSVIEW_BATT_DISCHARGING; else if ((int)val == 2) *state |= XOSVIEW_BATT_CHARGING; // there's also 0 state for idle/full } #endif if (batteries == 0) { // all batteries are off *state = XOSVIEW_BATT_NONE; *remaining = 0; return; } *remaining = 100 * total_charge / total_capacity; if ( !(*state & XOSVIEW_BATT_CHARGING) && !(*state & XOSVIEW_BATT_DISCHARGING) ) *state |= XOSVIEW_BATT_FULL; // it's full when not charging nor discharging if (total_capacity < total_low) *state |= XOSVIEW_BATT_LOW; if (total_capacity < total_crit) *state |= XOSVIEW_BATT_CRITICAL; #else // XOSVIEW_FREEBSD || XOSVIEW_DFBSD /* Adapted from acpiconf and apm. */ int fd; if ( (fd = open(ACPIDEV, O_RDONLY)) == -1 ) { // No ACPI -> try APM if ( (fd = open(APMDEV, O_RDONLY)) == -1 ) err(EX_OSFILE, "could not open %s or %s", ACPIDEV, APMDEV); struct apm_info aip; if ( ioctl(fd, APMIO_GETINFO, &aip) == -1 ) err(EX_IOERR, "failed to get APM battery info"); if ( close(fd) == -1 ) err(EX_OSERR, "Could not close %s", APMDEV); if (aip.ai_batt_life <= 100) *remaining = aip.ai_batt_life; // only 0-100 are valid values else *remaining = 0; if (aip.ai_batt_stat == 0) *state |= XOSVIEW_BATT_FULL; else if (aip.ai_batt_stat == 1) *state |= XOSVIEW_BATT_LOW; else if (aip.ai_batt_stat == 2) *state |= XOSVIEW_BATT_CRITICAL; else if (aip.ai_batt_stat == 3) *state |= XOSVIEW_BATT_CHARGING; else *state = XOSVIEW_BATT_NONE; return; } // ACPI union acpi_battery_ioctl_arg battio; battio.unit = ACPI_BATTERY_ALL_UNITS; if ( ioctl(fd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1 ) err(EX_IOERR, "failed to get ACPI battery info"); if ( close(fd) == -1 ) err(EX_OSERR, "Could not close %s", ACPIDEV); *remaining = battio.battinfo.cap; if (battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT) { if (battio.battinfo.state == 0) *state |= XOSVIEW_BATT_FULL; if (battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) *state |= XOSVIEW_BATT_CRITICAL; if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG) *state |= XOSVIEW_BATT_DISCHARGING; if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING) *state |= XOSVIEW_BATT_CHARGING; } #endif } xosview-1.20/bsd/kernel.h000066400000000000000000000027641317735352700153670ustar00rootroot00000000000000#ifndef __kernel_h__ #define __kernel_h__ // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "defines.h" void BSDInit(); void SetKernelName(const char* kernelName); int BSDGetCPUSpeed(); void BSDPageInit(); void BSDGetPageStats(uint64_t *meminfo, uint64_t *pageinfo); void BSDCPUInit(); void BSDGetCPUTimes(uint64_t *timesArray, unsigned int cpu = 0); int BSDNetInit(); void BSDGetNetInOut(uint64_t *inbytes, uint64_t *outbytes, const char *netIface, bool ignored); int BSDSwapInit(); void BSDGetSwapInfo(uint64_t *total, uint64_t *free); int BSDDiskInit(); uint64_t BSDGetDiskXFerBytes(uint64_t *read_bytes, uint64_t *write_bytes); int BSDIntrInit(); int BSDNumInts(); void BSDGetIntrStats(uint64_t *intrCount, unsigned int *intrNbrs); int BSDCountCpus(void); #if defined(__i386__) || defined(__x86_64) unsigned int BSDGetCPUTemperature(float *temps, float *tjmax); #endif void BSDGetSensor(const char *name, const char *valname, float *value, char *unit = NULL); bool BSDHasBattery(); void BSDGetBatteryInfo(int *remaining, unsigned int *state); #endif xosview-1.20/bsd/loadmeter.cc000066400000000000000000000073631317735352700162210ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // Most of this code was written by Werner Fink . // Only small changes were made on my part (M.R.) // And the near-trivial port to NetBSD was done by Brian Grayson // // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "loadmeter.h" #include "kernel.h" #include #include #include #include LoadMeter::LoadMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "LOAD", "PROCS/MIN", 1, 1, 0 ) { total_ = -1.0; } LoadMeter::~LoadMeter( void ) { } void LoadMeter::checkResources( void ) { FieldMeterGraph::checkResources(); procloadcol_ = parent_->allocColor( parent_->getResource("loadProcColor") ); warnloadcol_ = parent_->allocColor( parent_->getResource("loadWarnColor") ); critloadcol_ = parent_->allocColor( parent_->getResource("loadCritColor") ); setfieldcolor( 0, procloadcol_ ); setfieldcolor( 1, parent_->getResource("loadIdleColor") ); priority_ = atoi( parent_->getResource("loadPriority") ); dodecay_ = parent_->isResourceTrue("loadDecay"); useGraph_ = parent_->isResourceTrue("loadGraph"); SetUsedFormat( parent_->getResource("loadUsedFormat") ); do_cpu_speed_ = parent_->isResourceTrue("loadCpuSpeed"); const char *warn = parent_->getResource("loadWarnThreshold"); if (strncmp(warn, "auto", 2) == 0) warnThreshold_ = BSDCountCpus(); else warnThreshold_ = atoi(warn); const char *crit = parent_->getResource("loadCritThreshold"); if (strncmp(crit, "auto", 2) == 0) critThreshold_ = warnThreshold_ * 4; else critThreshold_ = atoi(crit); alarmstate_ = lastalarmstate_ = 0; if (dodecay_) { // Warning: Since the loadmeter changes scale occasionally, old // decay values need to be rescaled. However, if they are rescaled, // they could go off the edge of the screen. Thus, for now, to // prevent this whole problem, the load meter can not be a decay // meter. The load is a decaying average kind of thing anyway, // so having a decaying load average is redundant. std::cerr << "Warning: The loadmeter can not be configured as a decay\n" << " meter. See the source code (" << __FILE__ << ") for further\n" << " details.\n"; dodecay_ = 0; } } void LoadMeter::checkevent( void ) { getloadinfo(); if (do_cpu_speed_) { old_cpu_speed_ = cur_cpu_speed_; cur_cpu_speed_ = BSDGetCPUSpeed(); if (old_cpu_speed_ != cur_cpu_speed_) { char l[25]; snprintf(l, 25, "PROCS/MIN %d MHz", cur_cpu_speed_); legend(l); drawlegend(); } } drawfields(); } void LoadMeter::getloadinfo( void ) { double oneMinLoad; getloadavg(&oneMinLoad, 1); // Only get the 1-minute-average sample. fields_[0] = oneMinLoad; if (fields_[0] < warnThreshold_) alarmstate_ = 0; else if (fields_[0] >= critThreshold_) alarmstate_ = 2; else alarmstate_ = 1; if (alarmstate_ != lastalarmstate_) { if (alarmstate_ == 0) setfieldcolor(0, procloadcol_); else if (alarmstate_ == 1) setfieldcolor(0, warnloadcol_); else setfieldcolor(0, critloadcol_); drawlegend(); lastalarmstate_ = alarmstate_; } // Adjust total to next power-of-two of the current load. if ( (fields_[0]*5.0 < total_ && total_ > 1.0) || fields_[0] > total_ ) { unsigned int i = fields_[0]; i |= i >> 1; i |= i >> 2; i |= i >> 4; i |= i >> 8; i |= i >> 16; // i = 2^n - 1 total_ = i + 1; } fields_[1] = total_ - fields_[0]; setUsed(fields_[0], total_); } xosview-1.20/bsd/loadmeter.h000066400000000000000000000022431317735352700160530ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // Most of this code was written by Werner Fink // Only small changes were made on my part (M.R.) // And the near-trivial port to NetBSD was by bgrayson. // // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _LOADMETER_H_ #define _LOADMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class LoadMeter : public FieldMeterGraph { public: LoadMeter( XOSView *parent ); ~LoadMeter( void ); const char *name( void ) const { return "LoadMeter"; } void checkevent( void ); void checkResources( void ); protected: void getloadinfo( void ); private: unsigned long procloadcol_, warnloadcol_, critloadcol_; int warnThreshold_, critThreshold_, alarmstate_, lastalarmstate_; int old_cpu_speed_, cur_cpu_speed_; bool do_cpu_speed_; }; #endif xosview-1.20/bsd/memmeter.cc000066400000000000000000000043421317735352700160520ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was originally written by Brian Grayson for the NetBSD and // xosview projects. // The NetBSD memmeter was improved by Tom Pavel (pavel@slac.stanford.edu) // to provide active and inactive values, rather than just "used." // // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "memmeter.h" #include "defines.h" #include "kernel.h" #include MemMeter::MemMeter( XOSView *parent ) #if defined(HAVE_UVM) : FieldMeterGraph( parent, 4, "MEM", "ACT/INACT/WRD/FREE" ) { #else : FieldMeterGraph( parent, 5, "MEM", "ACT/INACT/WRD/CA/FREE" ) { #endif BSDPageInit(); } MemMeter::~MemMeter( void ) { } void MemMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("memActiveColor") ); setfieldcolor( 1, parent_->getResource("memInactiveColor") ); setfieldcolor( 2, parent_->getResource("memWiredColor") ); #if defined(HAVE_UVM) setfieldcolor( 3, parent_->getResource("memFreeColor") ); #else setfieldcolor( 3, parent_->getResource("memCacheColor") ); setfieldcolor( 4, parent_->getResource("memFreeColor") ); #endif priority_ = atoi( parent_->getResource("memPriority") ); dodecay_ = parent_->isResourceTrue("memDecay"); useGraph_ = parent_->isResourceTrue("memGraph"); SetUsedFormat( parent_->getResource("memUsedFormat") ); } void MemMeter::checkevent( void ) { getmeminfo(); drawfields(); } void MemMeter::getmeminfo( void ) { BSDGetPageStats(meminfo_, NULL); fields_[0] = (double)meminfo_[0]; fields_[1] = (double)meminfo_[1]; fields_[2] = (double)meminfo_[2]; #if defined(HAVE_UVM) fields_[3] = (double)meminfo_[4]; #else fields_[3] = (double)meminfo_[3]; fields_[4] = (double)meminfo_[4]; #endif total_ = (double)(meminfo_[0] + meminfo_[1] + meminfo_[2] + meminfo_[3] + meminfo_[4]); setUsed(total_ - (double)meminfo_[4], total_); } xosview-1.20/bsd/memmeter.h000066400000000000000000000016661317735352700157220ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _MEMMETER_H_ #define _MEMMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class MemMeter : public FieldMeterGraph { public: MemMeter( XOSView *parent ); ~MemMeter( void ); const char *name( void ) const { return "MemMeter"; } void checkevent( void ); void checkResources( void ); protected: void getmeminfo( void ); private: uint64_t meminfo_[5]; }; #endif xosview-1.20/bsd/netmeter.cc000066400000000000000000000052211317735352700160570ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "netmeter.h" #include "kernel.h" #include #include NetMeter::NetMeter( XOSView *parent, double max ) : FieldMeterGraph( parent, 3, "NET", "IN/OUT/IDLE" ) { if (!BSDNetInit()) { warnx("The kernel does not seem to have the symbols needed for the NetMeter."); warnx("The NetMeter has been disabled."); disableMeter (); } else { total_ = netBandwidth_ = max; lastBytesIn_ = lastBytesOut_ = 0; netIface_ = "False"; ignored_ = false; BSDGetNetInOut(&lastBytesIn_, &lastBytesOut_, netIface_.c_str(), ignored_); IntervalTimerStart(); } } NetMeter::~NetMeter( void ) { } void NetMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("netInColor") ); setfieldcolor( 1, parent_->getResource("netOutColor") ); setfieldcolor( 2, parent_->getResource("netBackground") ); priority_ = atoi( parent_->getResource("netPriority") ); dodecay_ = parent_->isResourceTrue("netDecay"); useGraph_ = parent_->isResourceTrue("netGraph"); SetUsedFormat( parent_->getResource("netUsedFormat") ); netIface_ = parent_->getResource("netIface"); if (netIface_[0] == '-') { ignored_ = true; netIface_.erase(0, netIface_.find_first_not_of("- ")); } } void NetMeter::checkevent( void ) { getstats(); drawfields(); } void NetMeter::getstats(void) { // Reset total_ to expected maximum. If it is too low, it // will be adjusted in adjust(). bgrayson total_ = netBandwidth_; fields_[0] = fields_[1] = 0; uint64_t nowBytesIn, nowBytesOut; IntervalTimerStop(); BSDGetNetInOut(&nowBytesIn, &nowBytesOut, netIface_.c_str(), ignored_); double t = (1.0) / IntervalTimeInSecs(); IntervalTimerStart(); fields_[0] = (double)(nowBytesIn - lastBytesIn_) * t; lastBytesIn_ = nowBytesIn; fields_[1] = (double)(nowBytesOut - lastBytesOut_) * t; lastBytesOut_ = nowBytesOut; if (total_ < (fields_[0] + fields_[1])) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - fields_[0] - fields_[1]; /* The fields_ values have already been scaled into bytes/sec by * the manipulations (* t) above. */ setUsed(fields_[0] + fields_[1], total_); } xosview-1.20/bsd/netmeter.h000066400000000000000000000020371317735352700157230ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _NETMETER_H_ #define _NETMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include class NetMeter : public FieldMeterGraph { public: NetMeter( XOSView *parent, double max ); ~NetMeter( void ); const char *name( void ) const { return "NetMeter"; } void checkevent( void ); void checkResources( void ); protected: void getstats(void); private: uint64_t lastBytesIn_, lastBytesOut_; double netBandwidth_; std::string netIface_; bool ignored_; }; #endif xosview-1.20/bsd/pagemeter.cc000066400000000000000000000033671317735352700162160ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was originally written by Brian Grayson for the NetBSD and // xosview projects. // // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "pagemeter.h" #include "kernel.h" #include PageMeter::PageMeter( XOSView *parent, double total ) : FieldMeterGraph( parent, 3, "PAGE", "IN/OUT/IDLE" ) { total_ = total; BSDPageInit(); BSDGetPageStats(NULL, previnfo_); } PageMeter::~PageMeter( void ) { } void PageMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("pageInColor") ); setfieldcolor( 1, parent_->getResource("pageOutColor") ); setfieldcolor( 2, parent_->getResource("pageIdleColor") ); priority_ = atoi( parent_->getResource("pagePriority") ); dodecay_ = parent_->isResourceTrue("pageDecay"); useGraph_ = parent_->isResourceTrue("pageGraph"); SetUsedFormat( parent_->getResource("pageUsedFormat") ); } void PageMeter::checkevent( void ) { getpageinfo(); drawfields(); } void PageMeter::getpageinfo( void ) { uint64_t info[2]; BSDGetPageStats(NULL, info); fields_[0] = info[0] - previnfo_[0]; fields_[1] = info[1] - previnfo_[1]; previnfo_[0] = info[0]; previnfo_[1] = info[1]; if (total_ < fields_[0] + fields_[1]) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - fields_[0] - fields_[1]; setUsed(total_ - fields_[2], total_); } xosview-1.20/bsd/pagemeter.h000066400000000000000000000017141317735352700160520ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _PAGEMETER_H_ #define _PAGEMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class PageMeter : public FieldMeterGraph { public: PageMeter( XOSView *parent, double total ); ~PageMeter( void ); const char *name( void ) const { return "PageMeter"; } void checkevent( void ); void checkResources( void ); protected: void getpageinfo( void ); private: uint64_t previnfo_[2]; }; #endif xosview-1.20/bsd/sensor.cc000066400000000000000000000056161317735352700155550ustar00rootroot00000000000000// // Copyright (c) 2012 by Tomi Tapper // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // // #include "sensor.h" #include "kernel.h" #include #include #include #include #include BSDSensor::BSDSensor( XOSView *parent, const char *name, const char *high, const char *low, const char *label, const char *caption, int nbr ) : SensorFieldMeter( parent, label, caption, 1, 1, 0 ) { nbr_ = nbr; highname_[0] = highval_[0] = '\0'; lowname_[0] = lowval_[0] = '\0'; std::string n(name), tmp; tmp = n.substr( 0, n.find_first_of('.') ); strncpy(name_, tmp.c_str(), NAMESIZE); tmp = n.substr( n.find_first_of('.') + 1 ); strncpy(val_, tmp.c_str(), NAMESIZE); if (high) { has_high_ = true; if ( sscanf(high, "%lf", &high_) == 0 ) { // high given as number? n = high; tmp = n.substr( 0, n.find_first_of('.') ); strncpy(highname_, tmp.c_str(), NAMESIZE); tmp = n.substr( n.find_first_of('.') + 1 ); strncpy(highval_, tmp.c_str(), NAMESIZE); } } if (low) { has_low_ = true; if ( sscanf(low, "%lf", &low_) == 0 ) { // low given as number? n = low; tmp = n.substr( 0, n.find_first_of('.') ); strncpy(lowname_, tmp.c_str(), NAMESIZE); tmp = n.substr( n.find_first_of('.') + 1 ); strncpy(lowval_, tmp.c_str(), NAMESIZE); } } } BSDSensor::~BSDSensor( void ) { } void BSDSensor::checkResources( void ) { SensorFieldMeter::checkResources(); actcolor_ = parent_->allocColor( parent_->getResource( "bsdsensorActColor" ) ); highcolor_ = parent_->allocColor( parent_->getResource( "bsdsensorHighColor" ) ); lowcolor_ = parent_->allocColor( parent_->getResource( "bsdsensorLowColor" ) ); setfieldcolor( 0, actcolor_ ); setfieldcolor( 1, parent_->getResource( "bsdsensorIdleColor" ) ); setfieldcolor( 2, highcolor_ ); priority_ = atoi( parent_->getResource( "bsdsensorPriority" ) ); char s[32]; const char *tmp = parent_->getResourceOrUseDefault( "bsdsensorHighest", "0" ); snprintf(s, 32, "bsdsensorHighest%d", nbr_); total_ = fabs( atof( parent_->getResourceOrUseDefault(s, tmp) ) ); snprintf(s, 32, "bsdsensorUsedFormat%d", nbr_); const char *f = parent_->getResourceOrUseDefault(s, NULL); SetUsedFormat( f ? f : parent_->getResource( "bsdsensorUsedFormat" ) ); if (!has_high_) high_ = total_; if (!has_low_) low_ = 0; // Get the unit. float dummy; BSDGetSensor(name_, val_, &dummy, unit_); updateLegend(); } void BSDSensor::checkevent( void ) { getsensor(); drawfields(); } void BSDSensor::getsensor( void ) { float value, high = high_, low = low_; BSDGetSensor(name_, val_, &value); if ( strlen(highname_) ) BSDGetSensor(highname_, highval_, &high); if ( strlen(lowname_) ) BSDGetSensor(lowname_, lowval_, &low); fields_[0] = value; checkFields(low, high); } xosview-1.20/bsd/sensor.h000066400000000000000000000015611317735352700154120ustar00rootroot00000000000000// // Copyright (c) 2012 by Tomi Tapper // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // // #ifndef _BSDSENSOR_H_ #define _BSDSENSOR_H_ #include "sensorfieldmeter.h" #include "xosview.h" #define NAMESIZE 32 class BSDSensor : public SensorFieldMeter { public: BSDSensor( XOSView *parent, const char *name, const char *high, const char *low, const char *label, const char *caption, int nbr ); ~BSDSensor( void ); const char *name( void ) const { return "BSDSensor"; } void checkevent( void ); void checkResources( void ); protected: void getsensor( void ); private: char name_[NAMESIZE], highname_[NAMESIZE], lowname_[NAMESIZE]; char val_[NAMESIZE], highval_[NAMESIZE], lowval_[NAMESIZE]; int nbr_; }; #endif xosview-1.20/bsd/swapmeter.cc000066400000000000000000000030441317735352700162440ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // NetBSD port: // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #include "swapmeter.h" #include "kernel.h" #include SwapMeter::SwapMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "SWAP", "USED/FREE" ) { BSDSwapInit(); } SwapMeter::~SwapMeter( void ) { } void SwapMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("swapUsedColor") ); setfieldcolor( 1, parent_->getResource("swapFreeColor") ); priority_ = atoi( parent_->getResource("swapPriority") ); dodecay_ = parent_->isResourceTrue("swapDecay"); useGraph_ = parent_->isResourceTrue("swapGraph"); SetUsedFormat( parent_->getResource("swapUsedFormat") ); } void SwapMeter::checkevent( void ) { getswapinfo(); drawfields(); } void SwapMeter::getswapinfo( void ) { uint64_t total = 0, used = 0; BSDGetSwapInfo(&total, &used); total_ = (double)total; if ( total_ == 0.0 ) total_ = 1.0; /* We don't want any division by zero, now, do we? :) */ fields_[0] = (double)used; fields_[1] = total_; setUsed(fields_[0], total_); } xosview-1.20/bsd/swapmeter.h000066400000000000000000000015021317735352700161030ustar00rootroot00000000000000// // Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _SWAPMETER_H_ #define _SWAPMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class SwapMeter : public FieldMeterGraph { public: SwapMeter( XOSView *parent ); ~SwapMeter( void ); const char *name( void ) const { return "SwapMeter"; } void checkevent( void ); void checkResources( void ); protected: void getswapinfo( void ); }; #endif xosview-1.20/defresources.awk000066400000000000000000000012331317735352700163510ustar00rootroot00000000000000# # This is a simple awk program which will generate defaultstring.cc # from an X resource file. # # # insert the "header" for defaultstring.cc # BEGIN { print "//"; print "// Do not edit this file."; print "// This file is generated automagically from Xdefaults"; print "// using the awk program found in defresources.awk."; print "// This file will be rebuilt when Xdefaults is modified."; print "//\n"; printf "const char *defaultXResourceString = \""; } # # Echo each line of input (that is not a comment or empty) to stdout. # (! /^!/) && (NF != 0) { printf "%s\\n\\\n", $0 } # # Insert the "tail" for defresources.cc # END { print "\";\n"; } xosview-1.20/fieldmeter.cc000066400000000000000000000210751317735352700156110ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "fieldmeter.h" #include #include #include #include #include FieldMeter::FieldMeter( XOSView *parent, int numfields, const char *title, const char *legend, int docaptions, int dolegends, int dousedlegends ) : Meter(parent, title, legend, docaptions, dolegends, dousedlegends){ /* We need to set print_ to something valid -- the meters * apparently get drawn before the meters have a chance to call * CheckResources() themselves. */ numWarnings_ = printedZeroTotalMesg_ = 0; print_ = PERCENT; metric_ = false; usedoffset_ = 0; used_ = 0; lastused_ = -1; fields_ = NULL; colors_ = NULL; lastvals_ = NULL; lastx_ = NULL; setNumFields(numfields); } void FieldMeter::disableMeter ( ) { setNumFields(1); setfieldcolor (0, "gray"); Meter::legend ("Disabled"); // And specify the total of 1.0, so the meter is grayed out. total_ = 1.0; fields_[0] = 1.0; } FieldMeter::~FieldMeter( void ){ delete[] fields_; delete[] colors_; delete[] lastvals_; delete[] lastx_; } void FieldMeter::checkResources( void ){ Meter::checkResources(); usedcolor_ = parent_->allocColor( parent_->getResource( "usedLabelColor") ); } void FieldMeter::SetUsedFormat ( const char * const fmt ) { /* Do case-insensitive compares. */ if (!strncasecmp (fmt, "percent", 8)) print_ = PERCENT; else if (!strncasecmp (fmt, "autoscale", 10)) print_ = AUTOSCALE; else if (!strncasecmp (fmt, "float", 6)) print_ = FLOAT; else { std::cerr << "Error: could not parse format of '" << fmt << "'.\n" << " I expected one of 'percent', 'autoscale', or 'float'" << " (Case-insensitive)." << std::endl; exit(1); } } void FieldMeter::setUsed (double val, double total) { if (print_ == FLOAT) used_ = val; else if (print_ == PERCENT) { if (total != 0.0) used_ = val / total * 100.0; else { if (!printedZeroTotalMesg_) { printedZeroTotalMesg_ = 1; std::cerr << "Warning: " << name() << " meter had a zero total field! " << "Would have caused a div-by-zero exception." << std::endl; } used_ = 0.0; } } else if (print_ == AUTOSCALE) used_ = val; else { std::cerr << "Error in " << name() << ": I can't handle a UsedType enum " << "value of " << print_ << "!" << std::endl; exit(1); } } void FieldMeter::reset( void ){ for ( int i = 0 ; i < numfields_ ; i++ ) lastvals_[i] = lastx_[i] = -1; } void FieldMeter::setfieldcolor( int field, const char *color ){ colors_[field] = parent_->allocColor( color ); } void FieldMeter::setfieldcolor( int field, unsigned long color ) { colors_[field] = color; } void FieldMeter::draw( void ){ /* Draw the outline for the fieldmeter. */ parent_->setForeground( parent_->foreground() ); parent_->drawRectangle( x_ - 1, y_ - 1, width_ + 2, height_ + 2 ); if ( dolegends_ ){ parent_->setForeground( textcolor_ ); int offset; if ( dousedlegends_ ) offset = parent_->textWidth( "XXXXXXXXXX" ); else offset = parent_->textWidth( "XXXXXX" ); parent_->drawString( x_ - offset + 1, y_ + height_, title_ ); } drawlegend(); drawfields( 1 ); } void FieldMeter::drawlegend( void ){ char *tmp1, *tmp2, buff[100]; int n, x = x_; if (!docaptions_ || !dolegends_) return; parent_->clear( x_, y_ - 5 - parent_->textHeight(), width_ + 5, parent_->textHeight() + 4 ); tmp1 = tmp2 = legend_; for ( int i = 0 ; i < numfields_ ; i++ ){ n = 0; while ( (*tmp2 != '/') && (*tmp2 != '\0') ){ if ( (*tmp2 == '\\') && (*(tmp2 + 1) == '/') ) // allow '/' in field as '\/' memmove( tmp2, tmp2 + 1, strlen(tmp2) ); tmp2++; n++; } tmp2++; strncpy( buff, tmp1, n ); buff[n] = '\0'; parent_->setStippleN(i%4); parent_->setForeground( colors_[i] ); parent_->drawString( x, y_ - 5, buff ); x += parent_->textWidth( buff, n ); parent_->setForeground( parent_->foreground() ); if ( i != numfields_ - 1 ) parent_->drawString( x, y_ - 5, "/" ); x += parent_->textWidth( "/", 1 ); tmp1 = tmp2; } parent_->setStippleN(0); /* Restore default all-bits stipple. */ } void FieldMeter::drawused( int mandatory ){ if ( !mandatory ) if ( lastused_ == used_ ) return; parent_->setStippleN(0); /* Use all-bits stipple. */ static const int onechar = parent_->textWidth( "X" ); if (!usedoffset_) // metric meters need extra space for '-' sign usedoffset_ = ( metric_ ? parent_->textWidth( "XXXXXX" ) : parent_->textWidth( "XXXXX" ) ); char buf[10]; if (print_ == PERCENT){ snprintf( buf, 10, "%d%%", (int)used_ ); } else if (print_ == AUTOSCALE){ char scale[2]; double scaled_used = scaleValue(used_, scale, metric_); /* For now, we can only print 3 characters, plus the optional sign and * suffix, without overprinting the legends. Thus, we can * print 965, or we can print 34, but we can't print 34.7 (the * decimal point takes up one character). bgrayson */ if (scaled_used == 0.0) snprintf (buf, 10, "0"); else { if (scaled_used < 0 && !metric_) snprintf (buf, 10, "-"); else if ( fabs(scaled_used) < 9.95 ) // 9.95 or above would get // rounded to 10.0, which is too wide. snprintf (buf, 10, "%.1f%s", scaled_used, scale); else snprintf (buf, 10, "%.0f%s", scaled_used, scale); } } else { if ( fabs(used_) < 99.95 ) snprintf( buf, 10, "%.1f", used_ ); else // drop the decimal if the string gets too long snprintf( buf, 10, "%.0f", used_ ); } parent_->clear( x_ - usedoffset_, y_ + height_ - parent_->textHeight(), usedoffset_ - onechar / 2, parent_->textHeight() + 1 ); parent_->setForeground( usedcolor_ ); parent_->drawString( x_ - (strlen( buf ) + 1 ) * onechar + 2, y_ + height_, buf ); lastused_ = used_; } void FieldMeter::drawfields( int mandatory ){ int twidth, x = x_; if ( total_ == 0 ) return; for ( int i = 0 ; i < numfields_ ; i++ ){ /* Look for bogus values. */ if (fields_[i] < 0.0 && !metric_) { /* Only print a warning 5 times per meter, followed by a * message about no more warnings. */ numWarnings_ ++; if (numWarnings_ < 5) std::cerr << "Warning: meter " << name() << " had a negative value of " << fields_[i] << " for field " << i << std::endl; if (numWarnings_ == 5) std::cerr << "Future warnings from the " << name() << " meter will not " << "be displayed." << std::endl; } twidth = (int)fabs(((width_ * fields_[i]) / total_)); if ( (i == numfields_ - 1) && ((x + twidth) != (x_ + width_)) ) twidth = width_ + x_ - x; if ( mandatory || (twidth != lastvals_[i]) || (x != lastx_[i]) ){ parent_->setForeground( colors_[i] ); parent_->setStippleN(i%4); parent_->drawFilledRectangle( x, y_, twidth, height_ ); parent_->setStippleN(0); /* Restore all-bits stipple. */ lastvals_[i] = twidth; lastx_[i] = x; } x += twidth; } if ( dousedlegends_ ) drawused( mandatory ); } void FieldMeter::checkevent( void ){ drawfields(0); } void FieldMeter::setNumFields(int n){ numfields_ = n; delete[] fields_; delete[] colors_; delete[] lastvals_; delete[] lastx_; fields_ = new double[numfields_]; colors_ = new unsigned long[numfields_]; lastvals_ = new int[numfields_]; lastx_ = new int[numfields_]; total_ = 0; for ( int i = 0 ; i < numfields_ ; i++ ){ fields_[i] = 0.0; /* egcs 2.91.66 bug !? don't do this and */ lastvals_[i] = lastx_[i] = 0; /* that in a single statement or it'll */ /* overwrite too much with 0 ... */ /* Thomas Waldmann ( tw@com-ma.de ) */ } } bool FieldMeter::checkX(int x, int width) const { if ((x < x_) || (x + width < x_) || (x > x_ + width_) || (x + width > x_ + width_)){ std::cerr << "FieldMeter::checkX() : bad horiz values for meter : " << name() << std::endl; std::cerr <<"value "< FieldMeterDecay::FieldMeterDecay( XOSView *parent, int numfields, const char *title, const char *legend, int docaptions, int dolegends, int dousedlegends ) : FieldMeter (parent, numfields, title, legend, docaptions, dolegends, dousedlegends) { decay_ = new double[numfields]; lastDecayval_ = new double[numfields]; firsttime_ = 1; dodecay_ = 1; } FieldMeterDecay::~FieldMeterDecay( void ){ delete[] decay_; delete[] lastDecayval_; } void FieldMeterDecay::drawfields( int mandatory ){ int twidth, x = x_; int decay_changed = 0; if (!dodecay_) { // If this meter shouldn't be done as a decaying splitmeter, // call the ordinary fieldmeter code. FieldMeter::drawfields (mandatory); return; } if ( total_ == 0.0 ) return; int halfheight = height_ / 2; int decaytwidth, decayx = x_; // This code is supposed to make the average display look just like // the ordinary display for the first drawfields, but it doesn't seem // to work too well. But it's better than setting all decay_ fields // to 0.0 initially! if (firsttime_) { firsttime_ = 0; mandatory = 1; for (int i = 0; i < numfields_; i++) { decay_[i] = 1.0*fields_[i]/total_; } } // Update the decay fields. This is not quite accurate, since if // the screen is refreshed, we will update the decay fields more // often than we need to. However, this makes the decay stuff // TOTALLY independent of the ????Meter methods. // The constant below can be modified for quicker or slower // exponential rates for the average. No fancy math is done to // set it to correspond to a five-second decay or anything -- I // just played with it until I thought it looked good! :) BCG #define ALPHA 0.97 /* This is majorly ugly code. It needs a rewrite. BCG */ /* I think one good way to do it may be to normalize all of the * fields_ in a temporary array into the range 0.0 .. 1.0, * calculate the shifted starting positions and ending positions * for coloring, multiply by the pixel width of the meter, and * then turn to ints. I think this will solve a whole bunch of * our problems with rounding that before we tackled at a whole * lot of places. BCG */ for ( int i = 0 ; i < numfields_ ; i++ ){ decay_[i] = ALPHA*decay_[i] + (1-ALPHA)*(fields_[i]*1.0/total_); // We want to round the widths, rather than truncate. twidth = (int) (0.5 + (width_ * (double) fields_[i]) / total_); decaytwidth = (int) (0.5 + width_ * decay_[i]); if (decaytwidth < 0.0) { std::cerr << "Error: FieldMeterDecay " << name() << ": decaytwidth of "; std::cerr << decaytwidth << ", width of " << width_ << ", decay_[" << i; std::cerr << "] of " << decay_[i] << std::endl; } // However, due to rounding, we may have gone one // pixel too far by the time we get to the later fields... if (x + twidth > x_ + width_) twidth = width_ + x_ - x; if (decayx + decaytwidth > x_ + width_) decaytwidth = width_ + x_ - decayx; // Also, due to rounding error, the last field may not go far // enough... if ( (i == numfields_ - 1) && ((x + twidth) != (x_ + width_)) ) twidth = width_ + x_ - x; if ( (i == numfields_ - 1) && ((decayx + decaytwidth) != (x_ + width_))) decaytwidth = width_ + x_ - decayx; parent_->setForeground( colors_[i] ); parent_->setStippleN(i%4); // drawFilledRectangle() adds one to its width and height. // Let's correct for that here. if ( mandatory || (twidth != lastvals_[i]) || (x != lastx_[i]) ){ if (!checkX(x, twidth)) std::cerr <<__FILE__ << ":" << __LINE__ <drawFilledRectangle( x, y_, twidth, halfheight ); } if ( mandatory || decay_changed || (decay_[i] != lastDecayval_[i]) ){ if (!checkX(decayx, decaytwidth)) std::cerr <<__FILE__ << ":" << __LINE__ <drawFilledRectangle( decayx, y_+halfheight+1, decaytwidth, height_ - halfheight-1); } lastvals_[i] = twidth; lastx_[i] = x; lastDecayval_[i] = decay_[i]; parent_->setStippleN(0); /* Restore all-bits stipple. */ if ( dousedlegends_ ) drawused( mandatory ); x += twidth; decayx += decaytwidth; } } xosview-1.20/fieldmeterdecay.h000066400000000000000000000022621317735352700164560ustar00rootroot00000000000000// // Original FieldMeter class is Copyright (c) 1994, 2006 by Mike Romberg // ( mike.romberg@noaa.gov ) // Modifications from FieldMeter class done in Oct. 1995 // by Brian Grayson ( bgrayson@netbsd.org ) // // This file was written by Brian Grayson for the NetBSD and xosview // projects. // This file may be distributed under terms of the GPL or of the BSD // license, whichever you choose. The full license notices are // contained in the files COPYING.GPL and COPYING.BSD, which you // should have received. If not, contact one of the xosview // authors for a copy. // #ifndef _FIELDMETERDECAY_H_ #define _FIELDMETERDECAY_H_ #include "fieldmeter.h" #include "xosview.h" class FieldMeterDecay : public FieldMeter { public: FieldMeterDecay( XOSView *parent, int numfields, const char *title = "", const char *legend = "", int docaptions = 0, int dolegends = 0, int dousedlegends = 0 ); virtual ~FieldMeterDecay( void ); virtual void drawfields( int mandatory = 0 ); protected: int dodecay_; int firsttime_; // Used to set up decaying fields right the first time. double *decay_; double *lastDecayval_; private: }; #endif xosview-1.20/fieldmetergraph.cc000066400000000000000000000114571317735352700166360ustar00rootroot00000000000000// // The original FieldMeter class is Copyright (c) 1994, 2006 by Mike Romberg // ( mike.romberg@noaa.gov ) // // Modifications from FieldMeter class done in Oct. 1995 // by Brian Grayson ( bgrayson@netbsd.org ) // // Modifications from FieldMeterDecay class done in Oct. 1998 // by Scott McNab ( jedi@tartarus.uwa.edu.au ) // // In order to use the FieldMeterGraph class in place of a FieldMeter class in // a meter file (say, cpumeter.cc), make the following changes: // 1. Change cpumeter.h to include fieldmetergraph.h instead of // fieldmeter.h // 2. Change CPUMeter to inherit from FieldMeterGraph, rather than // FieldMeter. // 3. Change the constructor call to use FieldMeterGraph(), rather than // FieldMeter(). // 4. Make the meter call FieldMeterGraph::checkResources(), // to pick up graphNumCols resource. // 5. Make the checkResources () function in the meter set the // useGraph_ variable according to the, e.g., xosview*cpuGraph resource. #include "fieldmetergraph.h" #include FieldMeterGraph::FieldMeterGraph( XOSView *parent, int numfields, const char *title, const char *legend, int docaptions, int dolegends, int dousedlegends ) : FieldMeterDecay (parent, numfields, title, legend, docaptions, dolegends, dousedlegends) { useGraph_ = 0; heightfield_ = NULL; lastWinState = XOSView::OBSCURED; // set number of columns to a reasonable default in case we can't // find the resource setNumCols( 100 ); } FieldMeterGraph::~FieldMeterGraph( void ) { delete [] heightfield_; } void FieldMeterGraph::drawfields( int mandatory ) { int i,j; enum XOSView::windowVisibilityState currWinState; if( !useGraph_ ) { // Call FieldMeterDecay code if this meter should not be // drawn as a graph FieldMeterDecay::drawfields( mandatory ); return; } if( total_ <= 0.0 ) return; // allocate memory for height field graph storage // note: this is done here as it is not certain that both // numfields_ and graphNumCols_ are defined in the constructor if( heightfield_ == NULL ) { if( numfields_ > 0 && graphNumCols_ > 0 ) { heightfield_ = new double [numfields_*graphNumCols_]; for( i = 0; i < graphNumCols_; i++ ) { for( j = 0; j < numfields_; j++ ) { if( j < numfields_-1 ) heightfield_[i*numfields_+j] = 0.0; else heightfield_[i*numfields_+j] = 1.0; } } } } // check current position here and slide graph if necessary if( graphpos_ >= graphNumCols_ ) { for( i = 0; i < graphNumCols_-1; i++ ) { for( j = 0; j < numfields_; j++ ) { heightfield_[i*numfields_+j] = heightfield_[(i+1)*numfields_+j]; } } graphpos_ = graphNumCols_ - 1; } // get current values to be plotted for( i = 0; i < numfields_; i++ ) { double a = fields_[i] / total_; if( a <= 0.0 ) a = 0.0; if( a >= 1.0 ) a = 1.0; heightfield_[graphpos_*numfields_+i] = a; } currWinState = parent_->getWindowVisibilityState(); // Try to avoid having to redraw everything. if (!mandatory && currWinState == XOSView::FULLY_VISIBLE && currWinState == lastWinState) { // scroll area int col_width = width_/graphNumCols_; if( col_width < 1 ) { col_width = 1; } int sx = x_ + col_width; int swidth = width_ - col_width; int sheight = height_ + 1; if( sx > x_ && swidth > 0 && sheight > 0 ) parent_->copyArea( sx, y_, swidth, sheight, x_, y_ ); drawBar( graphNumCols_ - 1 ); } else { // need to draw entire graph for some reason for( i = 0; i < graphNumCols_; i++ ) { drawBar( i ); } } lastWinState = currWinState; graphpos_++; parent_->setStippleN(0); // Restore all-bits stipple. if ( dousedlegends_ ) { drawused( mandatory ); } } void FieldMeterGraph::drawBar( int i ) { int j; int y = y_ + height_; int x = x_ + i*width_/graphNumCols_; int barwidth = (x_ + (i+1)*width_/graphNumCols_)-x; if( barwidth>0 ) { int barheight; for( j = 0 ; j < numfields_; j++ ) { /* Round up, by adding 0.5 before * converting to an int. */ barheight = (int)((heightfield_[i*numfields_+j]*height_)+0.5); parent_->setForeground( colors_[j] ); parent_->setStippleN(j%4); if( barheight > (y-y_) ) barheight = (y-y_); // hack to ensure last field always reaches top of graph area if( j == numfields_-1 ) barheight = (y-y_); y -= barheight; if( barheight>0 ) parent_->drawFilledRectangle( x, y, barwidth, barheight ); } } } void FieldMeterGraph::checkResources( void ) { FieldMeterDecay::checkResources(); const char *ptr = parent_->getResource( "graphNumCols" ); if( ptr ) { int i; if( sscanf( ptr, "%d", &i ) == 1 ) { if( i>0 ) { setNumCols( i ); } } } } void FieldMeterGraph::setNumCols( int n ) { graphNumCols_ = n; graphpos_ = graphNumCols_-1; if( heightfield_ ) delete [] heightfield_; heightfield_ = NULL; } xosview-1.20/fieldmetergraph.h000066400000000000000000000022451317735352700164730ustar00rootroot00000000000000// // Original FieldMeter class is Copyright (c) 1994, 2006 by Mike Romberg // ( mike.romberg@noaa.gov ) // // Modifications from FieldMeter class done in Oct. 1995 // by Brian Grayson ( bgrayson@netbsd.org ) // // Modifications from FieldMeterDecay class done in Oct. 1998 // by Scott McNab ( jedi@tartarus.uwa.edu.au ) // #ifndef _FIELDMETERGRAPH_H_ #define _FIELDMETERGRAPH_H_ #include "fieldmeterdecay.h" #include "xosview.h" class FieldMeterGraph : public FieldMeterDecay { public: FieldMeterGraph( XOSView *parent, int numfields, const char *title = "", const char *legend = "", int docaptions = 0, int dolegends = 0, int dousedlegends = 0 ); virtual ~FieldMeterGraph( void ); virtual void drawfields( int mandatory = 0 ); virtual void checkResources( void ); protected: void setNumCols( int n ); int useGraph_; int graphNumCols_; int graphpos_; /* There's some sort of corruption going on -- we can't have * variables after the heightfield_ below, otherwise they get * corrupted??? */ double *heightfield_; private: void drawBar( int i ); enum XOSView::windowVisibilityState lastWinState; }; #endif xosview-1.20/gnu/000077500000000000000000000000001317735352700137465ustar00rootroot00000000000000xosview-1.20/gnu/MeterMaker.cc000066400000000000000000000013751317735352700163170ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2002 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #include "MeterMaker.h" #include "xosview.h" #include "memmeter.h" #include "swapmeter.h" #include "pagemeter.h" #include "loadmeter.h" #include MeterMaker::MeterMaker(XOSView *xos){ _xos = xos; } void MeterMaker::makeMeters(void){ if (_xos->isResourceTrue("load")) push(new LoadMeter(_xos)); if (_xos->isResourceTrue("mem")) push(new MemMeter(_xos)); if (_xos->isResourceTrue("swap")) push(new SwapMeter(_xos)); if (_xos->isResourceTrue("page")) push(new PageMeter(_xos, atof(_xos->getResource("pageBandwidth")))); } xosview-1.20/gnu/MeterMaker.h000066400000000000000000000006641317735352700161610ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #ifndef _MeterMaker_h #define _MeterMaker_h #include "pllist.h" class Meter; class XOSView; class MeterMaker : public PLList { public: MeterMaker(XOSView *xos); void makeMeters(void); private: XOSView *_xos; }; #endif xosview-1.20/gnu/get_def_pager.c000066400000000000000000000017701317735352700166720ustar00rootroot00000000000000// // Copyright (c) 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #define _GNU_SOURCE #include #include #include #include #include #include #include mach_port_t get_def_pager(void) { mach_port_t def_pager = MACH_PORT_NULL; kern_return_t err; mach_port_t host; err = get_privileged_ports (&host, 0); if (err == EPERM) { def_pager = file_name_lookup (_SERVERS_DEFPAGER, O_READ, 0); if (def_pager == MACH_PORT_NULL) error (0, errno, _SERVERS_DEFPAGER); return def_pager; } else if (err) { error (0, err, "get_privileged_ports"); return MACH_PORT_NULL; } else { err = vm_set_default_memory_manager (host, &def_pager); mach_port_deallocate (mach_task_self(), host); if (err) { error (0, err, "vm_set_default_memory_manager"); return MACH_PORT_NULL; } return def_pager; } } xosview-1.20/gnu/get_def_pager.h000066400000000000000000000002651317735352700166750ustar00rootroot00000000000000// // Copyright (c) 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // extern mach_port_t get_def_pager(void); xosview-1.20/gnu/loadmeter.cc000066400000000000000000000062671317735352700162440ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // // Most of this code was written by Werner Fink . // Only small changes were made on my part (M.R.) // #include "loadmeter.h" #include "xosview.h" #include #include #include extern "C" { #include #include } LoadMeter::LoadMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "LOAD", "PROCS/MIN", 1, 1, 0 ){ lastalarmstate = -1; total_ = 2.0; } LoadMeter::~LoadMeter( void ){ } void LoadMeter::checkResources( void ){ FieldMeterGraph::checkResources(); procloadcol_ = parent_->allocColor(parent_->getResource( "loadProcColor" )); warnloadcol_ = parent_->allocColor(parent_->getResource( "loadWarnColor" )); critloadcol_ = parent_->allocColor(parent_->getResource( "loadCritColor" )); setfieldcolor( 0, procloadcol_ ); setfieldcolor( 1, parent_->getResource( "loadIdleColor" ) ); priority_ = atoi (parent_->getResource( "loadPriority" ) ); useGraph_ = parent_->isResourceTrue( "loadGraph" ); dodecay_ = parent_->isResourceTrue( "loadDecay" ); SetUsedFormat (parent_->getResource("loadUsedFormat")); warnThreshold = atoi (parent_->getResource("loadWarnThreshold")); critThreshold = atoi (parent_->getResource("loadCritThreshold")); if (dodecay_){ // Warning: Since the loadmeter changes scale occasionally, old // decay values need to be rescaled. However, if they are rescaled, // they could go off the edge of the screen. Thus, for now, to // prevent this whole problem, the load meter can not be a decay // meter. The load is a decaying average kind of thing anyway, // so having a decaying load average is redundant. std::cerr << "Warning: The loadmeter can not be configured as a decay\n" << " meter. See the source code (" << __FILE__ << ") for further\n" << " details.\n"; dodecay_ = 0; } } void LoadMeter::checkevent( void ){ getloadinfo(); drawfields(); } void LoadMeter::getloadinfo( void ){ host_load_info_data_t info; mach_msg_type_number_t count = HOST_LOAD_INFO_COUNT; kern_return_t err; err = host_info(mach_host_self(), HOST_LOAD_INFO, (host_info_t) &info, &count); if (err) { std::cerr << "Can not get host info"; parent_->done(1); return; } fields_[0] = (float) info.avenrun[0] / LOAD_SCALE; if ( fields_[0] < warnThreshold ) alarmstate = 0; else if ( fields_[0] >= critThreshold ) alarmstate = 2; else /* if fields_[0] >= warnThreshold */ alarmstate = 1; if ( alarmstate != lastalarmstate ){ if ( alarmstate == 0 ) setfieldcolor( 0, procloadcol_ ); else if ( alarmstate == 1 ) setfieldcolor( 0, warnloadcol_ ); else /* if alarmstate == 2 */ setfieldcolor( 0, critloadcol_ ); drawlegend(); lastalarmstate = alarmstate; } if ( fields_[0]*5.0total_ ) total_ = fields_[0]*5.0; if ( total_ < 1.0) total_ = 1.0; fields_[1] = (float) (total_ - fields_[0]); setUsed(fields_[0], (float) 1.0); } xosview-1.20/gnu/loadmeter.h000066400000000000000000000014371317735352700161000ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // // Most of this code was written by Werner Fink // Only small changes were made on my part (M.R.) // #ifndef _LOADMETER_H_ #define _LOADMETER_H_ #include "fieldmetergraph.h" class LoadMeter : public FieldMeterGraph { public: LoadMeter( XOSView *parent ); ~LoadMeter( void ); const char *name( void ) const { return "LoadMeter"; } void checkevent( void ); void checkResources( void ); protected: void getloadinfo( void ); unsigned long procloadcol_, warnloadcol_, critloadcol_; private: int warnThreshold, critThreshold, alarmstate, lastalarmstate; }; #endif xosview-1.20/gnu/memmeter.cc000066400000000000000000000033151317735352700160720ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #include "memmeter.h" #include "xosview.h" #include #include #include #include extern "C" { #include #include } MemMeter::MemMeter( XOSView *parent ) : FieldMeterGraph( parent, 4, "MEM", "ACT/INACT/WIRE/FREE" ){ } MemMeter::~MemMeter( void ){ } void MemMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "memActiveColor" ) ); setfieldcolor( 1, parent_->getResource( "memInactiveColor" ) ); setfieldcolor( 2, parent_->getResource( "memCacheColor" ) ); setfieldcolor( 3, parent_->getResource( "memFreeColor" ) ); priority_ = atoi (parent_->getResource( "memPriority" ) ); dodecay_ = parent_->isResourceTrue( "memDecay" ); useGraph_ = parent_->isResourceTrue( "memGraph" ); SetUsedFormat (parent_->getResource("memUsedFormat")); } void MemMeter::checkevent( void ){ getmeminfo(); drawfields(); } void MemMeter::getmeminfo( void ){ kern_return_t err; err = vm_statistics (mach_task_self(), &vmstats); if (err) { error (0, err, "vm_statistics"); parent_->done(1); return; } fields_[0] = (double) vmstats.active_count * vmstats.pagesize; fields_[1] = (double) vmstats.inactive_count * vmstats.pagesize;; fields_[2] = (double) vmstats.wire_count * vmstats.pagesize;; fields_[3] = (double) vmstats.free_count * vmstats.pagesize;; total_ = fields_[0] + fields_[1] + fields_[2] + fields_[3]; FieldMeterDecay::setUsed (total_ - fields_[3], total_); } xosview-1.20/gnu/memmeter.h000066400000000000000000000011651317735352700157350ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #ifndef _MEMMETER_H_ #define _MEMMETER_H_ #include "fieldmetergraph.h" extern "C" { #include } class MemMeter : public FieldMeterGraph { public: MemMeter( XOSView *parent ); ~MemMeter( void ); const char *name( void ) const { return "MemMeter"; } void checkevent( void ); void checkResources( void ); protected: void getmeminfo( void ); private: struct vm_statistics vmstats; }; #endif xosview-1.20/gnu/pagemeter.cc000066400000000000000000000043451317735352700162340ustar00rootroot00000000000000// // Copyright (c) 1996, 2004 by Massimiliano Ghilardi ( ghilardi@cibs.sns.it ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #include "pagemeter.h" #include "xosview.h" #include #include #include #include #include #include extern "C" { #include #include } PageMeter::PageMeter( XOSView *parent, float max ) : FieldMeterGraph( parent, 3, "PAGE", "IN/OUT/IDLE" ) { for ( int i = 0 ; i < 2 ; i++ ) for ( int j = 0 ; j < 2 ; j++ ) pageinfo_[j][i] = 0; maxspeed_ = max; pageindex_ = 0; } PageMeter::~PageMeter( void ){ } void PageMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "pageInColor" ) ); setfieldcolor( 1, parent_->getResource( "pageOutColor" ) ); setfieldcolor( 2, parent_->getResource( "pageIdleColor" ) ); priority_ = atoi (parent_->getResource( "pagePriority" ) ); maxspeed_ *= priority_ / 10.0; dodecay_ = parent_->isResourceTrue( "pageDecay" ); useGraph_ = parent_->isResourceTrue( "pageGraph" ); SetUsedFormat (parent_->getResource("pageUsedFormat")); } void PageMeter::checkevent( void ){ getpageinfo(); drawfields(); } void PageMeter::updateinfo(void) { int oldindex = (pageindex_+1)%2; for ( int i = 0; i < 2; i++ ) { if ( pageinfo_[oldindex][i] == 0 ) pageinfo_[oldindex][i] = pageinfo_[pageindex_][i]; fields_[i] = pageinfo_[pageindex_][i] - pageinfo_[oldindex][i]; total_ += fields_[i]; } if ( total_ > maxspeed_ ) fields_[2] = 0.0; else { fields_[2] = maxspeed_ - total_; total_ = maxspeed_; } setUsed (total_ - fields_[2], maxspeed_); pageindex_ = (pageindex_ + 1) % 2; } void PageMeter::getpageinfo(void) { struct vm_statistics vmstats; total_ = 0; kern_return_t err; err = vm_statistics (mach_task_self(), &vmstats); if (err) { error (0, err, "vm_statistics"); parent_->done(1); return; } pageinfo_[pageindex_][0] = vmstats.pageins; pageinfo_[pageindex_][1] = vmstats.pageouts; updateinfo(); } xosview-1.20/gnu/pagemeter.h000066400000000000000000000012171317735352700160710ustar00rootroot00000000000000// // Copyright (c) 1996 by Massimiliano Ghilardi ( ghilardi@cibs.sns.it ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #ifndef _PAGEMETER_H_ #define _PAGEMETER_H_ #include "fieldmetergraph.h" class PageMeter : public FieldMeterGraph { public: PageMeter( XOSView *parent, float max ); ~PageMeter( void ); const char *name( void ) const { return "PageMeter"; } void checkevent( void ); void checkResources( void ); protected: float pageinfo_[2][2]; int pageindex_; float maxspeed_; void getpageinfo( void ); void updateinfo(void); private: }; #endif xosview-1.20/gnu/swapmeter.cc000066400000000000000000000032171317735352700162670ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #include "swapmeter.h" #include "xosview.h" #include #include #include #include extern "C" { #include #include #include #include "get_def_pager.h" } SwapMeter::SwapMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "SWAP", "ACTIVE/USED/FREE" ){ def_pager = MACH_PORT_NULL; } SwapMeter::~SwapMeter( void ){ } void SwapMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "swapUsedColor" ) ); setfieldcolor( 1, parent_->getResource( "swapFreeColor" ) ); priority_ = atoi (parent_->getResource( "swapPriority" ) ); dodecay_ = parent_->isResourceTrue( "swapDecay" ); useGraph_ = parent_->isResourceTrue( "swapGraph" ); SetUsedFormat (parent_->getResource("swapUsedFormat")); } void SwapMeter::checkevent( void ){ getswapinfo(); drawfields(); } void SwapMeter::getswapinfo( void ){ kern_return_t err; if (def_pager == MACH_PORT_NULL) def_pager = get_def_pager(); if (!MACH_PORT_VALID (def_pager)) { def_pager = MACH_PORT_DEAD; parent_->done(1); return; } err = default_pager_info (def_pager, &def_pager_info); if (err) { error (0, err, "default_pager_info"); parent_->done(1); return; } total_ = def_pager_info.dpi_total_space; fields_[1] = def_pager_info.dpi_free_space; fields_[0] = total_ - fields_[1]; if (total_) setUsed (fields_[0], total_); } xosview-1.20/gnu/swapmeter.h000066400000000000000000000013051317735352700161250ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // 2007 by Samuel Thibault ( samuel.thibault@ens-lyon.org ) // // This file may be distributed under terms of the GPL // #ifndef _SWAPMETER_H_ #define _SWAPMETER_H_ #include "fieldmetergraph.h" extern "C" { #include #include } class SwapMeter : public FieldMeterGraph { public: SwapMeter( XOSView *parent ); ~SwapMeter( void ); const char *name( void ) const { return "SwapMeter"; } void checkevent( void ); void checkResources( void ); protected: void getswapinfo( void ); private: struct default_pager_info def_pager_info; mach_port_t def_pager; }; #endif xosview-1.20/hpux/000077500000000000000000000000001317735352700141415ustar00rootroot00000000000000xosview-1.20/hpux/MeterMaker.cc000066400000000000000000000014341317735352700165060ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #include "MeterMaker.h" #include "xosview.h" #include "cpumeter.h" #include "memmeter.h" #include "swapmeter.h" #include "loadmeter.h" #include "pagemeter.h" #include MeterMaker::MeterMaker(XOSView *xos){ _xos = xos; } void MeterMaker::makeMeters(void){ if (_xos->isResourceTrue("load")) push(new LoadMeter(_xos)); if (_xos->isResourceTrue("cpu")) push(new CPUMeter(_xos)); if (_xos->isResourceTrue("mem")) push(new MemMeter(_xos)); if (_xos->isResourceTrue("swap")) push(new SwapMeter(_xos)); if (_xos->isResourceTrue("page")) push(new PageMeter(_xos, atof(_xos->getResource("pageBandwidth")))); } xosview-1.20/hpux/MeterMaker.h000066400000000000000000000005711317735352700163510ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _MeterMaker_h #define _MeterMaker_h #include "pllist.h" class Meter; class XOSView; class MeterMaker : public PLList { public: MeterMaker(XOSView *xos); void makeMeters(void); private: XOSView *_xos; }; #endif xosview-1.20/hpux/cpumeter.cc000066400000000000000000000034451317735352700163020ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #include "cpumeter.h" #include "xosview.h" #include #include CPUMeter::CPUMeter( XOSView *parent ) : FieldMeterGraph( parent, 5, "CPU", "USR/NICE/SYS/INT/FREE" ){ for ( int i = 0 ; i < 2 ; i++ ) for ( int j = 0 ; j < 5 ; j++ ) cputime_[i][j] = 0; cpuindex_ = 0; } CPUMeter::~CPUMeter( void ){ } void CPUMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "cpuUserColor" ) ); setfieldcolor( 1, parent_->getResource( "cpuNiceColor" ) ); setfieldcolor( 2, parent_->getResource( "cpuSystemColor" ) ); setfieldcolor( 3, parent_->getResource( "cpuInterruptColor" ) ); setfieldcolor( 4, parent_->getResource( "cpuFreeColor" ) ); priority_ = atoi (parent_->getResource( "cpuPriority" ) ); dodecay_ = parent_->isResourceTrue( "cpuDecay" ); useGraph_ = parent_->isResourceTrue( "cpuGraph" ); SetUsedFormat( parent_->getResource( "cpuUsedFormat" ) ); } void CPUMeter::checkevent( void ){ getcputime(); drawfields(); } void CPUMeter::getcputime( void ){ total_ = 0; struct pst_dynamic stats; pstat_getdynamic( &stats, sizeof( struct pst_dynamic ), 1, 0 ); cputime_[cpuindex_][0] = stats.psd_cpu_time[0]; cputime_[cpuindex_][1] = stats.psd_cpu_time[1]; cputime_[cpuindex_][2] = stats.psd_cpu_time[2]; cputime_[cpuindex_][3] = stats.psd_cpu_time[4]; cputime_[cpuindex_][4] = stats.psd_cpu_time[3]; int oldindex = (cpuindex_+1)%2; for ( int i = 0 ; i < 5 ; i++ ){ fields_[i] = cputime_[cpuindex_][i] - cputime_[oldindex][i]; total_ += fields_[i]; } cpuindex_ = (cpuindex_ + 1) % 2; if (total_){ setUsed( total_ - fields_[4], total_ ); } } xosview-1.20/hpux/cpumeter.h000066400000000000000000000010171317735352700161350ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _CPUMETER_H_ #define _CPUMETER_H_ #include "fieldmetergraph.h" class CPUMeter : public FieldMeterGraph { public: CPUMeter( XOSView *parent ); ~CPUMeter( void ); const char *name( void ) const { return "CPUMeter"; } void checkevent( void ); void checkResources(void); protected: float cputime_[2][5]; int cpuindex_; void getcputime( void ); private: }; #endif xosview-1.20/hpux/loadmeter.cc000066400000000000000000000041761317735352700164340ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 1997 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #include "loadmeter.h" #include "xosview.h" #include #include LoadMeter::LoadMeter( XOSView *parent ) : FieldMeterDecay( parent, 2, "LOAD", "PROCS/MIN", 1, 0 ){ } LoadMeter::~LoadMeter( void ){ } void LoadMeter::checkResources( void ){ FieldMeterDecay::checkResources(); warnloadcol_ = parent_->allocColor(parent_->getResource( "loadWarnColor" )); procloadcol_ = parent_->allocColor(parent_->getResource( "loadProcColor" )); setfieldcolor( 0, procloadcol_ ); setfieldcolor( 1, parent_->getResource( "loadIdleColor" ) ); priority_ = atoi (parent_->getResource( "loadPriority" ) ); dodecay_ = parent_->isResourceTrue( "loadDecay" ); SetUsedFormat( parent_->getResource( "loadUsedFormat" )); alarmThreshold = atoi (parent_->getResource("loadAlarmThreshold")); if (dodecay_){ // Warning: Since the loadmeter changes scale occasionally, old // decay values need to be rescaled. However, if they are rescaled, // they could go off the edge of the screen. Thus, for now, to // prevent this whole problem, the load meter can not be a decay // meter. The load is a decaying average kind of thing anyway, // so having a decaying load average is redundant. std::cerr << "Warning: The loadmeter can not be configured as a decay\n" << " meter. See the source code (" << __FILE__ << ") for further\n" << " details.\n"; dodecay_ = 0; } } void LoadMeter::checkevent( void ){ getloadinfo(); drawfields(); } void LoadMeter::getloadinfo( void ){ struct pst_dynamic pstd; pstat_getdynamic(&pstd, sizeof(pstd), 1, 0); fields_[0] = pstd.psd_avg_1_min; if ( fields_[0] > alarmThreshold ) { if (total_ == alarmThreshold ) { setfieldcolor( 0, warnloadcol_ ); drawlegend(); } total_ = fields_[1] = 20; } else { if (total_ == 20 ) { setfieldcolor( 0, procloadcol_ ); drawlegend(); } total_ = fields_[1] = alarmThreshold; } setUsed( fields_[0], total_ ); } xosview-1.20/hpux/loadmeter.h000066400000000000000000000010731317735352700162670ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 1997 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _LOADMETER_H_ #define _LOADMETER_H_ #include "fieldmeterdecay.h" class LoadMeter : public FieldMeterDecay { public: LoadMeter( XOSView *parent ); ~LoadMeter( void ); const char *name( void ) const { return "LoadMeter"; } void checkevent( void ); void checkResources( void ); protected: void getloadinfo( void ); unsigned long procloadcol_, warnloadcol_; private: int alarmThreshold; }; #endif xosview-1.20/hpux/memmeter.cc000066400000000000000000000033311317735352700162630ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #include "memmeter.h" #include "xosview.h" #include #include MemMeter::MemMeter( XOSView *parent ) : FieldMeterDecay( parent, 4, "MEM", "TEXT/USED/OTHER/FREE" ){ struct pst_static pststatic; pstat_getstatic( &pststatic, sizeof( struct pst_static ), 1, 0); total_ = pststatic.physical_memory; _pageSize = (int)pststatic.page_size; stats_ = new struct pst_status[pststatic.max_proc]; } void MemMeter::checkResources( void ){ FieldMeterDecay::checkResources(); setfieldcolor( 0, parent_->getResource( "memTextColor" ) ); setfieldcolor( 1, parent_->getResource( "memUsedColor" ) ); setfieldcolor( 2, parent_->getResource( "memOtherColor" ) ); setfieldcolor( 3, parent_->getResource( "memFreeColor" ) ); priority_ = atoi (parent_->getResource( "memPriority" ) ); dodecay_ = parent_->isResourceTrue( "memDecay" ); SetUsedFormat( parent_->getResource( "memUsedFormat" ) ); } MemMeter::~MemMeter( void ){ delete[] stats_; } void MemMeter::checkevent( void ){ static int pass = 0; pass = (pass + 1)%5; if ( pass != 0 ) return; getmeminfo(); drawfields(); } void MemMeter::getmeminfo( void ){ struct pst_dynamic stats; pstat_getdynamic(&stats, sizeof( pst_dynamic ), 1, 0); struct pst_vminfo vmstats; pstat_getvminfo(&vmstats, sizeof(vmstats), 1, 0); fields_[0] = stats.psd_rmtxt + stats.psd_arm; fields_[1] = stats.psd_rm - stats.psd_rmtxt; fields_[2] = total_ - fields_[0] - fields_[1] - stats.psd_free; fields_[3] = stats.psd_free; FieldMeterDecay::setUsed( (total_ - fields_[3]) * _pageSize , total_ * _pageSize); } xosview-1.20/hpux/memmeter.h000066400000000000000000000010571317735352700161300ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _MEMMETER_H_ #define _MEMMETER_H_ #include "fieldmeterdecay.h" #include class MemMeter : public FieldMeterDecay { public: MemMeter( XOSView *parent ); ~MemMeter( void ); const char *name( void ) const { return "MemMeter"; } void checkevent( void ); void checkResources(void); protected: struct pst_status *stats_; int _pageSize; void getmeminfo( void ); private: }; #endif xosview-1.20/hpux/pagemeter.cc000066400000000000000000000033271317735352700164260ustar00rootroot00000000000000// // Copyright (c) 1997 by Mike Romberg (romberg@fsl.noaa.gov) // // This file may be distributed under terms of the GPL // #include "pagemeter.h" #include "xosview.h" #include #include PageMeter::PageMeter( XOSView *parent, float max ) : FieldMeterDecay( parent, 3, "PAGE", "IN/OUT/IDLE" ){ for ( int i = 0 ; i < 2 ; i++ ) for ( int j = 0 ; j < 2 ; j++ ) pageinfo_[j][i] = 0; maxspeed_ = max; pageindex_ = 0; } PageMeter::~PageMeter( void ){ } void PageMeter::checkResources( void ){ FieldMeterDecay::checkResources(); setfieldcolor( 0, parent_->getResource( "pageInColor" ) ); setfieldcolor( 1, parent_->getResource( "pageOutColor" ) ); setfieldcolor( 2, parent_->getResource( "pageIdleColor" ) ); priority_ = atoi (parent_->getResource( "pagePriority" ) ); maxspeed_ *= priority_ / 10.0; dodecay_ = parent_->isResourceTrue( "pageDecay" ); SetUsedFormat( parent_->getResource( "pageUsedFormat" ) ); } void PageMeter::checkevent( void ){ getpageinfo(); drawfields(); } void PageMeter::getpageinfo( void ){ struct pst_vminfo vminfo; pstat_getvminfo(&vminfo, sizeof(vminfo), 1, 0); total_ = 0; pageinfo_[pageindex_][0] = vminfo.psv_spgin; pageinfo_[pageindex_][1] = vminfo.psv_spgout; int oldindex = (pageindex_+1)%2; for ( int i = 0; i < 2; i++ ) { if ( pageinfo_[oldindex][i] == 0 ) pageinfo_[oldindex][i] = pageinfo_[pageindex_][i]; fields_[i] = pageinfo_[pageindex_][i] - pageinfo_[oldindex][i]; total_ += fields_[i]; } if ( total_ > maxspeed_ ) fields_[2] = 0.0; else { fields_[2] = maxspeed_ - total_; total_ = maxspeed_; } setUsed (total_ - fields_[2], maxspeed_ ); pageindex_ = (pageindex_ + 1) % 2; } xosview-1.20/hpux/pagemeter.h000066400000000000000000000010601317735352700162600ustar00rootroot00000000000000// // Copyright (c) 1997 by Mike Romberg (romberg@fsl.noaa.gov) // // This file may be distributed under terms of the GPL // #ifndef _PAGEMETER_H_ #define _PAGEMETER_H_ #include "fieldmeterdecay.h" class PageMeter : public FieldMeterDecay { public: PageMeter( XOSView *parent, float max ); ~PageMeter( void ); const char *name( void ) const { return "PageMeter"; } void checkevent( void ); void checkResources( void ); protected: float pageinfo_[2][2]; int pageindex_; float maxspeed_; void getpageinfo( void ); private: }; #endif xosview-1.20/hpux/swapmeter.cc000066400000000000000000000025641317735352700164660ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #include "swapmeter.h" #include "xosview.h" #include #include static int MAX_SWAP_AREAS = 16; SwapMeter::SwapMeter( XOSView *parent ) : FieldMeterDecay( parent, 2, "SWAP", "USED/FREE" ){ } SwapMeter::~SwapMeter( void ){ } void SwapMeter::checkResources( void ){ FieldMeterDecay::checkResources(); setfieldcolor( 0, parent_->getResource( "swapUsedColor" ) ); setfieldcolor( 1, parent_->getResource( "swapFreeColor" ) ); priority_ = atoi(parent_->getResource( "swapPriority" ) ); dodecay_ = parent_->isResourceTrue( "swapDecay" ); SetUsedFormat( parent_->getResource( "swapUsedFormat" ) ); } void SwapMeter::checkevent( void ){ static int pass = 0; pass = (pass + 1)%5; if ( pass != 0 ) return; getswapinfo(); drawfields(); } void SwapMeter::getswapinfo( void ){ struct pst_swapinfo swapinfo; total_ = 0; fields_[1] = 0; for (int i = 0 ; i < MAX_SWAP_AREAS ; i++) { pstat_getswap(&swapinfo, sizeof(swapinfo), 1, i); if (swapinfo.pss_idx == (unsigned)i) { total_ += (swapinfo.pss_nblksenabled * 1024); fields_[1] += (swapinfo.pss_nfpgs * 4 * 1024); } } fields_[0] = total_ - fields_[1]; setUsed( fields_[0], total_ ); } xosview-1.20/hpux/swapmeter.h000066400000000000000000000007601317735352700163240ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _SWAPMETER_H_ #define _SWAPMETER_H_ #include "fieldmeterdecay.h" class SwapMeter : public FieldMeterDecay { public: SwapMeter( XOSView *parent ); ~SwapMeter( void ); const char *name( void ) const { return "SwapMeter"; } void checkevent( void ); void checkResources(void); protected: void getswapinfo( void ); private: }; #endif xosview-1.20/irix65/000077500000000000000000000000001317735352700143035ustar00rootroot00000000000000xosview-1.20/irix65/MeterMaker.cc000066400000000000000000000033771317735352700166600ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #include "MeterMaker.h" #include "xosview.h" #include "loadmeter.h" #include "cpumeter.h" #include "memmeter.h" #include "gfxmeter.h" #include "diskmeter.h" #include MeterMaker::MeterMaker(XOSView *xos) { _xos = xos; } void MeterMaker::makeMeters(void) { if (_xos->isResourceTrue("load")) push(new LoadMeter(_xos)); // Standard meters (usually added, but users could turn them off) if (_xos->isResourceTrue("cpu")) { bool any = false; const int cpuCount = CPUMeter::nCPUs(); if( strncmp( _xos->getResource("cpuFormat"), "single", 2) == 0 || strncmp( _xos->getResource("cpuFormat"), "both", 2) == 0 ) { push(new CPUMeter(_xos, -1)); any = true; } if( strncmp( _xos->getResource("cpuFormat"), "all", 2) == 0 || strncmp( _xos->getResource("cpuFormat"), "both", 2) == 0 ) { for (int i = 0 ; i < cpuCount ; i++) push(new CPUMeter(_xos, i)); any = true; } if( strncmp( _xos->getResource("cpuFormat"), "auto", 2) == 0 ) { push(new CPUMeter(_xos, -1)); if( cpuCount>1 ) for (int i = 0 ; i < cpuCount ; i++) push(new CPUMeter(_xos, i)); any = true; } if( !any ) { for (int i = 0 ; i < cpuCount ; i++) push(new CPUMeter(_xos, i)); } } if( _xos->isResourceTrue("gfx") && GfxMeter::nPipes() > 0 ) push(new GfxMeter( _xos, atoi( _xos->getResource( "gfxWarnThreshold" )))); if (_xos->isResourceTrue("mem")) push(new MemMeter(_xos)); } xosview-1.20/irix65/MeterMaker.h000066400000000000000000000004721317735352700165130ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #ifndef _MeterMaker_h #define _MeterMaker_h #include "pllist.h" class Meter; class XOSView; class MeterMaker : public PLList { public: MeterMaker(XOSView *xos); void makeMeters(void); private: XOSView *_xos; }; #endif xosview-1.20/irix65/cpumeter.cc000066400000000000000000000060741317735352700164450ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #include "cpumeter.h" #include "xosview.h" #include #include #include #include #include CPUMeter::CPUMeter(XOSView *parent, int cpuid) : FieldMeterGraph(parent, USED_CPU_STATES, toUpper(cpuStr(cpuid)), "USER/SYS/INTR/WAIT/IDLE") { for (int i = 0 ; i < 2 ; i++) for (int j = 0 ; j < USED_CPU_STATES ; j++) cputime_[i][j] = 0; if ((sinfosz = sysmp(MP_SASZ, MPSA_SINFO)) < 0) { std::cerr << "sysinfo scall interface not supported" << endl; parent_->done(1); return; } cpuid_ = cpuid; cpuindex_ = 0; } CPUMeter::~CPUMeter(void) { } void CPUMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("cpuUserColor")); setfieldcolor(1, parent_->getResource("cpuSystemColor")); setfieldcolor(2, parent_->getResource("cpuInterruptColor")); setfieldcolor(3, parent_->getResource("cpuWaitColor")); setfieldcolor(4, parent_->getResource("cpuFreeColor")); priority_ = atoi(parent_->getResource("cpuPriority")); dodecay_ = parent_->isResourceTrue("cpuDecay"); useGraph_ = parent_->isResourceTrue("cpuGraph"); SetUsedFormat(parent_->getResource("cpuUsedFormat")); } void CPUMeter::checkevent(void) { getcputime(); drawfields(); } void CPUMeter::getcputime(void) { total_ = 0; if(cpuid_==-1) sysmp(MP_SAGET, MPSA_SINFO, (char *) &tsp, sinfosz); else sysmp(MP_SAGET1, MPSA_SINFO, (char *) &tsp, sinfosz, cpuid_); tsp.cpu[CPU_WAIT] -= (tsp.wait[W_GFXF] + tsp.wait[W_GFXC]); cputime_[cpuindex_][0] = tsp.cpu[CPU_USER]; cputime_[cpuindex_][1] = tsp.cpu[CPU_KERNEL]; cputime_[cpuindex_][2] = tsp.cpu[CPU_INTR]; cputime_[cpuindex_][3] = tsp.cpu[CPU_WAIT]; cputime_[cpuindex_][4] = tsp.cpu[CPU_IDLE] + tsp.cpu[CPU_SXBRK]; int oldindex = (cpuindex_ + 1) % 2; for (int i = 0 ; i < USED_CPU_STATES ; i++) { fields_[i] = cputime_[cpuindex_][i] - cputime_[oldindex][i]; total_ += fields_[i]; } cpuindex_ = (cpuindex_ + 1) % 2; if (total_) setUsed(total_ - fields_[3] - fields_[4], total_); // wait doesn't count // as used } const char *CPUMeter::toUpper(const char *str) { static char buffer[256]; strncpy(buffer, str, 256); for (char *tmp = buffer ; *tmp != '\0' ; tmp++) *tmp = toupper(*tmp); return buffer; } const char *CPUMeter::cpuStr(int num) { static char buffer[32]; const int nCPU = nCPUs(); if( nCPU==1 || num==-1 ) { snprintf(buffer, 32, "CPU"); } else if( nCPU<=10 ) { snprintf(buffer, 32, "#%d", num); } else if ( nCPU<=100 ) { snprintf(buffer, 32, "#%02d", num); } else if ( nCPU<=1000 ) { snprintf(buffer, 32, "#%03d", num); } else { snprintf(buffer, 32, "%4.1d", num); } return buffer; } int CPUMeter::nCPUs() { return sysmp(MP_NPROCS); // FIXME: use NAPROCS + identify 'unused procs' } xosview-1.20/irix65/cpumeter.h000066400000000000000000000014501317735352700163000ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #ifndef _CPUMETER_H_ #define _CPUMETER_H_ #include "fieldmetergraph.h" #include #include #include #define USED_CPU_STATES (CPU_STATES-1) // SXBRK + IDLE merged class CPUMeter : public FieldMeterGraph { public: CPUMeter(XOSView *parent, const int cpuid = 0); ~CPUMeter(void); const char *name(void) const { return "CPUMeter"; } void checkevent(void); void checkResources(void); static int nCPUs(); static const char *cpuStr(int num); protected: time_t cputime_[2][USED_CPU_STATES]; int cpuindex_; void getcputime(void); const char *toUpper(const char *str); private: struct sysinfo tsp; int sinfosz; int cpuid_; }; #endif xosview-1.20/irix65/diskmeter.cc000066400000000000000000000024351317735352700166050ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #include "diskmeter.h" #include "xosview.h" #include "sarmeter.h" #include DiskMeter::DiskMeter( XOSView *parent, float max ) : FieldMeterGraph( parent, 3, "DISK", "READ/WRITE/IDLE") { maxspeed_ = max; getdiskinfo(); } DiskMeter::~DiskMeter( void ) { } void DiskMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("diskReadColor") ); setfieldcolor( 1, parent_->getResource("diskWriteColor") ); setfieldcolor( 2, parent_->getResource("diskIdleColor") ); priority_ = atoi (parent_->getResource( "diskPriority" ) ); dodecay_ = parent_->isResourceTrue("diskDecay" ); useGraph_ = parent_->isResourceTrue( "diskGraph" ); SetUsedFormat(parent_->getResource("diskUsedFormat")); } void DiskMeter::checkevent( void ) { getdiskinfo(); drawfields(); } void DiskMeter::getdiskinfo( void ) { SarMeter::DiskInfo *di = SarMeter::Instance()->getDiskInfo(); // new data total_ = maxspeed_; if (fields_[0] + fields_[1] > total_) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - (fields_[0] + fields_[1]); setUsed((fields_[0]+fields_[1]), total_); IntervalTimerStart(); } xosview-1.20/irix65/diskmeter.h000066400000000000000000000007521317735352700164470ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #ifndef _DISKMETER_H_ #define _DISKMETER_H_ #include "fieldmetergraph.h" class DiskMeter : public FieldMeterGraph { public: DiskMeter( XOSView *parent, float max ); ~DiskMeter( void ); const char *name( void ) const { return "DiskMeter"; } void checkevent( void ); void checkResources( void ); protected: void getdiskinfo( void ); private: float maxspeed_; }; #endif xosview-1.20/irix65/gfxmeter.cc000066400000000000000000000065221317735352700164400ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #include "gfxmeter.h" #include "xosview.h" #include #include #include #include using namespace std; // GfxMeter display swapbuffers per second. max is base rate for one gfx pipe. GfxMeter::GfxMeter(XOSView *parent, int max) : FieldMeterGraph(parent, 2, "GFX","SWAPBUF/S", 1, 1, 0 ) { lastalarmstate = -1; total_ = 0; _nPipes = nPipes(); total_ = _nPipes * max; if ( total_==0 ) { parent_->done(1); return; } } GfxMeter::~GfxMeter(void) { } int GfxMeter::nPipes(void) { int _nPipes = 0; setinvent(); for( inventory_t *inv = getinvent(); inv != NULL; inv = getinvent() ) { if ( inv->inv_class==INV_GRAPHICS ) { _nPipes++; } } return _nPipes; } void GfxMeter::checkResources(void) { FieldMeterGraph::checkResources(); swapgfxcol_ = parent_->allocColor(parent_->getResource( "gfxSwapColor" )); warngfxcol_ = parent_->allocColor(parent_->getResource( "gfxWarnColor" )); critgfxcol_ = parent_->allocColor(parent_->getResource( "gfxCritColor" )); setfieldcolor(0, parent_->getResource( "gfxSwapColor" )); setfieldcolor(1, parent_->getResource("gfxIdleColor")); priority_ = atoi (parent_->getResource("gfxPriority")); useGraph_ = parent_->isResourceTrue("gfxGraph"); dodecay_ = parent_->isResourceTrue( "gfxDecay" ); SetUsedFormat(parent_->getResource("gfxUsedFormat")); warnThreshold = atoi (parent_->getResource("gfxWarnThreshold")) * _nPipes; critThreshold = atoi (parent_->getResource("gfxCritThreshold")) * _nPipes; if (dodecay_){ // Warning: Since the gfxmeter changes scale occasionally, old // decay values need to be rescaled. However, if they are rescaled, // they could go off the edge of the screen. Thus, for now, to // prevent this whole problem, the gfx meter can not be a decay // meter. The gfx is a decaying average kind of thing anyway, // so having a decaying gfx average is redundant. std::cerr << "Warning: The gfxmeter can not be configured as a decay\n" << " meter. See the source code (" <<__FILE__<< ") for further\n" << " details.\n"; dodecay_ = 0; } } void GfxMeter::checkevent(void) { getgfxinfo(); drawfields(); } void GfxMeter::getgfxinfo(void) { SarMeter::GfxInfo *gi = SarMeter::Instance()->getGfxInfo(); fields_[0] = (float)gi->swapBuf; if ( fields_[0] < warnThreshold ) alarmstate = 0; else if ( fields_[0] >= critThreshold ) alarmstate = 2; else alarmstate = 1; if ( alarmstate != lastalarmstate ) { if ( alarmstate == 0 ) setfieldcolor( 0, swapgfxcol_ ); else if ( alarmstate == 1 ) setfieldcolor( 0, warngfxcol_ ); else setfieldcolor( 0, critgfxcol_ ); drawlegend(); lastalarmstate = alarmstate; } if ( fields_[0]*5.0total_ ) total_ = fields_[0]*5.0; if ( total_ < 1.0) total_ = 1.0; fields_[1] = (float) (total_ - fields_[0]); setUsed(fields_[0], (float) 1.0); } xosview-1.20/irix65/gfxmeter.h000066400000000000000000000012061317735352700162740ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #ifndef _GFXMETER_H_ #define _GFXMETER_H_ #include "sarmeter.h" #include class GfxMeter : public FieldMeterGraph { public: GfxMeter(XOSView *parent, int max); ~GfxMeter(void); const char *name(void) const { return "GfxMeter"; } void checkevent(void); void checkResources(void); static int nPipes( void ); protected: void getgfxinfo(void); unsigned long swapgfxcol_, warngfxcol_, critgfxcol_; private: int warnThreshold, critThreshold, alarmstate, lastalarmstate; int _nPipes; }; #endif xosview-1.20/irix65/loadmeter.cc000066400000000000000000000065521317735352700165760ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // // Most of this code was written by Werner Fink . // Only small changes were made on my part (M.R.) // Small changes for Irix 6.5 port Stefan Eilemann // #include "loadmeter.h" #include "xosview.h" #include #include #include #ifndef FSCALE #define FSCALE (1 << 8) #endif using namespace std; LoadMeter::LoadMeter(XOSView *parent) : FieldMeterGraph( parent, 2, "LOAD", "PROCS/MIN", 1, 1, 0 ) { lastalarmstate = -1; total_ = 2.0; if (gethostname (hostname, 255) != 0) { perror ("gethostname"); parent_->done(1); return; } } LoadMeter::~LoadMeter(void) { } void LoadMeter::checkResources(void) { FieldMeterGraph::checkResources(); procloadcol_ = parent_->allocColor(parent_->getResource( "loadProcColor" )); warnloadcol_ = parent_->allocColor(parent_->getResource( "loadWarnColor" )); critloadcol_ = parent_->allocColor(parent_->getResource( "loadCritColor" )); setfieldcolor(0, parent_->getResource( "loadProcColor" )); setfieldcolor(1, parent_->getResource("loadIdleColor")); priority_ = atoi (parent_->getResource("loadPriority")); useGraph_ = parent_->isResourceTrue("loadGraph"); dodecay_ = parent_->isResourceTrue( "loadDecay" ); SetUsedFormat(parent_->getResource("loadUsedFormat")); warnThreshold = atoi (parent_->getResource("loadWarnThreshold")); critThreshold = atoi (parent_->getResource("loadCritThreshold")); if (dodecay_){ // Warning: Since the loadmeter changes scale occasionally, old // decay values need to be rescaled. However, if they are rescaled, // they could go off the edge of the screen. Thus, for now, to // prevent this whole problem, the load meter can not be a decay // meter. The load is a decaying average kind of thing anyway, // so having a decaying load average is redundant. std::cerr << "Warning: The loadmeter can not be configured as a decay\n" << " meter. See the source code (" <<__FILE__<< ") for further\n" << " details.\n"; dodecay_ = 0; } } void LoadMeter::checkevent(void) { getloadinfo(); drawfields(); } void LoadMeter::getloadinfo(void) { if (rstat (hostname, &res) != 0) { std::cerr << hostname <= critThreshold ) alarmstate = 2; else alarmstate = 1; if ( alarmstate != lastalarmstate ) { if ( alarmstate == 0 ) setfieldcolor( 0, procloadcol_ ); else if ( alarmstate == 1 ) setfieldcolor( 0, warnloadcol_ ); else setfieldcolor( 0, critloadcol_ ); drawlegend(); lastalarmstate = alarmstate; } if ( fields_[0]*5.0total_ ) total_ = fields_[0]*5.0; if ( total_ < 1.0) total_ = 1.0; fields_[1] = (float) (total_ - fields_[0]); setUsed(fields_[0], (float) 1.0); } xosview-1.20/irix65/loadmeter.h000066400000000000000000000011631317735352700164310ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #ifndef _LOADMETER_H_ #define _LOADMETER_H_ #include "fieldmetergraph.h" #include class LoadMeter : public FieldMeterGraph { public: LoadMeter(XOSView *parent); ~LoadMeter(void); const char *name(void) const { return "LoadMeter"; } void checkevent(void); void checkResources(void); protected: void getloadinfo(void); unsigned long procloadcol_, warnloadcol_, critloadcol_; private: int warnThreshold, critThreshold, alarmstate, lastalarmstate; char hostname[256]; struct statstime res; }; #endif xosview-1.20/irix65/memmeter.cc000066400000000000000000000034761317735352700164370ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #include "memmeter.h" #include "xosview.h" #include #include #include MemMeter::MemMeter(XOSView *parent) : FieldMeterGraph(parent, 4, "MEM","KERNEL/FS/USER/FREE") { inventory_t *inv; _pageSize = getpagesize(); minfosz = sysmp(MP_SASZ, MPSA_RMINFO); total_ = 0; setinvent(); for( inv = getinvent(); inv != NULL; inv = getinvent() ) { if ( inv->inv_class==INV_MEMORY && inv->inv_type == INV_MAIN_MB ) { total_ = inv->inv_state*1024/_pageSize*1024; break; } } if ( total_==0 ) { parent_->done(1); return; } } void MemMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("memKernelColor")); setfieldcolor(1, parent_->getResource("memCacheColor")); setfieldcolor(2, parent_->getResource("memUsedColor")); setfieldcolor(3, parent_->getResource("memFreeColor")); priority_ = atoi (parent_->getResource("memPriority")); dodecay_ = parent_->isResourceTrue("memDecay"); useGraph_ = parent_->isResourceTrue("memGraph"); SetUsedFormat(parent_->getResource("memUsedFormat")); } MemMeter::~MemMeter(void) { } void MemMeter::checkevent(void) { getmeminfo(); drawfields(); } void MemMeter::getmeminfo(void) { sysmp(MP_SAGET, MPSA_RMINFO, (char *) &mp, minfosz); fields_[0] = total_ - (mp.availrmem + mp.bufmem); fields_[1] = mp.bufmem + mp.dchunkpages + mp.dpages + mp.chunkpages - mp.dchunkpages; fields_[2] = mp.availrmem - (mp.freemem + mp.chunkpages + mp.dpages); fields_[3] = mp.freemem; FieldMeterDecay::setUsed( (fields_[0]+fields_[1]+fields_[2]) * _pageSize, total_ * _pageSize); } xosview-1.20/irix65/memmeter.h000066400000000000000000000011621317735352700162670ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #ifndef _MEMMETER_H_ #define _MEMMETER_H_ #include "fieldmetergraph.h" #include #include #include /* for SAGET and MINFO structures */ class MemMeter : public FieldMeterGraph { public: MemMeter(XOSView *parent); ~MemMeter(void); const char *name(void) const { return "MemMeter"; } void checkevent( void ); void checkResources(void); protected: // struct pst_status *stats_; int _pageSize; void getmeminfo( void ); private: struct rminfo mp; int minfosz; }; #endif xosview-1.20/irix65/sarmeter.cc000066400000000000000000000114141317735352700164350ustar00rootroot00000000000000// // Initial port performed by Stefan Eilemann (eilemann@gmail.com) // #include "sarmeter.h" #include SarMeter *SarMeter::_instance = NULL; SarMeter *SarMeter::Instance() { if( _instance == NULL ) _instance = new SarMeter(); return _instance; } SarMeter::SarMeter( void ) : _bufSize(0) { _input = setupSadc(); _gi.last.gswapbuf = 0; _gi.info.swapBuf = 0; for( int i=0; i 100 ) { // look for 'S' (starting of Sarmagic) char *ptr = (char *)memchr( _buf, 'S', _bufSize ); // not found -- discard this buffer if( ptr == NULL ) { _bufSize = 0; return; } // not enough data read if( (ptr+100) > (_buf+_bufSize) ) return; // check for SarmagicGFX if( memcmp( ptr, "SarmagicGFX", 11 ) == 0 ) { forwardBufferTo( ptr ); // data is not complete in buffer if( _bufSize < 24 + sizeof( gfxinfo )) return; // retrieve gfxinfo structure ptr = _buf + 24; memcpy( &_gi.current, ptr, sizeof( gfxinfo )); ptr += sizeof( gfxinfo ); forwardBufferTo( ptr ); newGfxInfo(); } // check for SarmagicNEODISK else if( memcmp( ptr, "SarmagicNEODISK", 15 ) == 0 ) { forwardBufferTo( ptr ); ptr = _buf + 20; // number of records [devices] int num; memcpy( &num, ptr, 4 ); ptr += 4; if( num > MAX_DISKS ) num = MAX_DISKS; // data is not complete in buffer if( _bufSize < 24 + num*sizeof( diskinfo )) return; _di.info.nDevices = num; // read disk info for( int i=0; i #include #include // some structs typedef struct { unsigned int recsize; unsigned int numrec; } header; typedef struct { char name[12]; char pad1[68]; struct iotime stat; char pad2[4]; } diskinfo; #define MAX_DISKS 16 #define BUFSIZE 0x2000 // common function for all sar based graphs class SarMeter { public: static SarMeter *Instance(); struct GfxInfo { unsigned int swapBuf; }; struct DiskInfo { unsigned int nDevices; unsigned int read[MAX_DISKS]; unsigned int write[MAX_DISKS]; }; GfxInfo *getGfxInfo( void ) { checkSadc(); return &_gi.info; } DiskInfo *getDiskInfo( void ) { checkSadc(); return &_di.info; } private: SarMeter(); ~SarMeter(void) {} int setupSadc( void ); void checkSadc( void ); bool readLine( void ); void parseBuffer( void ); void forwardBufferTo( char *ptr ); void newGfxInfo( void ); void newDiskInfo( void ); static SarMeter *_instance; int _input; off_t _bufSize; char _buf[BUFSIZE]; struct { gfxinfo current; gfxinfo last; GfxInfo info; } _gi; struct { diskinfo current[MAX_DISKS]; diskinfo last[MAX_DISKS]; DiskInfo info; } _di; }; #endif xosview-1.20/linux/000077500000000000000000000000001317735352700143145ustar00rootroot00000000000000xosview-1.20/linux/MeterMaker.cc000066400000000000000000000174751317735352700166750ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "MeterMaker.h" #include "xosview.h" #include "loadmeter.h" #include "cpumeter.h" #include "memmeter.h" #include "diskmeter.h" #include "raidmeter.h" #include "swapmeter.h" #include "pagemeter.h" #include "wirelessmeter.h" #include "netmeter.h" #include "nfsmeter.h" #include "serialmeter.h" #include "intmeter.h" #include "intratemeter.h" #include "btrymeter.h" #if defined(__i386__) || defined(__x86_64__) #include "coretemp.h" #endif #include "lmstemp.h" #include "acpitemp.h" #include #include #include #include #include #include #include MeterMaker::MeterMaker(XOSView *xos){ _xos = xos; } void MeterMaker::makeMeters(void){ // check for the load meter if (_xos->isResourceTrue("load")) push(new LoadMeter(_xos)); // Standard meters (usually added, but users could turn them off) if (_xos->isResourceTrue("cpu")){ bool single, both, all; unsigned int cpuCount = CPUMeter::countCPUs(); single = (strncmp(_xos->getResource("cpuFormat"), "single", 2) == 0); both = (strncmp(_xos->getResource("cpuFormat"), "both", 2) == 0); all = (strncmp(_xos->getResource("cpuFormat"), "all", 2) == 0); if (strncmp(_xos->getResource("cpuFormat"), "auto", 2) == 0) { if (cpuCount == 1 || cpuCount > 4) { single = true; } else { all = true; } } if (single || both) push(new CPUMeter(_xos, CPUMeter::cpuStr(0))); if (all || both) { for (unsigned int i = 1; i <= cpuCount; i++) push(new CPUMeter(_xos, CPUMeter::cpuStr(i))); } } if (_xos->isResourceTrue("mem")) push(new MemMeter(_xos)); if (_xos->isResourceTrue("disk")) push(new DiskMeter(_xos, atof(_xos->getResource("diskBandwidth")))); // check for the RAID meter if (_xos->isResourceTrue("RAID")){ int RAIDCount = atoi(_xos->getResource("RAIDdevicecount")); for (int i = 0 ; i < RAIDCount ; i++) push(new RAIDMeter(_xos, i)); } if (_xos->isResourceTrue("swap")) push(new SwapMeter(_xos)); if (_xos->isResourceTrue("page")) push(new PageMeter(_xos, atof(_xos->getResource("pageBandwidth")))); // check for the wireless meter if ( _xos->isResourceTrue("wireless") ) { std::ifstream stats( WLFILENAME ); if (!stats) std::cerr << "Wireless Meter needs Linux Wireless Extensions or cfg80211-" << "WEXT compatibility to work." << std::endl; else { int count = WirelessMeter::countdevices(); for (int i = 0; i < count; i++) push(new WirelessMeter(_xos, i, ( count == 1 ? "WLAN" : WirelessMeter::wirelessStr(i)))); } } // check for the net meter if (_xos->isResourceTrue("net")) push(new NetMeter(_xos, atof(_xos->getResource("netBandwidth")))); // check for the NFS mesters if (_xos->isResourceTrue("NFSDStats")){ push(new NFSDStats(_xos)); } if (_xos->isResourceTrue("NFSStats")){ push(new NFSStats(_xos)); } // check for the serial meters. #if defined(__aarch64__) || defined (__arm__) || defined(__mc68000__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__sparc__) || defined(__s390__) || defined(__s390x__) /* these architectures have no ioperm() */ #else for (int i = 0 ; i < SerialMeter::numDevices() ; i++) { bool ok ; unsigned long val ; const char *res = SerialMeter::getResourceName((SerialMeter::Device)i); if ( !(ok = _xos->isResourceTrue(res)) ) { std::istringstream is(_xos->getResource(res)); is >> std::setbase(0) >> val; if (!is) ok = false; else ok = val & 0xFFFF; } if ( ok ) push(new SerialMeter(_xos, (SerialMeter::Device)i)); } #endif // check for the interrupt meter if (_xos->isResourceTrue("interrupts")) { int cpuCount = IntMeter::countCPUs(); cpuCount = cpuCount == 0 ? 1 : cpuCount; if (_xos->isResourceTrue("intSeparate")) { for (int i = 0 ; i < cpuCount ; i++) push(new IntMeter(_xos, i)); } else push(new IntMeter(_xos, cpuCount-1)); } // check for irqrate meter if (_xos->isResourceTrue("irqrate")) push(new IrqRateMeter(_xos)); // check for the battery meter if (_xos->isResourceTrue("battery") && BtryMeter::has_source()) push(new BtryMeter(_xos)); #if defined(__i386__) || defined(__x86_64__) // Check for the CPU temperature meter if (_xos->isResourceTrue("coretemp")) { char caption[32], name[8] = "CPU"; unsigned int coreCount, pkgCount, cpu, pkg = 0; snprintf(caption, 32, "ACT(\260C)/HIGH/%s", _xos->getResourceOrUseDefault( "coretempHighest", "100" ) ); const char *displayType = _xos->getResourceOrUseDefault( "coretempDisplayType", "separate" ); pkgCount = CoreTemp::countCpus(); if ( strncmp(displayType, "separate", 1) == 0 ) { for (pkg = 0; pkg < pkgCount; pkg++) { coreCount = CoreTemp::countCores(pkg); for (cpu = 0; cpu < coreCount; cpu++) { if (pkgCount > 1) { if (cpu == 0) // give title only to first core of each physical cpu snprintf(name, 8, "CPU%d", pkg); else name[0] = '\0'; } else { if (coreCount > 1) snprintf(name, 8, "CPU%d", cpu); } push(new CoreTemp(_xos, name, caption, pkg, cpu)); } } } else if ( strncmp(displayType, "average", 1) == 0 ) { do { if (pkgCount > 1) snprintf(name, 8, "CPU%d", pkg); push(new CoreTemp(_xos, name, caption, pkg, -1)); } while (++pkg < pkgCount); } else if ( strncmp(displayType, "maximum", 1) == 0 ) { do { if (pkgCount > 1) snprintf(name, 8, "CPU%d", pkg); push(new CoreTemp(_xos, name, caption, pkg, -2)); } while (++pkg < pkgCount); } else { std::cerr << "Unknown value of coretempDisplayType: " << displayType << std::endl; std::cerr << "Supported types are: separate, average and maximum." << std::endl; _xos->done(1); } } #endif // check for the LmsTemp meter if (_xos->isResourceTrue("lmstemp")){ char caption[16], s[16]; const char *tempfile, *highfile, *lowfile, *name, *label; snprintf( caption, 16, "ACT/HIGH/%s", _xos->getResourceOrUseDefault("lmstempHighest", "100") ); for (int i = 1 ; ; i++) { snprintf(s, 16, "lmstemp%d", i); tempfile = _xos->getResourceOrUseDefault(s, NULL); if (!tempfile || !*tempfile) break; snprintf(s, 16, "lmshigh%d", i); highfile = _xos->getResourceOrUseDefault(s, NULL); snprintf(s, 16, "lmslow%d", i); lowfile = _xos->getResourceOrUseDefault(s, NULL); snprintf(s, 16, "lmsname%d", i); name = _xos->getResourceOrUseDefault(s, NULL); snprintf(s, 16, "lmstempLabel%d", i); label = _xos->getResourceOrUseDefault(s, "TMP"); push(new LmsTemp(_xos, name, tempfile, highfile, lowfile, label, caption, i)); } } // check for the ACPITemp meter if (_xos->isResourceTrue("acpitemp")) { char caption[32]; snprintf(caption, 32, "ACT(\260C)/HIGH/%s", _xos->getResourceOrUseDefault("acpitempHighest", "100")); for (int i = 1 ; ; i++) { char s[16]; snprintf(s, 16, "acpitemp%d", i); const char *tempfile = _xos->getResourceOrUseDefault(s, NULL); if (!tempfile || !*tempfile) break; snprintf(s, 16, "acpihigh%d", i); const char *highfile = _xos->getResourceOrUseDefault(s, NULL); if (!highfile || !*highfile) break; snprintf(s, 16, "acpitempLabel%d", i); const char *lab = _xos->getResourceOrUseDefault(s, "TMP"); push(new ACPITemp(_xos, tempfile, highfile, lab, caption)); } } } xosview-1.20/linux/MeterMaker.h000066400000000000000000000006121317735352700165200ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _MeterMaker_h #define _MeterMaker_h #include "pllist.h" #include "meter.h" #include "xosview.h" class MeterMaker : public PLList { public: MeterMaker(XOSView *xos); void makeMeters(void); private: XOSView *_xos; }; #endif xosview-1.20/linux/acpitemp.cc000066400000000000000000000114371317735352700164330ustar00rootroot00000000000000// // Copyright (c) 2009 by Tomi Tapper // // File based on lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // // #include "acpitemp.h" #include #include #include #include #include #include #include #include #include static const char PROC_ACPI_TZ[] = "/proc/acpi/thermal_zone"; static const char SYS_ACPI_TZ[] = "/sys/devices/virtual/thermal"; ACPITemp::ACPITemp( XOSView *parent, const char *tempfile, const char *highfile, const char *label, const char *caption ) : FieldMeter( parent, 3, label, caption, 1, 1, 0 ) { metric_ = true; if (!checkacpi(tempfile, highfile)) { std::cerr << "Can not find file : "; if (tempfile[0] == '/' && highfile[0] == '/') std::cerr << tempfile << " or " << highfile; else if (tempfile[0] == '/') std::cerr << tempfile << ", or " << highfile << " under " << PROC_ACPI_TZ << " or " << SYS_ACPI_TZ; else if (highfile[0] == '/') std::cerr << tempfile << " under " << PROC_ACPI_TZ << " or " << SYS_ACPI_TZ << ", or " << highfile; else std::cerr << tempfile << " or " << highfile << " under " << PROC_ACPI_TZ << " or " << SYS_ACPI_TZ; std::cerr << "." << std::endl; parent_->done(1); } _high = 0; } ACPITemp::~ACPITemp( void ) { } int ACPITemp::checkacpi( const char *tempfile, const char *highfile ) { struct stat buf; char temp[PATH_SIZE], high[PATH_SIZE]; bool temp_found = false, high_found = false; if (tempfile[0] == '/') { if ( stat(tempfile, &buf) == 0 && S_ISREG(buf.st_mode) ) temp_found = true; else return false; } if (highfile[0] == '/') { if ( stat(highfile, &buf) == 0 && S_ISREG(buf.st_mode) ) high_found = true; else return false; } if (temp_found && high_found) { strncpy(_tempfile, tempfile, PATH_SIZE); strncpy(_highfile, highfile, PATH_SIZE); return true; } snprintf(temp, PATH_SIZE, "%s/%s", SYS_ACPI_TZ, tempfile); snprintf(high, PATH_SIZE, "%s/%s", SYS_ACPI_TZ, highfile); if ( (stat(temp, &buf) == 0 && S_ISREG(buf.st_mode)) && (stat(high, &buf) == 0 && S_ISREG(buf.st_mode)) ) { strncpy(_tempfile, temp, PATH_SIZE); strncpy(_highfile, high, PATH_SIZE); _usesysfs = true; return true; } _usesysfs = false; snprintf(temp, PATH_SIZE, "%s/%s", PROC_ACPI_TZ, tempfile); snprintf(high, PATH_SIZE, "%s/%s", PROC_ACPI_TZ, highfile); if ( (stat(temp, &buf) == 0 && S_ISREG(buf.st_mode)) && (stat(high, &buf) == 0 && S_ISREG(buf.st_mode)) ) { strncpy(_tempfile, temp, PATH_SIZE); strncpy(_highfile, high, PATH_SIZE); return true; } return false; } void ACPITemp::checkResources( void ) { FieldMeter::checkResources(); _actcolor = parent_->allocColor( parent_->getResource( "acpitempActColor" ) ); _highcolor = parent_->allocColor( parent_->getResource( "acpitempHighColor" ) ); setfieldcolor( 0, _actcolor ); setfieldcolor( 1, parent_->getResource( "acpitempIdleColor" ) ); setfieldcolor( 2, _highcolor ); total_ = atoi( parent_->getResourceOrUseDefault( "acpitempHighest", "100" ) ); priority_ = atoi( parent_->getResource( "acpitempPriority" ) ); SetUsedFormat( parent_->getResource( "acpitempUsedFormat" ) ); } void ACPITemp::checkevent( void ) { getacpitemp(); drawfields(); } void ACPITemp::getacpitemp( void ) { std::ifstream temp_file(_tempfile); std::ifstream high_file(_highfile); if (!temp_file) { std::cerr << "Can not open file : " << _tempfile << std::endl; parent_->done(1); return; } if (!high_file) { std::cerr << "Can not open file : " << _highfile << std::endl; parent_->done(1); return; } float high; std::string dummy; bool do_legend = false; if (_usesysfs) { high_file >> high; high /= 1000.0; temp_file >> fields_[0]; fields_[0] /= 1000.0; } else { high_file >> dummy >> dummy >> high; temp_file >> dummy >> fields_[0]; } if (high > total_ || high != _high) { char l[16]; if (high > total_) total_ = 10 * (int)((high * 1.25) / 10); _high = high; snprintf(l, 16, "ACT(\260C)/%d/%d", (int)high, (int)total_); legend(l); do_legend = true; } setUsed( fields_[0], total_ ); if (fields_[0] < 0) fields_[0] = 0.0; fields_[1] = high - fields_[0]; if (fields_[1] < 0) { // alarm: T > high fields_[1] = 0; if (colors_[0] != _highcolor) { setfieldcolor( 0, _highcolor ); do_legend = true; } } else { if (colors_[0] != _actcolor) { setfieldcolor( 0, _actcolor ); do_legend = true; } } fields_[2] = total_ - fields_[1] - fields_[0]; if (fields_[2] < 0) fields_[2] = 0; if (do_legend) drawlegend(); } xosview-1.20/linux/acpitemp.h000066400000000000000000000015751317735352700162770ustar00rootroot00000000000000// // Copyright (c) 2009 by Tomi Tapper // // File based on lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // // #ifndef _ACPITEMP_H_ #define _ACPITEMP_H_ #include "fieldmeter.h" #include "xosview.h" #define PATH_SIZE 128 class ACPITemp : public FieldMeter { public: ACPITemp( XOSView *parent, const char *tempfile, const char *highfile, const char *label, const char * caption); ~ACPITemp( void ); const char *name( void ) const { return "ACPITemp"; } void checkevent( void ); void checkResources( void ); protected: void getacpitemp( void ); int checkacpi(const char* tempfile, const char* highfile); private: char _tempfile[PATH_SIZE]; char _highfile[PATH_SIZE]; int _high; bool _usesysfs; unsigned long _actcolor, _highcolor; }; #endif xosview-1.20/linux/btrymeter.cc000066400000000000000000000430101317735352700166360ustar00rootroot00000000000000// // Copyright (c) 1997, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "btrymeter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static const char APMFILENAME[] = "/proc/apm"; static const char ACPIBATTERYDIR[] = "/proc/acpi/battery"; static const char SYSPOWERDIR[] = "/sys/class/power_supply"; BtryMeter::BtryMeter( XOSView *parent ) : FieldMeter( parent, 2, "BTRY", "CHRG/USED", 1, 1, 0 ){ // find out ONCE whether to use ACPI, APM or sysfs use_acpi = use_apm = use_syspower = false; if ( has_apm() ) { use_apm=true; use_acpi=false; use_syspower=false; } if ( has_acpi() ) { use_acpi=true; use_apm=false; use_syspower=false; } if ( has_syspower() ) { use_acpi=false; use_apm=false; use_syspower=true; } old_apm_battery_state = apm_battery_state = 0xFF; old_acpi_charge_state = acpi_charge_state = -2; } BtryMeter::~BtryMeter( void ){ } // determine if any usable source of battery information bool BtryMeter::has_source( void ){ return has_apm() || has_acpi() || has_syspower(); } // determine if /proc/apm exists and is readable bool BtryMeter::has_apm( void ){ struct stat stbuf; int fd; if ( stat(APMFILENAME, &stbuf) != 0 ) { XOSDEBUG("APM: stat failed: %d - not APM ?\n",errno); return false; } if ( S_ISREG(stbuf.st_mode) ) { XOSDEBUG("apm: %s exists and is a file\n",APMFILENAME); } else { XOSDEBUG("no APM file\n"); return false; } fd=open(APMFILENAME,O_RDONLY); if ( fd < 0 ) { XOSDEBUG("open failed on %s: with errno=%d\n",APMFILENAME,errno); return false; } else close(fd); // good enough ... // all our tests succeeded - apm seems usable return true; } // determine if /proc/acpi/battery exists and is a DIR // (XXX: too lazy - no tests for actual readability is done) bool BtryMeter::has_acpi( void ){ struct stat stbuf; if ( stat(ACPIBATTERYDIR, &stbuf) != 0 ) { XOSDEBUG("has_acpi(): stat failed: %d\n",errno); return false; } if ( S_ISDIR(stbuf.st_mode) ) { XOSDEBUG("%s exists and is a DIR.\n", ACPIBATTERYDIR); } else { XOSDEBUG("no ACPI dir\n"); return false; } // declare ACPI as usable return true; } /* * Look for something resembling a battery in /sys/class/power_supply */ bool BtryMeter::has_syspower( void ){ bool found; DIR *dir; struct dirent *dp; struct stat buf; char dirname[80], f[80]; std::ifstream type; std::string t; dir = opendir(SYSPOWERDIR); if (dir == NULL) return false; found = false; while (!found && (dp = readdir(dir))) { if (!strncmp(dp->d_name, ".", 1)) continue; if (!strncmp(dp->d_name, "..", 2)) continue; snprintf(dirname, 80, "%s/%s", SYSPOWERDIR, dp->d_name); if (stat(dirname, &buf) == 0 && S_ISDIR(buf.st_mode)) { snprintf(f, 80, "%s/%s", dirname, "/type"); type.open(f); if (type.good()) { type >> t; if (strncmp(t.c_str(), "Battery", 7) == 0) { found = true; break; } } type.close(); } } if (closedir(dir) != 0) abort(); return found; } void BtryMeter::checkResources( void ){ FieldMeter::checkResources(); setfieldcolor( 0, parent_->getResource( "batteryLeftColor" ) ); setfieldcolor( 1, parent_->getResource( "batteryUsedColor" ) ); priority_ = atoi (parent_->getResource( "batteryPriority" ) ); SetUsedFormat(parent_->getResource( "batteryUsedFormat" ) ); } void BtryMeter::handle_apm_state( void ){ switch ( apm_battery_state ) { case 0: /* high (e.g. over 25% on my box) */ XOSDEBUG("battery_status HIGH\n"); setfieldcolor( 0, parent_->getResource("batteryLeftColor")); legend("High AVAIL/USED"); break; case 1: /* low ( e.g. under 25% on my box ) */ XOSDEBUG("battery_status LOW\n"); setfieldcolor( 0, parent_->getResource("batteryLowColor")); legend("LOW avail/used"); break; case 2: /* critical ( less than 5% on my box ) */ XOSDEBUG("battery_status CRITICAL\n"); setfieldcolor( 0, parent_->getResource("batteryCritColor")); legend( "Crit LOW/Used"); break; case 3: /* Charging */ XOSDEBUG("battery_status CHARGING\n"); setfieldcolor( 0, parent_->getResource("batteryChargeColor")); legend( "AC/Charging"); break; case 4: /* selected batt not present */ /* no idea how this state ever could happen with APM */ XOSDEBUG("battery_status not present\n"); setfieldcolor( 0, parent_->getResource("batteryNoneColor")); legend( "Not Present/N.A."); break; case 255: /* unknown - do nothing - maybe not APM */ // on my system this state comes if you pull both batteries // ( while on AC of course :-)) ) XOSDEBUG("apm battery_state not known\n"); setfieldcolor( 0, parent_->getResource("batteryNoneColor")); legend( "Unknown/N.A."); break; } } void BtryMeter::handle_acpi_state( void ){ switch ( acpi_charge_state ) { case 0: // charged XOSDEBUG("battery_status CHARGED\n"); setfieldcolor( 0, parent_->getResource("batteryFullColor")); legend( "CHRG/FULL"); break; case -1: // discharging XOSDEBUG("battery_status DISCHARGING\n"); setfieldcolor( 0, parent_->getResource("batteryLeftColor")); legend( "CHRG/USED"); break; case -2: // discharging - below alarm XOSDEBUG("battery_status ALARM DISCHARGING\n"); setfieldcolor( 0, parent_->getResource("batteryCritColor")); legend( "CHRG/USED"); break; case -3: // not present XOSDEBUG("battery_status NOT PRESENT\n"); setfieldcolor( 0, parent_->getResource("batteryNoneColor")); legend( "NONE/NONE"); break; case 1: // charging XOSDEBUG("battery_status CHARGING\n"); setfieldcolor( 0, parent_->getResource("batteryChargeColor")); legend( "CHRG/AC"); break; } } /* * All redraws come from this function (not children) */ void BtryMeter::checkevent( void ){ getpwrinfo(); if ( old_apm_battery_state != apm_battery_state ) { /* APM only changes if we have APM */ handle_apm_state(); drawlegend(); drawfields(1); return; } if ( old_acpi_charge_state != acpi_charge_state ) { handle_acpi_state(); drawlegend(); drawfields(1); return; } drawfields(); } void BtryMeter::getpwrinfo( void ){ if ( use_acpi || use_syspower ) { getacpi_or_sys_info(); return; } if ( use_apm ) { getapminfo(); return; } // We can hit this spot in any of two cases: // - We have an ACPI system and the battery is removed // - We have neither ACPI nor APM in the system // We report an empty battery (i.e., we are running off AC power) instead of // original behavior of just exiting the program. // (Refer to Debian bug report #281565) total_ = 100; fields_[0] = 0; fields_[1] = 100; setUsed(fields_[0], total_); } bool BtryMeter::getapminfo( void ){ std::ifstream loadinfo( APMFILENAME ); /* just a tiny note here about APM states: See: arch/i386/kernel/apm.c apm_get_info() Arguments, with symbols from linux/apm_bios.h. Information is from the Get Power Status (0x0a) call unless otherwise noted. 0) Linux driver version (this will change if format changes) 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2. 2) APM flags from APM Installation Check (0x00): bit 0: APM_16_BIT_SUPPORT bit 1: APM_32_BIT_SUPPORT bit 2: APM_IDLE_SLOWS_CLOCK bit 3: APM_BIOS_DISABLED bit 4: APM_BIOS_DISENGAGED 3) AC line status 0x00: Off-line 0x01: On-line 0x02: On backup power (BIOS >= 1.1 only) 0xff: Unknown 4) Battery status 0x00: High 0x01: Low 0x02: Critical 0x03: Charging 0x04: Selected battery not present (BIOS >= 1.2 only) 0xff: Unknown 5) Battery flag bit 0: High bit 1: Low bit 2: Critical bit 3: Charging bit 7: No system battery 0xff: Unknown 6) Remaining battery life (percentage of charge): 0-100: valid -1: Unknown 7) Remaining battery life (time units): Number of remaining minutes or seconds -1: Unknown 8) min = minutes; sec = seconds */ if ( !loadinfo.good() ){ XOSDEBUG("Can not open file : %s\n", APMFILENAME); return false; } int battery_status=0xff; // assume unknown as default char buff[256]; loadinfo >> buff >> buff >> buff >> buff >> std::hex >> battery_status >> buff >> fields_[0]; // XOSDEBUG("apm battery_status is: %d\n",battery_status); // save previous state // if there was no state-change - the gui won't do full redraw old_apm_battery_state=apm_battery_state; apm_battery_state=battery_status; // If the battery status is reported as a negative number, it means we are // running on AC power and no battery status is available - Report it as // completely empty (0). (Refer to Debian bug report #281565) if (fields_[0] < 0) fields_[0] = 0; total_ = 100; if ( apm_battery_state != 0xFF ) { fields_[1] = total_ - fields_[0]; } else { // prevent setting it to '-1' if no batt fields_[0] = 0; fields_[1] = total_; } setUsed (fields_[0], total_); return true; } // ACPI provides a lot of info, // but munging it into something usefull is ugly // esp. as you can have more than one battery ... bool BtryMeter::getacpi_or_sys_info( void ){ DIR *dir = NULL; std::string abs_battery_dir; if (use_acpi) { abs_battery_dir = ACPIBATTERYDIR; } else { abs_battery_dir = SYSPOWERDIR; } dir = opendir(abs_battery_dir.c_str()); if (dir==NULL) { XOSDEBUG("ACPI/SYS: Cannot open directory : %s\n", abs_battery_dir.c_str()); return false; } bool found = false; // whether we found at least ONE battery // reset all sums acpi_sum_cap=0; acpi_sum_remain=0; acpi_sum_rate=0; acpi_sum_alarm=0; // save old state old_acpi_charge_state=acpi_charge_state; acpi_charge_state=0; // assume charged for (struct dirent *dirent; (dirent = readdir(dir)) != NULL; ) { if (strncmp(dirent->d_name, ".", 1) == 0 || strncmp(dirent->d_name, "..", 2) == 0) continue; std::string abs_battery_name = abs_battery_dir + "/" + dirent->d_name; XOSDEBUG("ACPI/SYS Batt: %s\n", dirent->d_name); // still can happen that it's not present: if ( (use_acpi && (acpi_battery_present(abs_battery_name + "/info" )) && (acpi_parse_battery(abs_battery_name))) || (use_syspower && (sys_battery_present(abs_battery_name + "/present" )) && (sys_parse_battery(abs_battery_name))) ) { // sum up: // clip values to get realistic on full-charged batteries if ( battery.remaining_capacity >= battery.last_full_capacity) battery.remaining_capacity=battery.last_full_capacity; acpi_sum_cap +=battery.last_full_capacity; acpi_sum_remain+=battery.remaining_capacity; acpi_sum_rate +=battery.present_rate; acpi_sum_alarm +=battery.alarm; // sum up charge state ... // works only w. signed formats acpi_charge_state|=battery.charging_state; found = true; // found at least one } } closedir(dir); total_ = 100; // convert into percent vals // XOSDEBUG("acpi: total max=%d, remain=%d\n",acpi_sum_cap,acpi_sum_remain); // below alarm ? if ( acpi_sum_alarm >= acpi_sum_remain && acpi_charge_state != 1 ) acpi_charge_state=-2; // if NONE of the batts is present: if ( found ) { fields_[0] = (float)acpi_sum_remain/(float)acpi_sum_cap*100.0; } else { // none of the batts is present // (just pull out both while on AC) fields_[0] = 0; acpi_charge_state=-3; } fields_[1] = total_ - fields_[0]; setUsed (fields_[0], total_); return true; } // present yes/no can change anytime ! // by adding/removing a battery bool BtryMeter::acpi_battery_present(const std::string& filename) { std::ifstream loadinfo( filename.c_str() ); std::string argname; std::string argval; while ( !loadinfo.eof() ) { argname.clear(); argval.clear(); loadinfo >> argname >> argval; XOSDEBUG("batt ?: a=\"%s\" v=\"%s\"\n",argname.c_str(),argval.c_str() ); if ( argname == "present:" ) if ( argval == "yes" ) return true; } XOSDEBUG("batt %s not present\n",filename.c_str() ); return false; } bool BtryMeter::acpi_parse_battery(const std::string& dirname) { // actually there are THREE files to check: // 'alarm', 'info' and 'state' std::string filename; std::ifstream loadinfo; std::istringstream inp_strm; std::string inp_line; std::string argname; std::string argval; filename = dirname + "/alarm"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { std::getline(loadinfo,inp_line); inp_strm.str(inp_line.c_str() ); argname.clear(); argval.clear(); inp_strm >> argname >> argval; XOSDEBUG("alarm: a=\"%s\" v=\"%s\"\n",argname.c_str(),argval.c_str() ); if ( argname == "alarm:" ) { battery.alarm = atoi(argval.c_str()); break; } } loadinfo.close(); loadinfo.clear(); filename = dirname + "/info"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { argname.clear(); std::getline(loadinfo,argname,':'); argval.clear(); std::getline(loadinfo,argval); XOSDEBUG("info: a=\"%s\" v=\"%s\"\n",argname.c_str(),argval.c_str() ); if ( argname == "design capacity" ) { battery.design_capacity=atoi(argval.c_str() ); } if ( argname == "last full capacity" ) { battery.last_full_capacity=atoi(argval.c_str() ); } if ( argname == "last full capacity" ) { battery.last_full_capacity=atoi(argval.c_str() ); } } loadinfo.close(); loadinfo.clear(); // clear eof-bit filename = dirname + "/state"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { // argname can contain spaces argname.clear(); std::getline(loadinfo,argname,':'); // argval should NOT contain blanks inp_line.clear(); std::getline(loadinfo,inp_line); inp_strm.clear(); inp_strm.seekg(0); inp_strm.str(inp_line.c_str() ); argval.clear(); inp_strm >> argval; // this ignores leading spaces XOSDEBUG("state: a=\"%s\" v=\"%s\"\n",argname.c_str(),argval.c_str() ); if ( argname == "charging state" ) { if ( argval == "charged" ) battery.charging_state=0; if ( argval == "discharging" ) battery.charging_state=-1; if ( argval == "charging" ) battery.charging_state=1; } if ( argname == "last full capacity" ) { battery.last_full_capacity=atoi(argval.c_str() ); } if ( argname == "last full capacity" ) { battery.last_full_capacity=atoi(argval.c_str() ); } if ( argname == "remaining capacity" ) { battery.remaining_capacity=atoi(argval.c_str() ); } } return true; } // present yes/no can change anytime ! // by adding/removing a battery bool BtryMeter::sys_battery_present(const std::string& filename) { std::ifstream loadinfo( filename.c_str() ); std::string value; while ( loadinfo.good() ) { value.clear(); loadinfo >> value; if (value == "1") return true; } XOSDEBUG("batt %s not present\n",filename.c_str() ); return false; } bool BtryMeter::sys_parse_battery(const std::string& dirname) { std::string filename; std::ifstream loadinfo; std::string value; struct stat stbuf; filename = dirname + "/alarm"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { value.clear(); loadinfo >> value; XOSDEBUG("alarm (%s): v=\"%s\"\n", filename.c_str(), value.c_str() ); battery.alarm = atoi(value.c_str()); break; } loadinfo.close(); loadinfo.clear(); filename = dirname + "/energy_full_design"; if (stat(filename.c_str(),&stbuf)!=0) filename=dirname+"/charge_full_design"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { value.clear(); loadinfo >> value; XOSDEBUG("design_capacity (%s): v=\"%s\"\n", filename.c_str(), value.c_str() ); battery.design_capacity = atoi(value.c_str()); break; } loadinfo.close(); loadinfo.clear(); filename = dirname + "/energy_full"; if (stat(filename.c_str(),&stbuf)!=0) filename=dirname+"/charge_full"; loadinfo.open(filename.c_str() ); if (!loadinfo.good()) { loadinfo.close(); loadinfo.clear(); filename=dirname+"/charge_full_design"; loadinfo.open(filename.c_str()); } while ( loadinfo.good() ) { value.clear(); loadinfo >> value; XOSDEBUG("last_full_capacity (%s): v=\"%s\"\n", filename.c_str(), value.c_str() ); battery.last_full_capacity = atoi(value.c_str()); break; } loadinfo.close(); loadinfo.clear(); filename = dirname + "/energy_now"; if (stat(filename.c_str(),&stbuf)!=0) filename=dirname+"/charge_now"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { value.clear(); loadinfo >> value; XOSDEBUG("remaining_capacity (%s): v=\"%s\"\n", filename.c_str(), value.c_str() ); battery.remaining_capacity = atoi(value.c_str()); break; } loadinfo.close(); loadinfo.clear(); filename = dirname + "/status"; loadinfo.open(filename.c_str() ); while ( loadinfo.good() ) { value.clear(); loadinfo >> value; XOSDEBUG("status (%s): v=\"%s\"\n", filename.c_str(), value.c_str() ); battery.charging_state=0; if ( value == "Discharging" ) battery.charging_state=-1; if ( value == "Charging" ) battery.charging_state=1; break; } loadinfo.close(); loadinfo.clear(); return true; } xosview-1.20/linux/btrymeter.h000066400000000000000000000032241317735352700165030ustar00rootroot00000000000000// // Copyright (c) 1997, 2005, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _BTRYMETER_H_ #define _BTRYMETER_H_ #include "fieldmeter.h" #include "xosview.h" #include class BtryMeter : public FieldMeter { public: BtryMeter( XOSView *parent ); ~BtryMeter( void ); const char *name( void ) const { return "BtryMeter"; } void checkevent( void ); void checkResources( void ); // some basic fields of 'info','alarm','state' // XXX: should be private struct acpi_batt { int alarm; // in mWh int design_capacity; // in mWh int last_full_capacity; // in mWh int charging_state; // charged=0,discharging=-1,charging=1 int present_rate; // in mW, 0=unknown int remaining_capacity; // in mW }; acpi_batt battery; static bool has_source( void ); protected: void getpwrinfo( void ); private: bool getapminfo( void ); bool getacpi_or_sys_info( void ); bool use_apm; bool use_acpi; bool use_syspower; bool acpi_battery_present(const std::string& filename); bool acpi_parse_battery(const std::string& filename); bool sys_battery_present(const std::string& filename); bool sys_parse_battery(const std::string& filename); static bool has_acpi(void); static bool has_apm(void); static bool has_syspower(void); void handle_apm_state(void); void handle_acpi_state(void); int apm_battery_state; int old_apm_battery_state; int acpi_charge_state; int old_acpi_charge_state; int acpi_sum_cap; int acpi_sum_remain; int acpi_sum_rate; int acpi_sum_alarm; }; #endif xosview-1.20/linux/coretemp.cc000066400000000000000000000261741317735352700164530ustar00rootroot00000000000000// // Copyright (c) 2008-2014 by Tomi Tapper // // Read CPU temperature readings from /sys and display actual temperature. // If actual >= high, actual temp changes color to indicate alarm. // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // #include "coretemp.h" #include #include #include #include #include #include #include #include #include #include #define PATH_SIZE 128 static const char SYS_HWMON[] = "/sys/class/hwmon"; static const char SYS_CORETEMP[] = "/sys/devices/platform/coretemp"; static const char SYS_VIATEMP[] = "/sys/devices/platform/via_cputemp"; CoreTemp::CoreTemp( XOSView *parent, const char *label, const char *caption, int pkg, int cpu ) : FieldMeter( parent, 3, label, caption, 1, 1, 1 ), _pkg(pkg), _cpu(cpu) { metric_ = true; _high = 0; } CoreTemp::~CoreTemp( void ) { } void CoreTemp::checkResources( void ) { FieldMeter::checkResources(); _actcolor = parent_->allocColor( parent_->getResource( "coretempActColor" ) ); _highcolor = parent_->allocColor( parent_->getResource( "coretempHighColor") ); setfieldcolor( 0, _actcolor ); setfieldcolor( 1, parent_->getResource( "coretempIdleColor") ); setfieldcolor( 2, _highcolor ); priority_ = atoi( parent_->getResource( "coretempPriority" ) ); SetUsedFormat( parent_->getResource( "coretempUsedFormat" ) ); findSysFiles(); if ( _cpus.empty() ) { // should not happen at this point std::cerr << "BUG: Could not determine sysfs file(s) for coretemp." << std::endl; parent_->done(1); } // Get TjMax and use it for total, if available. // Not found on k8temp and via-cputemp. std::ifstream file; std::string dummy = _cpus.front(); dummy.replace(dummy.find_last_of('_'), 6, "_crit"); file.open(dummy.c_str()); if ( file.good() ) { file >> total_; file.close(); total_ /= 1000.0; } else total_ = atoi( parent_->getResourceOrUseDefault("coretempHighest", "100") ); // Use tTarget/tCtl (when maximum cooling needs to be turned on) as high, // if found. On older Cores this MSR is empty and kernel sets this equal to // tjMax. Not found on k8temp and via-cputemp. On k10temp this is fixed value. char l[32]; dummy = _cpus.front(); dummy.replace(dummy.find_last_of('_'), 6, "_max"); file.open(dummy.c_str()); if ( file.good() ) { file >> _high; file.close(); _high /= 1000.0; snprintf(l, 32, "ACT(\260C)/%d/%d", (int)_high, (int)total_); } else _high = total_; if (_high == total_) { // No tTarget/tCtl // Use user-defined high, or "no high". const char *high = parent_->getResourceOrUseDefault("coretempHigh", NULL); if (high) { _high = atoi(high); snprintf(l, 32, "ACT(\260C)/%d/%d", (int)_high, (int)total_); } else snprintf(l, 32, "ACT(\260C)/HIGH/%d", (int)total_); } legend(l); } /* Find absolute paths of files to be used. */ void CoreTemp::findSysFiles( void ) { int cpu = 0; unsigned int i = 0, cpucount = countCores(_pkg); char name[PATH_SIZE]; std::string dummy; std::ifstream file; glob_t gbuf; DIR *dir; struct dirent *dent; struct stat buf; // Intel and VIA CPUs. // Platform device sysfs node changed in kernel 3.15 -> try both paths. snprintf(name, PATH_SIZE, "%s.%d/temp*_label", SYS_CORETEMP, _pkg); glob(name, 0, NULL, &gbuf); snprintf(name, PATH_SIZE, "%s.%d/hwmon/hwmon*/temp*_label", SYS_CORETEMP, _pkg); glob(name, GLOB_APPEND, NULL, &gbuf); snprintf(name, PATH_SIZE, "%s.%d/temp*_label", SYS_VIATEMP, _pkg); glob(name, GLOB_APPEND, NULL, &gbuf); snprintf(name, PATH_SIZE, "%s.%d/hwmon/hwmon*/temp*_label", SYS_VIATEMP, _pkg); glob(name, GLOB_APPEND, NULL, &gbuf); for (i = 0; i < gbuf.gl_pathc; i++) { file.open(gbuf.gl_pathv[i]); file >> dummy >> cpu; // "Core n" or "Physical id n" file.close(); if ( strncmp(dummy.c_str(), "Core", 4) == 0 ) { strcpy(strrchr(gbuf.gl_pathv[i], '_'), "_input"); if (_cpu < 0 || cpu == _cpu) _cpus.push_back(gbuf.gl_pathv[i]); } } globfree(&gbuf); if ( !_cpus.empty() ) return; // AMD CPUs. if ( !(dir = opendir(SYS_HWMON)) ) { std::cerr << "Can not open " << SYS_HWMON << " directory." << std::endl; parent_->done(1); return; } while ( (dent = readdir(dir)) ) { if ( !strncmp(dent->d_name, ".", 1) || !strncmp(dent->d_name, "..", 2) ) continue; snprintf(name, PATH_SIZE, "%s/%s/name", SYS_HWMON, dent->d_name); file.open(name); if (!file) { // Older kernels place the name in device directory. snprintf(name, PATH_SIZE, "%s/%s/device/name", SYS_HWMON, dent->d_name); file.open(name); if (!file) continue; } file >> dummy; file.close(); if ( strncmp(dummy.c_str(), "k8temp", 6) == 0 || strncmp(dummy.c_str(), "k10temp", 7) == 0 ) { if (cpu++ != _pkg) continue; // K8 core has two sensors with index starting from 1 // K10 has only one sensor per physical CPU if (_cpu < 0) { // avg or max for (i = 1; i <= cpucount; i++) { snprintf(name, PATH_SIZE, "%s/%s/temp%d_input", SYS_HWMON, dent->d_name, i); if (!( stat(name, &buf) == 0 && S_ISREG(buf.st_mode) )) snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", SYS_HWMON, dent->d_name, i); _cpus.push_back(name); } } else { // single sensor snprintf(name, PATH_SIZE, "%s/%s/temp%d_input", SYS_HWMON, dent->d_name, _cpu + 1); if (!( stat(name, &buf) == 0 && S_ISREG(buf.st_mode) )) snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", SYS_HWMON, dent->d_name, i); _cpus.push_back(name); } } } closedir(dir); } void CoreTemp::checkevent( void ) { getcoretemp(); drawfields(); } void CoreTemp::getcoretemp( void ) { std::ifstream file; double dummy; fields_[0] = 0.0; if (_cpu >= 0) { // only one core file.open(_cpus.back().c_str()); if (!file) { std::cerr << "Can not open file : " << _cpus.back().c_str() << std::endl; parent_->done(1); return; } file >> fields_[0]; file.close(); } else if (_cpu == -1) { // average for (uint i = 0; i < _cpus.size(); i++) { file.open(_cpus[i].c_str()); if (!file) { std::cerr << "Can not open file : " << _cpus[i].c_str() << std::endl; parent_->done(1); return; } file >> dummy; file.close(); fields_[0] += dummy; } fields_[0] /= (double)_cpus.size(); } else if (_cpu == -2) { // maximum for (uint i = 0; i < _cpus.size(); i++) { file.open(_cpus[i].c_str()); if (!file) { std::cerr << "Can not open file : " << _cpus[i].c_str() << std::endl; parent_->done(1); return; } file >> dummy; file.close(); if (dummy > fields_[0]) fields_[0] = dummy; } } else { // should not happen std::cerr << "Unknown CPU core number " << _cpu << " in coretemp." << std::endl; parent_->done(1); return; } fields_[0] /= 1000.0; setUsed( fields_[0], total_ ); if (fields_[0] < 0) fields_[0] = 0.0; fields_[1] = _high - fields_[0]; if (fields_[1] < 0) { // alarm: T > high fields_[1] = 0; if (colors_[0] != _highcolor) { setfieldcolor( 0, _highcolor ); drawlegend(); } } else { if (colors_[0] != _actcolor) { setfieldcolor( 0, _actcolor ); drawlegend(); } } fields_[2] = total_ - fields_[1] - fields_[0]; if (fields_[2] < 0) fields_[2] = 0; } /* Count sensors available to coretemp in the given package. */ unsigned int CoreTemp::countCores( unsigned int pkg ) { glob_t gbuf; char s[PATH_SIZE]; unsigned int i, count = 0, cpu = 0; DIR *dir; struct dirent *dent; struct stat buf; std::string dummy; std::ifstream file; // Intel or VIA CPU. // Platform device sysfs node changed in kernel 3.15 -> try both paths. snprintf(s, PATH_SIZE, "%s.%d/temp*_label", SYS_CORETEMP, pkg); glob(s, 0, NULL, &gbuf); snprintf(s, PATH_SIZE, "%s.%d/hwmon/hwmon*/temp*_label", SYS_CORETEMP, pkg); glob(s, GLOB_APPEND, NULL, &gbuf); snprintf(s, PATH_SIZE, "%s.%d/temp*_label", SYS_VIATEMP, pkg); glob(s, GLOB_APPEND, NULL, &gbuf); snprintf(s, PATH_SIZE, "%s.%d/hwmon/hwmon*/temp*_label", SYS_VIATEMP, pkg); glob(s, GLOB_APPEND, NULL, &gbuf); // loop through paths in gbuf and check if it is a core or package for (i = 0; i < gbuf.gl_pathc; i++) { file.open(gbuf.gl_pathv[i]); file >> dummy; file.close(); if ( strncmp(dummy.c_str(), "Core", 4) == 0 ) count++; } globfree(&gbuf); if (count > 0) return count; // AMD CPU. if ( !(dir = opendir(SYS_HWMON)) ) return 0; // loop through hwmon devices and when AMD sensor is found, count its inputs while ( (dent = readdir(dir)) ) { if ( !strncmp(dent->d_name, ".", 1) || !strncmp(dent->d_name, "..", 2) ) continue; snprintf(s, PATH_SIZE, "%s/%s/name", SYS_HWMON, dent->d_name); if (!( stat(s, &buf) == 0 && S_ISREG(buf.st_mode) )) // Older kernels place the name in device directory. snprintf(s, PATH_SIZE, "%s/%s/device/name", SYS_HWMON, dent->d_name); file.open(s); if ( file.good() ) { file >> dummy; file.close(); if ( strncmp(dummy.c_str(), "k8temp", 6) == 0 || strncmp(dummy.c_str(), "k10temp", 7) == 0 ) { if (cpu++ < pkg) continue; snprintf(s, PATH_SIZE, "%s/%s/temp*_input", SYS_HWMON, dent->d_name); glob(s, 0, NULL, &gbuf); snprintf(s, PATH_SIZE, "%s/%s/device/temp*_input", SYS_HWMON, dent->d_name); glob(s, GLOB_APPEND, NULL, &gbuf); count += gbuf.gl_pathc; globfree(&gbuf); } } } closedir(dir); return count; } /* Count physical CPUs with sensors. */ unsigned int CoreTemp::countCpus( void ) { glob_t gbuf; char s[PATH_SIZE]; unsigned int count = 0; DIR *dir; struct dirent *dent; struct stat buf; std::string dummy; std::ifstream file; // Count Intel and VIA packages. snprintf(s, PATH_SIZE, "%s.*", SYS_CORETEMP); glob(s, 0, NULL, &gbuf); snprintf(s, PATH_SIZE, "%s.*", SYS_VIATEMP); glob(s, GLOB_APPEND, NULL, &gbuf); count += gbuf.gl_pathc; globfree(&gbuf); if (count > 0) return count; // Count AMD packages. if ( !(dir = opendir(SYS_HWMON)) ) return 0; while ( (dent = readdir(dir)) ) { if ( !strncmp(dent->d_name, ".", 1) || !strncmp(dent->d_name, "..", 2) ) continue; snprintf(s, PATH_SIZE, "%s/%s/name", SYS_HWMON, dent->d_name); if (!( stat(s, &buf) == 0 && S_ISREG(buf.st_mode) )) // Older kernels place the name in device directory. snprintf(s, PATH_SIZE, "%s/%s/device/name", SYS_HWMON, dent->d_name); file.open(s); if ( file.good() ) { file >> dummy; file.close(); if ( strncmp(dummy.c_str(), "k8temp", 6) == 0 || strncmp(dummy.c_str(), "k10temp", 7) == 0 ) count++; } } closedir(dir); return count; } xosview-1.20/linux/coretemp.h000066400000000000000000000016271317735352700163110ustar00rootroot00000000000000// // Copyright (c) 2008-2014 by Tomi Tapper // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch // // This file may be distributed under terms of the GPL // // #ifndef _CORETEMP_H_ #define _CORETEMP_H_ #include "fieldmeter.h" #include "xosview.h" #include #include class CoreTemp : public FieldMeter { public: CoreTemp( XOSView *parent, const char *label, const char *caption, int pkg, int cpu); ~CoreTemp( void ); const char *name( void ) const { return "CoreTemp"; } void checkevent( void ); void checkResources( void ); static unsigned int countCores( unsigned int pkg ); static unsigned int countCpus( void ); protected: void getcoretemp( void ); private: void findSysFiles( void ); int _pkg, _cpu, _high; std::vector _cpus; unsigned long _actcolor, _highcolor; }; #endif xosview-1.20/linux/cpumeter.cc000066400000000000000000000264651317735352700164640ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "cpumeter.h" #include #include #include #include #include #include #include #include static const char STATFILENAME[] = "/proc/stat"; static int cputime_to_field[10] = { 0, 1, 2, 9, 5, 4, 3, 8, 6, 7 }; #define MAX_PROCSTAT_LENGTH 4096 CPUMeter::CPUMeter(XOSView *parent, const char *cpuID) : FieldMeterGraph( parent, 10, toUpper(cpuID), "USR/NIC/SYS/SI/HI/WIO/GST/NGS/STL/IDLE" ) { _lineNum = findLine(cpuID); for ( int i = 0 ; i < 2 ; i++ ) for ( int j = 0 ; j < 10 ; j++ ) cputime_[i][j] = 0; cpuindex_ = 0; kernel_ = getkernelversion(); if (kernel_ < 2006000) statfields_ = 4; else if (kernel_ < 2006011) statfields_ = 7; else if (kernel_ < 2006024) statfields_ = 8; else if (kernel_ < 2006032) statfields_ = 9; else statfields_ = 10; } CPUMeter::~CPUMeter( void ){ } void CPUMeter::checkResources( void ){ FieldMeterGraph::checkResources(); unsigned long usercolor = parent_->allocColor(parent_->getResource( "cpuUserColor" ) ); unsigned long nicecolor = parent_->allocColor(parent_->getResource( "cpuNiceColor" ) ); unsigned long syscolor = parent_->allocColor(parent_->getResource( "cpuSystemColor" ) ); unsigned long sintcolor = parent_->allocColor(parent_->getResource( "cpuSInterruptColor" ) ); unsigned long intcolor = parent_->allocColor(parent_->getResource( "cpuInterruptColor" ) ); unsigned long waitcolor = parent_->allocColor(parent_->getResource( "cpuWaitColor" ) ); unsigned long gstcolor = parent_->allocColor(parent_->getResource( "cpuGuestColor" ) ); unsigned long ngstcolor = parent_->allocColor(parent_->getResource( "cpuNiceGuestColor" ) ); unsigned long stealcolor= parent_->allocColor(parent_->getResource( "cpuStolenColor" ) ); unsigned long idlecolor = parent_->allocColor(parent_->getResource( "cpuFreeColor" ) ); priority_ = atoi(parent_->getResource( "cpuPriority" ) ); dodecay_ = parent_->isResourceTrue( "cpuDecay" ); useGraph_ = parent_->isResourceTrue( "cpuGraph" ); SetUsedFormat(parent_->getResource("cpuUsedFormat") ); /* Use user-defined fields. * Fields Including if not its own field * --------------|------------------------------ * USED all used time, including user and system times * USR user time, including nice and guest times * NIC niced time, including niced guest unless guest is present * GST guest time, including niced guest time * NGS niced guest time * SYS system time, including interrupt and stolen times * INT interrupt time, including soft and hard interrupt times * HI hard interrupt time * SI soft interrupt time * STL stolen time * IDLE idle time, including io wait time * WIO io wait time * * Stolen time is a class of its own in kernel scheduler, in cpufreq it is * considered used time. Here it is part of used and system time, but can be * separate field as well. * Idle field is always present. * Either USED or at least USR+SYS must be included. */ const char *f = parent_->getResource( "cpuFields" ); std::string lgnd, fields(f); int field = 0; /* Check for possible fields and define field mapping. Assign colors and * build legend on the way. */ if (fields.find("USED") != fields.npos) { // USED = USR+NIC+SYS+SI+HI+GST+NGS(+STL) if (fields.find("USR") != fields.npos || fields.find("NIC") != fields.npos || fields.find("SYS") != fields.npos || fields.find("INT") != fields.npos || fields.find("HI") != fields.npos || fields.find("SI") != fields.npos || fields.find("GST") != fields.npos || fields.find("NGS") != fields.npos) { std::cerr << "'USED' cannot be in cpuFields together with either 'USR', " << "'NIC', 'SYS', 'INT', 'HI', 'SI', 'GST' or 'NGS'." << std::endl; exit(1); } setfieldcolor(field, usercolor); if (kernel_ >= 2006000) // SI and HI cputime_to_field[5] = cputime_to_field[6] = field; if (kernel_ >= 2006024) // GST cputime_to_field[8] = field; if (kernel_ >= 2006032) // NGS cputime_to_field[9] = field; if (kernel_ >= 2006011 && fields.find("STL") == fields.npos) cputime_to_field[7] = field; // STL can be separate as well // USR, NIC and SYS cputime_to_field[0] = cputime_to_field[1] = cputime_to_field[2] = field++; lgnd = "USED"; } if (fields.find("USR") != fields.npos) { setfieldcolor(field, usercolor); // add NIC if not on its own if (fields.find("NIC") == fields.npos) cputime_to_field[1] = field; // add GST if not on its own if (kernel_ >= 2006024 && fields.find("GST") == fields.npos) cputime_to_field[8] = field; // add NGS if not on its own and neither NIC or GST is present if (kernel_ >= 2006032 && fields.find("NGS") == fields.npos && fields.find("NIC") == fields.npos && fields.find("GST") == fields.npos) cputime_to_field[9] = field; cputime_to_field[0] = field++; lgnd = "USR"; } else { if (fields.find("USED") == fields.npos) { std::cerr << "Either 'USED' or 'USR' is mandatory in cpuFields." << std::endl; exit(1); } } if (fields.find("NIC") != fields.npos) { setfieldcolor(field, nicecolor); // add NGS if not on its own and GST is not present if (kernel_ >= 2006032 && fields.find("NGS") == fields.npos && fields.find("GST") == fields.npos) cputime_to_field[9] = field; cputime_to_field[1] = field++; lgnd += "/NIC"; } if (fields.find("SYS") != fields.npos) { setfieldcolor(field, syscolor); // add SI if not on its own and INT is not present if (kernel_ >= 2006000 && fields.find("SI") == fields.npos && fields.find("INT") == fields.npos) cputime_to_field[6] = field; // add HI if not on its own and INT is not present if (kernel_ >= 2006000 && fields.find("HI") == fields.npos && fields.find("INT") == fields.npos) cputime_to_field[5] = field; // add STL if not on its own if (kernel_ >= 2006011 && fields.find("STL") == fields.npos) cputime_to_field[7] = field; cputime_to_field[2] = field++; lgnd += "/SYS"; } else { if (fields.find("USED") == fields.npos) { std::cerr << "Either 'USED' or 'SYS' is mandatory in cpuFields." << std::endl; exit(1); } } if (kernel_ >= 2006000) { if (fields.find("INT") != fields.npos) { // combine soft and hard interrupt times setfieldcolor(field, intcolor); cputime_to_field[5] = cputime_to_field[6] = field++; lgnd += "/INT"; } // Maybe should warn if both INT and HI/SI are requested ??? else { // separate soft and hard interrupt times if (fields.find("SI") != fields.npos) { setfieldcolor(field, sintcolor); cputime_to_field[5] = field++; lgnd += "/SI"; } if (fields.find("HI") != fields.npos) { setfieldcolor(field, intcolor); cputime_to_field[6] = field++; lgnd += "/HI"; } } if (fields.find("WIO") != fields.npos) { setfieldcolor(field, waitcolor); cputime_to_field[4] = field++; lgnd += "/WIO"; } if (kernel_ >= 2006024 && fields.find("GST") != fields.npos) { setfieldcolor(field, gstcolor); // add NGS if not on its own if (kernel_ >= 2006032 && fields.find("NGS") == fields.npos) cputime_to_field[9] = field; cputime_to_field[8] = field++; lgnd += "/GST"; } if (kernel_ >= 2006032 && fields.find("NGS") != fields.npos) { setfieldcolor(field, ngstcolor); cputime_to_field[9] = field++; lgnd += "/NGS"; } if (kernel_ >= 2006011 && fields.find("STL") != fields.npos) { setfieldcolor(field, stealcolor); cputime_to_field[7] = field++; lgnd += "/STL"; } } // always add IDLE field setfieldcolor(field, idlecolor); // add WIO if not on its own if (kernel_ >= 2006000 && fields.find("WIO") == fields.npos) cputime_to_field[4] = field; cputime_to_field[3] = field++; lgnd += "/IDLE"; legend(lgnd.c_str()); numfields_ = field; // can't use setNumFields as it destroys the color mapping } void CPUMeter::checkevent( void ){ getcputime(); drawfields(); } void CPUMeter::getcputime( void ){ total_ = 0; std::string tmp; std::ifstream stats( STATFILENAME ); char *end = NULL; if ( !stats ){ std::cerr <<"Can not open file : " < #include #include #include #include #include #include #include #include #include #include #define MAX_PROCSTAT_LENGTH 4096 DiskMeter::DiskMeter( XOSView *parent, float max ) : FieldMeterGraph( parent, 3, "DISK", "READ/WRITE/IDLE"), _vmstat(false), _statFileName("/proc/stat") { read_prev_ = 0; write_prev_ = 0; maxspeed_ = max; _sysfs=_vmstat=false; struct stat buf; // first - try sysfs: if (stat("/sys/block", &buf) == 0 && buf.st_mode & S_IFDIR) { _sysfs = true; _statFileName = "/sys/block"; XOSDEBUG("diskmeter: using sysfs /sys/block\n"); getsysfsdiskinfo(); } else // try vmstat: if (stat("/proc/vmstat", &buf) == 0 && buf.st_mode & S_IFREG) { _vmstat = true; _sysfs = false; _statFileName = "/proc/vmstat"; getvmdiskinfo(); } else // fall back to stat getdiskinfo(); } DiskMeter::~DiskMeter( void ) { } void DiskMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("diskReadColor") ); setfieldcolor( 1, parent_->getResource("diskWriteColor") ); setfieldcolor( 2, parent_->getResource("diskIdleColor") ); priority_ = atoi (parent_->getResource( "diskPriority" ) ); dodecay_ = parent_->isResourceTrue("diskDecay" ); useGraph_ = parent_->isResourceTrue( "diskGraph" ); SetUsedFormat(parent_->getResource("diskUsedFormat")); } void DiskMeter::checkevent( void ) { if (_vmstat) getvmdiskinfo(); else if ( _sysfs ) getsysfsdiskinfo(); else getdiskinfo(); drawfields(); } // IMHO the logic here is quite broken - but for backward compat UNCHANGED: void DiskMeter::updateinfo(unsigned long one, unsigned long two, int fudgeFactor) { // assume each "unit" is 1k. // This is true for ext2, but seems to be 512 bytes // for vfat and 2k for cdroms // work in 512-byte blocks // tw: strange, on my system, a ext2fs (read and write) // unit seems to be 2048. kernel 2.2.12 and the file system // is on a SW-RAID5 device (/dev/md0). // So this is a FIXME - but how ??? float itim = IntervalTimeInMicrosecs(); unsigned long read_curr = one * fudgeFactor; // FIXME! unsigned long write_curr = two * fudgeFactor; // FIXME! // avoid strange values at first call if(read_prev_ == 0) read_prev_ = read_curr; if(write_prev_ == 0) write_prev_ = write_curr; // calculate rate in bytes per second fields_[0] = ((read_curr - read_prev_) * 1e6 * 512) / itim; fields_[1] = ((write_curr - write_prev_) * 1e6 * 512) / itim; // fix overflow (conversion bug?) if (fields_[0] < 0.0) fields_[0] = 0.0; if (fields_[1] < 0.0) fields_[1] = 0.0; if (fields_[0] + fields_[1] > total_) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - (fields_[0] + fields_[1]); read_prev_ = read_curr; write_prev_ = write_curr; setUsed((fields_[0]+fields_[1]), total_); IntervalTimerStart(); } void DiskMeter::getvmdiskinfo(void) { IntervalTimerStop(); total_ = maxspeed_; char buf[MAX_PROCSTAT_LENGTH]; std::ifstream stats(_statFileName); unsigned long one, two; if ( !stats ) { std::cerr <<"Can not open file : " << _statFileName << std::endl; exit( 1 ); } stats >> buf; // kernel >= 2.5 while (!stats.eof() && strncmp(buf, "pgpgin", 7)) { stats.ignore(1024, '\n'); stats >> buf; } // read first value stats >> one; while (!stats.eof() && strncmp(buf, "pgpgout", 7)) { stats.ignore(1024, '\n'); stats >> buf; } // read second value stats >> two; updateinfo(one, two, 4); } void DiskMeter::getdiskinfo( void ) { IntervalTimerStop(); total_ = maxspeed_; char buf[MAX_PROCSTAT_LENGTH]; std::ifstream stats(_statFileName); if ( !stats ) { std::cerr <<"Can not open file : " << _statFileName << std::endl; exit( 1 ); } // Find the line with 'page' stats >> buf; while (strncmp(buf, "disk_io:", 8)) { stats.ignore(MAX_PROCSTAT_LENGTH, '\n'); stats >> buf; if (stats.eof()) break; } // read values unsigned long one=0, two=0; unsigned long junk,read1,write1; stats >> buf; while (7 == sscanf(buf,"(%lu,%lu):(%lu,%lu,%lu,%lu,%lu)",&junk,&junk,&junk,&junk,&read1,&junk,&write1)) { one += read1; two += write1; stats >> buf; } updateinfo(one, two, 1); } // sysfs version - works with long-long !! void DiskMeter::update_info(const diskmap &reads, const diskmap &writes) { float itim = IntervalTimeInMicrosecs(); // the sum of all disks unsigned long long all_bytes_read = 0, all_bytes_written = 0; unsigned int sect_size = 512; // from linux-3.10/Documentation/block/stat.txt // avoid strange values at first call // (by this - the first value displayed becomes zero) if (sysfs_read_prev_.empty()) { sysfs_read_prev_ = reads; sysfs_write_prev_ = writes; itim = 1; // itim is garbage here too. Valgrind complains. } for (diskmap::const_iterator it = reads.begin(); it != reads.end(); it++) { if (it->second < sysfs_read_prev_[it->first]) // counter wrapped all_bytes_read += ULONG_MAX - sysfs_read_prev_[it->first] + it->second; else all_bytes_read += it->second - sysfs_read_prev_[it->first]; } for (diskmap::const_iterator it = writes.begin(); it != writes.end(); it++) { if (it->second < sysfs_write_prev_[it->first]) // counter wrapped all_bytes_written += ULONG_MAX - sysfs_write_prev_[it->first] + it->second; else all_bytes_written += it->second - sysfs_write_prev_[it->first]; } all_bytes_read *= sect_size; all_bytes_written *= sect_size; XOSDEBUG("disk: read: %llu, written: %llu\n", all_bytes_read, all_bytes_written); // convert rate from bytes/microsec into bytes/second fields_[0] = all_bytes_read * ( 1e6 / itim ); fields_[1] = all_bytes_written * ( 1e6 / itim ); // fix overflow (conversion bug?) if (fields_[0] < 0.0) fields_[0] = 0.0; if (fields_[1] < 0.0) fields_[1] = 0.0; // bump up max total: if (fields_[0] + fields_[1] > total_) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - (fields_[0] + fields_[1]); // save old vals for next round sysfs_read_prev_ = reads; sysfs_write_prev_ = writes; setUsed(fields_[0] + fields_[1], total_); IntervalTimerStart(); } // XXX: sysfs - read Documentation/iostats.txt !!! // extract stats from /sys/block/*/stat // each disk reports an unsigned long, which can WRAP around void DiskMeter::getsysfsdiskinfo( void ) { // field-3: sects read since boot (but can wrap!) // field-7: sects written since boot (but can wrap!) // just sum up everything in /sys/block/*/stat std::string sysfs_dir = _statFileName; std::string disk, tmp; std::ifstream diskstat; struct stat buf; char line[128]; unsigned long vals[7]; diskmap reads, writes; IntervalTimerStop(); total_ = maxspeed_; sysfs_dir += '/'; DIR *dir = opendir(_statFileName); if (dir == NULL) { XOSDEBUG("sysfs: Cannot open directory : %s\n", _statFileName); return; } // visit every /sys/block/*/stat and sum up the values: for (struct dirent *dirent; (dirent = readdir(dir)) != NULL; ) { if (strncmp(dirent->d_name, ".", 1) == 0 || strncmp(dirent->d_name, "..", 2) == 0 || strncmp(dirent->d_name, "loop", 4) == 0 || strncmp(dirent->d_name, "ram", 3) == 0) continue; disk = sysfs_dir + dirent->d_name; if (stat(disk.c_str(), &buf) == 0 && buf.st_mode & S_IFDIR) { // only scan for real HW (raid, md, and lvm all mapped on them) tmp = disk + "/device"; if (lstat(tmp.c_str(), &buf) != 0 || (buf.st_mode & S_IFLNK) == 0) continue; // is a dir, locate 'stat' file in it disk += "/stat"; diskstat.open(disk.c_str()); if (diskstat.good()) { diskstat.getline(line, 128); char *cur = line, *end = NULL; for (int i = 0; i < 7; i++) { vals[i] = strtoul(cur, &end, 10); cur = end; } reads[dirent->d_name] = vals[2]; writes[dirent->d_name] = vals[6]; XOSDEBUG("disk stat: %s | read: %lu, written: %lu\n", disk.c_str(), vals[2], vals[6]); diskstat.close(); diskstat.clear(); } else XOSDEBUG("disk stat open: %s - errno=%d\n", disk.c_str(), errno); } else XOSDEBUG("disk is not dir: %s - errno=%d\n", disk.c_str(), errno); } // for closedir(dir); update_info(reads, writes); } xosview-1.20/linux/diskmeter.h000066400000000000000000000022311317735352700164520ustar00rootroot00000000000000// // Copyright (c) 1999, 2006 by Mike Romberg (mike.romberg@noaa.gov) // // This file may be distributed under terms of the GPL // #ifndef _DISKMETER_H_ #define _DISKMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include #include typedef std::map diskmap; class DiskMeter : public FieldMeterGraph { public: DiskMeter( XOSView *parent, float max ); ~DiskMeter( void ); const char *name( void ) const { return "DiskMeter"; } void checkevent( void ); void checkResources( void ); protected: // sysfs: void update_info(const diskmap &reads, const diskmap &writes); void getsysfsdiskinfo( void ); void getdiskinfo( void ); void getvmdiskinfo( void ); void updateinfo(unsigned long one, unsigned long two, int fudgeFactor); private: // sysfs: diskmap sysfs_read_prev_, sysfs_write_prev_; bool _sysfs; unsigned long int read_prev_; unsigned long int write_prev_; float maxspeed_; bool _vmstat; const char *_statFileName; }; #endif xosview-1.20/linux/intmeter.cc000066400000000000000000000113161317735352700164540ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "intmeter.h" #include #include #include #include #include #include static const char *INTFILE = "/proc/interrupts"; static std::map realintnum; static const int max = 1024; IntMeter::IntMeter( XOSView *parent, int cpu ) : BitMeter( parent, "INTS", "", 1, 0, 0 ), _cpu(cpu) { _irqs = _lastirqs = NULL; initirqcount(); } IntMeter::~IntMeter( void ){ if (_irqs) delete[] _irqs; if (_lastirqs) delete[] _lastirqs; } void IntMeter::checkevent( void ){ getirqs(); for ( int i = 0 ; i < numBits() ; i++ ){ bits_[i] = ((_irqs[i] - _lastirqs[i]) != 0); _lastirqs[i] = _irqs[i]; } BitMeter::checkevent(); } void IntMeter::checkResources( void ){ BitMeter::checkResources(); onColor_ = parent_->allocColor( parent_->getResource( "intOnColor" ) ); offColor_ = parent_->allocColor( parent_->getResource( "intOffColor" ) ); priority_ = atoi( parent_->getResource( "intPriority" ) ); _separate = parent_->isResourceTrue( "intSeparate" ); } void IntMeter::getirqs( void ){ std::ifstream intfile( INTFILE ); std::string line; int intno, idx, i; unsigned long count, tmp; char *end = NULL; if ( !intfile ){ std::cerr <<"Can not open file : " < line.find_first_of(':') ) break; // reached non-numeric interrupts idx = strtoul(line.c_str(), &end, 10); if (idx >= max) break; intno = realintnum[idx]; if ( intno >= numBits() ) updateirqcount(intno, false); const char *cur = end + 1; count = tmp = i = 0; while (*cur && i++ <= _cpu) { tmp = strtoul(cur, &end, 10); count += tmp; cur = end; } _irqs[intno] = ( _separate ? tmp : count ); } } /* The highest numbered interrupts, the number of interrupts * is going to be at least +1 (for int 0) and probably higher * if interrupts numbered more than this one just aren't active. * Must call with init = true the first time. */ void IntMeter::updateirqcount( int n, bool init ){ int old_bits = numBits(); setNumBits(n + 1); std::ostringstream os; os << "0"; if (realintnum.upper_bound(15) == realintnum.end()) // only 16 ints os << "-15"; else { int prev = 15, prev2 = 14; for (std::map::const_iterator it = realintnum.upper_bound(15), end = realintnum.end(); it != end; ++it) { if ( &*it == &*realintnum.rbegin() ) { // last element if ( it->first == prev + 1 ) os << "-" ; else { if ( prev == prev2 + 1 ) os << "-" << prev; os << "," ; } os << it->first; } else { if ( it->first != prev + 1 ) { if ( prev == prev2 + 1 ) os << "-" << prev; os << "," << it->first ; } } prev2 = prev; prev = it->first; } os << std::ends; } legend(os.str().c_str()); unsigned long *old_irqs = _irqs, *old_lastirqs = _lastirqs; _irqs = new unsigned long[n+1]; _lastirqs = new unsigned long[n+1]; /* If we are in init, set it to zero, * otherwise copy over the old set */ if (init) { for (int i = 0; i < numBits(); i++) _irqs[i] = _lastirqs[i] = 0; } else { for (int i = 0; i < old_bits; i++) { _irqs[i] = old_irqs[i]; _lastirqs[i] = old_lastirqs[i]; } // zero to the end the irq's that haven't been seen before for (int i = old_bits; i < numBits(); i++) _irqs[i] = _lastirqs[i] = 0; } if (old_irqs) delete[] old_irqs; if (old_lastirqs) delete[] old_lastirqs; } /* Find the highest number of interrupts and call updateirqcount to * update the number of interrupts listed */ void IntMeter::initirqcount( void ){ std::ifstream intfile( INTFILE ); int intno = 0; int i, idx; if ( !intfile ){ std::cerr <<"Can not open file : " <> i; /* break when reaching non-numeric special interrupts */ if (!intfile) break; if (i < 16) intno = i; else { intno = idx; realintnum[i] = idx++; } intfile.ignore(max, '\n'); } updateirqcount(intno, true); } xosview-1.20/linux/intmeter.h000066400000000000000000000012351317735352700163150ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _INTMETER_H_ #define _INTMETER_H_ #include "bitmeter.h" #include "xosview.h" #include "cpumeter.h" class IntMeter : public BitMeter { public: IntMeter( XOSView *parent, int cpu = 0 ); ~IntMeter( void ); void checkevent( void ); void checkResources( void ); static int countCPUs( void ) { return CPUMeter::countCPUs(); } private: unsigned long *_irqs, *_lastirqs; int _cpu; bool _separate; void getirqs( void ); void updateirqcount( int n, bool init ); void initirqcount( void ); }; #endif xosview-1.20/linux/intratemeter.cc000066400000000000000000000044401317735352700173300ustar00rootroot00000000000000// // Copyright (c) 2014 by Tomi Tapper (tomi.o.tapper@jyu.fi) // // Based on bsd/intratemeter.* by // Copyright (c) 1999 by Brian Grayson (bgrayson@netbsd.org) // and on linux/intmeter.* by // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "intratemeter.h" #include "cpumeter.h" #include #include #include #include static const char *INTFILE = "/proc/interrupts"; IrqRateMeter::IrqRateMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "IRQs", "IRQs per sec/IDLE", 1, 1, 0 ) { _lastirqs = 0; _cpucount = CPUMeter::countCPUs(); } IrqRateMeter::~IrqRateMeter( void ) { } void IrqRateMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("irqrateUsedColor") ); setfieldcolor( 1, parent_->getResource("irqrateIdleColor") ); priority_ = atoi( parent_->getResource("irqratePriority") ); dodecay_ = parent_->isResourceTrue("irqrateDecay"); useGraph_ = parent_->isResourceTrue("irqrateGraph"); SetUsedFormat( parent_->getResource("irqrateUsedFormat") ); total_ = 2000; } void IrqRateMeter::checkevent( void ) { getinfo(); drawfields(); } void IrqRateMeter::getinfo( void ) { std::ifstream intfile(INTFILE); std::string line; unsigned long long count = 0; unsigned long tmp; const char *cur = NULL; char *end = NULL; if (!intfile) { std::cerr << "Can not open file : " << INTFILE << std::endl; parent_->done(1); return; } IntervalTimerStop(); intfile.ignore(1024, '\n'); // sum all interrupts on all cpus while ( !intfile.eof() ) { unsigned int i = 0; std::getline(intfile, line); if ( line.find_first_of("0123456789") > line.find_first_of(':') ) break; // reached non-numeric interrupts tmp = strtoul(line.c_str(), &end, 10); cur = end + 1; while (*cur && i++ < _cpucount) { tmp = strtoul(cur, &end, 10); count += tmp; cur = end; } } if (_lastirqs == 0) // first run _lastirqs = count; fields_[0] = (count - _lastirqs) / IntervalTimeInSecs(); IntervalTimerStart(); _lastirqs = count; // Bump total, if needed. if (fields_[0] > total_) total_ = fields_[0]; setUsed(fields_[0], total_); } xosview-1.20/linux/intratemeter.h000066400000000000000000000014271317735352700171740ustar00rootroot00000000000000// // Copyright (c) 2014 by Tomi Tapper (tomi.o.tapper@jyu.fi) // // Based on bsd/intratemeter.* by // Copyright (c) 1999 by Brian Grayson (bgrayson@netbsd.org) // and on linux/intmeter.* by // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _IRQRATEMETER_H_ #define _IRQRATEMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class IrqRateMeter : public FieldMeterGraph { public: IrqRateMeter( XOSView *parent ); ~IrqRateMeter( void ); const char *name( void ) const { return "IrqRateMeter"; } void checkevent( void ); void checkResources( void ); protected: void getinfo( void ); private: unsigned long long _lastirqs; unsigned int _cpucount; }; #endif xosview-1.20/linux/lmstemp.cc000066400000000000000000000276501317735352700163160ustar00rootroot00000000000000// // Copyright (c) 2000, 2006 by Leopold Toetsch // // Read temperature entries from /proc/sys/dev/sensors/*/* // and display actual and high temperature // if actual >= high, actual temp changes color to indicate alarm // // File based on btrymeter.* by // Copyright (c) 1997 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // // // #include "lmstemp.h" #include #include #include #include #include #include #include #include #include #include static const char PROC_SENSORS[] = "/proc/sys/dev/sensors"; static const char SYS_SENSORS[] = "/sys/class/hwmon"; LmsTemp::LmsTemp( XOSView *parent, const char *name, const char *tempfile, const char *highfile, const char *lowfile, const char *label, const char *caption, unsigned int nbr ) : SensorFieldMeter( parent, label, caption, 1, 1, 0 ){ _nbr = nbr; _scale = 1.0; _isproc = _name_found = _temp_found = _high_found = _low_found = false; // Check if high is given as value if ( highfile && sscanf(highfile, "%lf", &high_) > 0 ) { has_high_ = _high_found = true; highfile = NULL; } // Check if low is given as value if ( lowfile && sscanf(lowfile, "%lf", &low_) > 0 ) { has_low_ = _low_found = true; lowfile = NULL; } if ( !checksensors(name, tempfile, highfile, lowfile) ) { if ( !_name_found && (( !_temp_found && tempfile[0] != '/' ) || ( !_high_found && (highfile && highfile[0] != '/') ) || ( !_low_found && (lowfile && lowfile[0] != '/') )) ) std::cerr << label << " : No sensor named " << name << " was found in " << SYS_SENSORS << "." << std::endl; else { if (!_temp_found && tempfile[0] != '/') { std::cerr << label << " : Could not find file " << tempfile << "{,_input}"; if (name) std::cerr << " under " << name << " in " << SYS_SENSORS; else std::cerr << " under " << PROC_SENSORS << " or " << SYS_SENSORS; std::cerr << "." << std::endl; } if (!_high_found && highfile && highfile[0] != '/') { std::cerr << label << " : Could not find file " << highfile; if (name) std::cerr << " under " << name << " in " << SYS_SENSORS; else std::cerr << " under " << SYS_SENSORS; std::cerr << "." << std::endl; } if (!_low_found && lowfile && lowfile[0] != '/') { std::cerr << label << " : Could not find file " << lowfile; if (name) std::cerr << " under " << name << " in " << SYS_SENSORS; else std::cerr << " under " << SYS_SENSORS; std::cerr << "." << std::endl; } } parent_->done(1); } } LmsTemp::~LmsTemp( void ){ } bool LmsTemp::checksensors( const char *name, const char *tempfile, const char *highfile, const char *lowfile ) { // Logic: // 0) tempfile must always be found, highfile and lowfile only if given // 1) absolute path in any filename must match as is // 2) if name is given, only files in that sysfs node can match // 3) any filename matches as is // 4) tempfile + "_input" matches and tempfile + "_max" and/or // tempfile + "_min" matches DIR *dir; struct dirent *ent; struct stat buf; std::string dirname, f, f2, n; /* First, check if absolute paths were given. */ if (tempfile[0] == '/') { if ( stat(tempfile, &buf) == 0 && S_ISREG(buf.st_mode) ) { _tempfile = tempfile; _temp_found = true; } else std::cerr << title() << " : Could not find file " << tempfile << "." << std::endl; } if (highfile && highfile[0] == '/') { if ( stat(highfile, &buf) == 0 && S_ISREG(buf.st_mode) ) { _highfile = highfile; _high_found = true; } else std::cerr << title() << " : Could not find file " << highfile << "." << std::endl; } if (lowfile && lowfile[0] == '/') { if ( stat(lowfile, &buf) == 0 && S_ISREG(buf.st_mode) ) { _lowfile = lowfile; _low_found = true; } else std::cerr << title() << " : Could not find file " << lowfile << "." << std::endl; } if ( _temp_found && (_high_found || !highfile) && (_low_found || !lowfile) ) { _isproc = ( strncmp(_tempfile.c_str(), "/proc", 5) ? false : true ); return true; } /* Then, try to find the given file. */ /* Try /proc first. */ if ( (dir = opendir(PROC_SENSORS)) ) { while ( !_temp_found && (ent = readdir(dir)) ) { if ( !strncmp(ent->d_name, ".", 1) || !strncmp(ent->d_name, "..", 2) ) continue; dirname = PROC_SENSORS; dirname += '/'; dirname += ent->d_name; if ( stat(dirname.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode) ) { f = dirname + '/' + tempfile; if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _temp_found = true; _tempfile = f; _isproc = true; } } } closedir(dir); if (_temp_found) return true; } /* Next, try /sys. */ if ( !(dir = opendir(SYS_SENSORS)) ) return false; while ( !(_temp_found && (_high_found || !highfile) && (_low_found || !lowfile) ) && (ent = readdir(dir)) ) { if ( !strncmp(ent->d_name, ".", 1) || !strncmp(ent->d_name, "..", 2) ) continue; // Try every node under /sys/class/hwmon dirname = SYS_SENSORS; dirname += '/'; dirname += ent->d_name; int i = 0; do { if ( stat(dirname.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode) ) { // Try to get the sensor's name f = dirname + "/name"; std::ifstream namefile( f.c_str() ); if ( namefile.good() ) { namefile >> n; namefile.close(); } if (!name || n == name) { // Either no name was given, or the name matches. // Check if the files exist here. _name_found = true; if (highfile && !_high_found) { f = dirname + '/' + highfile; if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _high_found = true; _highfile = f; } } if (lowfile && !_low_found) { f = dirname + '/' + lowfile; if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _low_found = true; _lowfile = f; } } f = dirname + '/' + tempfile; if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _temp_found = true; _tempfile = f; } else { f2 = f + "_input"; if ( stat(f2.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _temp_found = true; _tempfile = f2; f2 = f + "_max"; if ( !_high_found && !highfile && stat(f2.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _high_found = true; _highfile = f2; } f2 = f + "_min"; if ( !_low_found && !lowfile && stat(f2.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) { _low_found = true; _lowfile = f2; } } } } } // Some /sys sensors have the files in subdirectory /device dirname += "/device"; } while ( ++i < 2 && !( _temp_found && (_high_found || !highfile) && (_low_found || !lowfile) ) ); } closedir(dir); // No highfile or lowfile is OK. if (!highfile) _high_found = true; if (!lowfile) _low_found = true; return (_temp_found & _high_found & _low_found); } /* Adapted from libsensors. */ void LmsTemp::determineScale( void ){ char type[16], subtype[32]; int n; std::string basename = _tempfile.substr(_tempfile.find_last_of('/') + 1); if ( sscanf(basename.c_str(), "%[a-z]%d_%s", type, &n, subtype) == 3 ) { if (( !strncmp(type, "in", strlen(type)) && !strncmp(subtype, "input", strlen(subtype)) ) || ( !strncmp(type, "temp", strlen(type)) && !strncmp(subtype, "input", strlen(subtype)) ) || ( !strncmp(type, "temp", strlen(type)) && !strncmp(subtype, "offset", strlen(subtype)) ) || ( !strncmp(type, "curr", strlen(type)) && !strncmp(subtype, "input", strlen(subtype)) ) || ( !strncmp(type, "power", strlen(type)) && !strncmp(subtype, "average_interval", strlen(subtype)) ) || ( !strncmp(type, "cpu", strlen(type)) && !strncmp(subtype, "vid", strlen(subtype)) )) { _scale = 1000.0; return; } if (( !strncmp(type, "power", strlen(type)) && !strncmp(subtype, "average", strlen(subtype)) ) || ( !strncmp(type, "energy", strlen(type)) && !strncmp(subtype, "input", strlen(subtype)) )) { _scale = 1000000.0; return; } } _scale = 1.0; } void LmsTemp::determineUnit( void ){ char type[16], subtype[32]; int n; std::string basename = _tempfile.substr(_tempfile.find_last_of('/') + 1); if ( sscanf(basename.c_str(), "%[a-z]%d_%s", type, &n, subtype) == 3 ) { if ( !strncmp(type, "temp", strlen(type)) ) strcpy(unit_, "\260C"); else if ( !strncmp(type, "in", strlen(type)) || !strncmp(subtype, "vid", strlen(type)) ) strcpy(unit_, "V"); else if ( !strncmp(type, "fan", strlen(type)) ) strcpy(unit_, "RPM"); else if ( !strncmp(type, "power", strlen(type)) ) { if ( strncmp(subtype, "average_interval", strlen(type)) ) strcpy(unit_, "s"); else strcpy(unit_, "W"); } else if ( !strncmp(type, "energy", strlen(type)) ) strcpy(unit_, "J"); else if ( !strncmp(type, "curr", strlen(type)) ) strcpy(unit_, "A"); else if ( !strncmp(type, "humidity", strlen(type)) ) strcpy(unit_, "%"); } } void LmsTemp::checkResources( void ){ SensorFieldMeter::checkResources(); char s[32]; const char *tmp = NULL; actcolor_ = parent_->allocColor( parent_->getResource( "lmstempActColor" ) ); highcolor_ = parent_->allocColor( parent_->getResource( "lmstempHighColor" ) ); lowcolor_ = parent_->allocColor( parent_->getResource( "lmstempLowColor" ) ); setfieldcolor( 0, actcolor_ ); setfieldcolor( 1, parent_->getResource( "lmstempIdleColor") ); setfieldcolor( 2, highcolor_ ); tmp = parent_->getResourceOrUseDefault( "lmstempHighest", "0" ); snprintf(s, 32, "lmstempHighest%d", _nbr); total_ = fabs( atof( parent_->getResourceOrUseDefault(s, tmp) ) ); priority_ = atoi( parent_->getResource( "lmstempPriority" ) ); tmp = parent_->getResource( "lmstempUsedFormat" ); snprintf(s, 32, "lmstempUsedFormat%d", _nbr); SetUsedFormat( parent_->getResourceOrUseDefault(s, tmp) ); if ( !_highfile.empty() ) has_high_ = true; if ( !_lowfile.empty() ) has_low_ = true; if (!has_high_) high_ = total_; if (!has_low_) low_ = 0; determineScale(); determineUnit(); updateLegend(); } void LmsTemp::checkevent( void ){ getlmstemp(); drawfields(); } void LmsTemp::getlmstemp( void ){ double high = high_, low = low_; std::ifstream tempfile( _tempfile.c_str() ); if (!tempfile) { std::cerr << "Can not open file : " << _tempfile << std::endl; parent_->done(1); return; } if (_isproc) tempfile >> high >> low >> fields_[0]; else { tempfile >> fields_[0]; fields_[0] /= _scale; if ( !_highfile.empty() ) { std::ifstream highfile( _highfile.c_str() ); if (!highfile) { std::cerr << "Can not open file : " << _highfile << std::endl; parent_->done(1); return; } highfile >> high; high /= _scale; } if ( !_lowfile.empty() ) { std::ifstream lowfile( _lowfile.c_str() ); if (!lowfile) { std::cerr << "Can not open file : " << _lowfile << std::endl; parent_->done(1); return; } lowfile >> low; low /= _scale; } } checkFields(low, high); } xosview-1.20/linux/lmstemp.h000066400000000000000000000021441317735352700161470ustar00rootroot00000000000000// // Copyright (c) 2000, 2006 by Leopold Toetsch // // File based on btrymeter.* by // Copyright (c) 1997 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // // // #ifndef _LMSTEMP_H_ #define _LMSTEMP_H_ #include "sensorfieldmeter.h" #include "xosview.h" #include class LmsTemp : public SensorFieldMeter { public: LmsTemp( XOSView *parent, const char *name, const char *tempfile, const char *highfile, const char *lowfile, const char *label, const char *caption, unsigned int nbr ); ~LmsTemp( void ); const char *name( void ) const { return "LmsTemp"; } void checkevent( void ); void checkResources( void ); protected: void getlmstemp( void ); bool checksensors( const char *name, const char *tempfile, const char *highfile, const char *lowfile ); private: void determineScale( void ); void determineUnit( void ); std::string _tempfile, _highfile, _lowfile; unsigned int _nbr; double _scale; bool _isproc, _name_found, _temp_found, _high_found, _low_found; }; #endif xosview-1.20/linux/loadmeter.cc000066400000000000000000000107711317735352700166050ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006, 2008 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // // Most of this code was written by Werner Fink . // Only small changes were made on my part (M.R.) // #include "loadmeter.h" #include "cpumeter.h" #include #include #include #include #include #include static const char LOADFILENAME[] = "/proc/loadavg"; static const char SPEEDFILENAME[] = "/proc/cpuinfo"; LoadMeter::LoadMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "LOAD", "PROCS/MIN", 1, 1, 0 ){ lastalarmstate = -1; total_ = 2.0; old_cpu_speed_= cur_cpu_speed_=0; do_cpu_speed = 0; } LoadMeter::~LoadMeter( void ){ } void LoadMeter::checkResources( void ){ FieldMeterGraph::checkResources(); procloadcol_ = parent_->allocColor(parent_->getResource( "loadProcColor" )); warnloadcol_ = parent_->allocColor(parent_->getResource( "loadWarnColor" )); critloadcol_ = parent_->allocColor(parent_->getResource( "loadCritColor" )); setfieldcolor( 0, procloadcol_ ); setfieldcolor( 1, parent_->getResource( "loadIdleColor" ) ); priority_ = atoi (parent_->getResource( "loadPriority" ) ); useGraph_ = parent_->isResourceTrue( "loadGraph" ); dodecay_ = parent_->isResourceTrue( "loadDecay" ); SetUsedFormat (parent_->getResource("loadUsedFormat")); const char *warn = parent_->getResource("loadWarnThreshold"); if (strncmp(warn, "auto", 2) == 0) { warnThreshold = CPUMeter::countCPUs(); } else { warnThreshold = atoi(warn); } const char *crit = parent_->getResource("loadCritThreshold"); if (strncmp(crit, "auto", 2) == 0) { critThreshold = warnThreshold * 4; } else { critThreshold = atoi(crit); } do_cpu_speed = parent_->isResourceTrue( "loadCpuSpeed" ); if (dodecay_){ // Warning: Since the loadmeter changes scale occasionally, old // decay values need to be rescaled. However, if they are rescaled, // they could go off the edge of the screen. Thus, for now, to // prevent this whole problem, the load meter can not be a decay // meter. The load is a decaying average kind of thing anyway, // so having a decaying load average is redundant. std::cerr << "Warning: The loadmeter can not be configured as a decay\n" << " meter. See the source code (" << __FILE__ << ") for further\n" << " details.\n"; dodecay_ = 0; } } void LoadMeter::checkevent( void ){ getloadinfo(); if ( do_cpu_speed ) { getspeedinfo(); if ( old_cpu_speed_ != cur_cpu_speed_ ) { // update the legend: char l[32]; snprintf(l, 32, "PROCS/MIN %d MHz", cur_cpu_speed_); legend(l); drawlegend(); } } drawfields(); } void LoadMeter::getloadinfo( void ){ std::ifstream loadinfo( LOADFILENAME ); if ( !loadinfo ){ std::cerr <<"Can not open file : " <done(1); return; } loadinfo >> fields_[0]; if ( fields_[0] < warnThreshold ) alarmstate = 0; else if ( fields_[0] >= critThreshold ) alarmstate = 2; else /* if fields_[0] >= warnThreshold */ alarmstate = 1; if ( alarmstate != lastalarmstate ){ if ( alarmstate == 0 ) setfieldcolor( 0, procloadcol_ ); else if ( alarmstate == 1 ) setfieldcolor( 0, warnloadcol_ ); else /* if alarmstate == 2 */ setfieldcolor( 0, critloadcol_ ); drawlegend(); lastalarmstate = alarmstate; } // Adjust total to next power-of-two of the current load. if ( (fields_[0]*5.0 < total_ && total_ > 1.0) || fields_[0] > total_ ) { unsigned int i = fields_[0]; i |= i >> 1; i |= i >> 2; i |= i >> 4; i |= i >> 8; i |= i >> 16; // i = 2^n - 1 total_ = i + 1; } fields_[1] = (float) (total_ - fields_[0]); setUsed(fields_[0], (float) 1.0); } // just check /proc/cpuinfo for the speed of cpu // (average multi-cpus on different speeds) // (yes - i know about devices/system/cpu/cpu*/cpufreq ) void LoadMeter::getspeedinfo( void ){ std::ifstream speedinfo(SPEEDFILENAME); std::string line, val; unsigned int total_cpu = 0, ncpus = 0; while ( speedinfo.good() ) { std::getline(speedinfo, line); if ( strncmp(line.c_str(), "cpu MHz", 7) == 0 ) { val = line.substr(line.find_last_of(':') + 1); XOSDEBUG("SPEED: %s\n", val.c_str()); total_cpu += atoi(val.c_str()); ncpus++; } } old_cpu_speed_ = cur_cpu_speed_; if (ncpus > 0) cur_cpu_speed_ = total_cpu / ncpus; else cur_cpu_speed_ = 0; } xosview-1.20/linux/loadmeter.h000066400000000000000000000015301317735352700164400ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // // Most of this code was written by Werner Fink // Only small changes were made on my part (M.R.) // #ifndef _LOADMETER_H_ #define _LOADMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class LoadMeter : public FieldMeterGraph { public: LoadMeter( XOSView *parent ); ~LoadMeter( void ); const char *name( void ) const { return "LoadMeter"; } void checkevent( void ); void checkResources( void ); protected: void getloadinfo( void ); unsigned long procloadcol_, warnloadcol_, critloadcol_; void getspeedinfo( void ); private: int warnThreshold, critThreshold, alarmstate, lastalarmstate; int old_cpu_speed_, cur_cpu_speed_; int do_cpu_speed; }; #endif xosview-1.20/linux/memmeter.cc000066400000000000000000000060441317735352700164420ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // Copyright (c) 2015 Framestore // // This file may be distributed under terms of the GPL // #include "memmeter.h" #include #include #include #include #define MEMFILENAME "/proc/meminfo" #define KB(x) ((double)((x) * 1024)) MemMeter::MemMeter( XOSView *parent ) : FieldMeterGraph( parent, 5, "MEM", "USED/BUFF/SLAB/CACHE/FREE" ){ } void MemMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "memUsedColor" ) ); setfieldcolor( 1, parent_->getResource( "memBufferColor" ) ); setfieldcolor( 2, parent_->getResource( "memSlabColor" ) ); setfieldcolor( 3, parent_->getResource( "memCacheColor" ) ); setfieldcolor( 4, parent_->getResource( "memFreeColor" ) ); priority_ = atoi (parent_->getResource( "memPriority" ) ); dodecay_ = parent_->isResourceTrue( "memDecay" ); useGraph_ = parent_->isResourceTrue( "memGraph" ); SetUsedFormat (parent_->getResource("memUsedFormat")); } void MemMeter::checkevent( void ){ getstats(); drawfields(); } void MemMeter::getstats() { FILE *f; f = fopen(MEMFILENAME, "r"); if (!f) { perror(MEMFILENAME); exit(1); } /* * The kernel's "unsigned long" values vary in size on 64-bit and * 32-bit implementations. * * But there's nothing saying userland will match the kernel; we * must pretty much accomodate anything in ASCII that /proc gives * us, so 64-bit integers are always used. */ unsigned long long mem_total = 0, mem_free = 0, buffers = 0, slab = 0, cached = 0; for (;;) { char line[128]; char *c, *endptr; unsigned long long kb = 0; /* * Parse lines in the format: "FieldName: 12345678 kB" * * We prefer to not use scanf because it's harder with variable * number of fields; the 'kB' is not present if value is 0 */ if (!fgets(line, sizeof line, f)) break; c = strchr(line, ':'); if (!c) { fprintf(stderr, MEMFILENAME ": parse error, ':' expected at '%s'\n", line); exit(1); } *c = '\0'; c++; kb = strtoull(c, &endptr, 10); if (kb == ULLONG_MAX) { fprintf(stderr, MEMFILENAME ": parse error, '%s' is out of range\n", c); exit(1); } if (strcmp(line, "MemTotal") == 0) mem_total = kb; else if (strcmp(line, "MemFree") == 0) mem_free = kb; else if (strcmp(line, "Buffers") == 0) buffers = kb; else if (strcmp(line, "Cached") == 0) cached = kb; else if (strcmp(line, "Slab") == 0) slab = kb; } if (fclose(f) != 0) abort(); /* Don't do arithmetic on the fields_ themselves; these are floating * point and when memory is large are affected by inaccuracy */ fields_[1] = KB(buffers); fields_[2] = KB(slab); fields_[3] = KB(cached); fields_[4] = KB(mem_free); fields_[0] = KB(mem_total - mem_free - buffers - cached - slab); total_ = KB(mem_total); setUsed(KB(mem_total - mem_free), KB(mem_total)); } xosview-1.20/linux/memmeter.h000066400000000000000000000007651317735352700163100ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _MEMMETER_H_ #define _MEMMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include class MemMeter : public FieldMeterGraph { public: MemMeter( XOSView *parent ); const char *name( void ) const { return "MemMeter"; } void checkevent( void ); void checkResources( void ); private: void getstats( void ); }; #endif xosview-1.20/linux/netmeter.cc000066400000000000000000000116141317735352700164510ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // Modifications to support dynamic addresses by: // Michael N. Lipp (mnl@dtro.e-technik.th-darmstadt.de) // // This file may be distributed under terms of the GPL // #include "netmeter.h" #include #include #include #include #include #include #include #include static const char PROCNETDEV[] = "/proc/net/dev"; static const char SYSCLASSNET[] = "/sys/class/net"; /* * Parse the integer count from the given filename * * This is quite relaxed about error conditions because the file may * have been removed before it was opened, or truncated, in which case * the count is zero. * * Return: 0 if not not avilable, otherwise count (which may be zero) */ static unsigned long long getCount( const char *filename ){ unsigned long long n, count = 0; FILE *f; f = fopen(filename, "r"); if (!f) return 0; if (fscanf(f, "%llu", &n) == 1) count = n; if (fclose(f) != 0) abort(); return count; } NetMeter::NetMeter( XOSView *parent, float max ) : FieldMeterGraph( parent, 3, "NET", "IN/OUT/IDLE" ){ _maxpackets = max; _lastBytesIn = _lastBytesOut = 0; _usesysfs = _ignored = false; struct stat buf; if ( stat(SYSCLASSNET, &buf) == 0 && S_ISDIR(buf.st_mode) ) _usesysfs = true; } NetMeter::~NetMeter( void ){ } void NetMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "netInColor" ) ); setfieldcolor( 1, parent_->getResource( "netOutColor" ) ); setfieldcolor( 2, parent_->getResource( "netBackground" ) ); priority_ = atoi( parent_->getResource( "netPriority" ) ); useGraph_ = parent_->isResourceTrue( "netGraph" ); dodecay_ = parent_->isResourceTrue( "netDecay" ); SetUsedFormat( parent_->getResource("netUsedFormat") ); _netIface = parent_->getResource( "netIface" ); if (_netIface[0] == '-') { _ignored = true; _netIface.erase(0, _netIface.find_first_not_of("- ")); } } void NetMeter::checkevent( void ){ unsigned long long totin = 0, totout = 0; fields_[2] = _maxpackets; // assume no fields_[0] = fields_[1] = 0; // network activity IntervalTimerStop(); if (_usesysfs) getSysStats(totin, totout); else getProcStats(totin, totout); double t = IntervalTimeInSecs(); IntervalTimerStart(); if (_lastBytesIn == 0 && _lastBytesOut == 0) { // first run _lastBytesIn = totin; _lastBytesOut = totout; } fields_[0] = (totin - _lastBytesIn) / t; fields_[1] = (totout - _lastBytesOut) / t; _lastBytesIn = totin; _lastBytesOut = totout; total_ = fields_[0] + fields_[1]; if (total_ > _maxpackets) fields_[2] = 0; else { total_ = _maxpackets; fields_[2] = total_ - fields_[0] - fields_[1]; } setUsed(fields_[0] + fields_[1], total_); drawfields(); } void NetMeter::getSysStats( unsigned long long &totin, unsigned long long &totout ){ DIR *dir; struct dirent *ent; char filename[128]; std::ifstream ifs; if ( !(dir = opendir(SYSCLASSNET)) ) { std::cerr << "Can not open directory : " << SYSCLASSNET << std::endl; parent_->done(1); return; } // walk through /sys/class/net/*/statistics/{r,t}x_bytes while ( (ent = readdir(dir)) ) { if ( ent->d_type != DT_LNK ) continue; if ( _netIface != "False" && ( (!_ignored && ent->d_name != _netIface) || ( _ignored && ent->d_name == _netIface) ) ) continue; snprintf(filename, 128, "%s/%s/statistics/rx_bytes", SYSCLASSNET, ent->d_name); totin += getCount(filename); snprintf(filename, 128, "%s/%s/statistics/tx_bytes", SYSCLASSNET, ent->d_name); totout += getCount(filename); } closedir(dir); } void NetMeter::getProcStats( unsigned long long &totin, unsigned long long &totout ){ std::ifstream ifs(PROCNETDEV); std::string line, ifname; if (!ifs) { std::cerr << "Can not open file : " << PROCNETDEV << std::endl; parent_->done(1); return; } ifs.ignore(1024, '\n'); ifs.ignore(1024, '\n'); while ( !ifs.eof() ) { unsigned long long vals[9]; std::getline(ifs, line); if ( !ifs.good() ) break; int colon = line.find_first_of(':'); ifname = line.substr(0, colon); ifname.erase(0, ifname.find_first_not_of(' ')); if (_netIface != "False") { if ( (!_ignored && ifname != _netIface) || ( _ignored && ifname == _netIface) ) continue; } std::string l = line.erase(0, colon + 1); const char *cur = l.c_str(); if ( strncmp(cur, " No ", 4) == 0 ) continue; // xxx: No statistics available. char *end = NULL; for (int i = 0; i < 9; i++) { vals[i] = strtoull(cur, &end, 10); cur = end; } totin += vals[0]; totout += vals[8]; XOSDEBUG("%s: %llu bytes received, %llu bytes sent.\n", ifname.c_str(), vals[0], vals[8]); } } xosview-1.20/linux/netmeter.h000066400000000000000000000014171317735352700163130ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _NETMETER_H_ #define _NETMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include class NetMeter : public FieldMeterGraph { public: NetMeter(XOSView *parent, float max); ~NetMeter( void ); const char *name( void ) const { return "NetMeter"; } void checkevent( void ); void checkResources( void ); private: void getProcStats( unsigned long long &totin, unsigned long long &totout ); void getSysStats( unsigned long long &totin, unsigned long long &totout ); float _maxpackets; std::string _netIface; bool _usesysfs, _ignored; unsigned long long _lastBytesIn, _lastBytesOut; }; #endif xosview-1.20/linux/nfsmeter.cc000066400000000000000000000121371317735352700164520ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // Modifications to support dynamic addresses by: // Michael N. Lipp (mnl@dtro.e-technik.th-darmstadt.de) // // This file may be distributed under terms of the GPL // #include "nfsmeter.h" #include #include #include // #include #ifndef MAX #define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) #endif static const char *NFSSVCSTAT = "/proc/net/rpc/nfsd"; static const char * NFSCLTSTAT = "/proc/net/rpc/nfs"; NFSMeter::NFSMeter(XOSView *parent, const char *name, int nfields, const char *fields, const char *statfile) : FieldMeterGraph( parent, nfields, name, fields ){ _statfile = statfile; _statname = name; } NFSMeter::~NFSMeter( void ){ } void NFSMeter::checkResources( void ){ FieldMeterGraph::checkResources(); } NFSDStats::NFSDStats(XOSView *parent) : NFSMeter(parent, "NFSD", 4, "BAD/UDP/TCP/IDLE", NFSSVCSTAT ){ starttimer(); } NFSDStats::~NFSDStats( void ) { } void NFSDStats::checkResources( void ){ NFSMeter::checkResources(); setfieldcolor( 0, parent_->getResource( "NFSDStatBadCallsColor" ) ); setfieldcolor( 1, parent_->getResource( "NFSDStatUDPColor" ) ); setfieldcolor( 2, parent_->getResource( "NFSDStatTCPColor" ) ); setfieldcolor( 3, parent_->getResource( "NFSDStatIdleColor" ) ); useGraph_ = parent_->isResourceTrue( "NFSDStatGraph" ); dodecay_ = parent_->isResourceTrue( "NFSDStatDecay" ); SetUsedFormat (parent_->getResource("NFSDStatUsedFormat")); //useGraph_ = 1; //dodecay_ = 1; //SetUsedFormat ("autoscale"); //SetUsedFormat ("percent"); } void NFSDStats::checkevent(void) { char buf[4096], name[64]; unsigned long netcnt, netudpcnt, nettcpcnt, nettcpconn; unsigned long calls, badcalls; int found; std::ifstream ifs(_statfile); if (!ifs) { // cerr <<"Can not open file : " <<_statfile <done(1); return; } fields_[0] = fields_[1] = fields_[2] = 0; // network activity stoptimer(); name[0] = '\0'; found = 0; while (!ifs.eof() && found != 2) { ifs.getline(buf, 4096, '\n'); if (strncmp("net", buf, strlen("net")) == 0) { sscanf(buf, "%s %lu %lu %lu %lu\n", name, &netcnt, &netudpcnt, &nettcpcnt, &nettcpconn); found++; } if (strncmp("rpc", buf, strlen("rpc")) == 0) { sscanf(buf, "%s %lu %lu\n", name, &calls, &badcalls); found++; } } float t = 1000000.0 / usecs(); if (t < 0) t = 0.1; maxpackets_ = MAX(netcnt, calls) - _lastNetCnt; if (maxpackets_ == 0) { maxpackets_ = netcnt; } else { fields_[0] = (badcalls - _lastBad) * t; fields_[1] = (netudpcnt - _lastUdp) * t; fields_[2] = (nettcpcnt - _lastTcp) * t; } total_ = fields_[0] + fields_[1] + fields_[2]; if (total_ > maxpackets_) fields_[3] = 0; else { total_ = maxpackets_; fields_[3] = total_ - fields_[0] - fields_[1] - fields_[2]; } if (total_) setUsed(fields_[0] + fields_[1] + fields_[2], total_); starttimer(); drawfields(); _lastNetCnt = MAX(netcnt, calls); _lastTcp = nettcpcnt; _lastUdp = netudpcnt; _lastBad = badcalls; } NFSStats::NFSStats(XOSView *parent) : NFSMeter(parent, "NFS", 4, "RETRY/AUTH/CALL/IDLE", NFSCLTSTAT ){ starttimer(); } NFSStats::~NFSStats( void ) { } void NFSStats::checkResources( void ){ NFSMeter::checkResources(); setfieldcolor( 0, parent_->getResource( "NFSStatReTransColor" ) ); setfieldcolor( 1, parent_->getResource( "NFSStatAuthRefrshColor" ) ); setfieldcolor( 2, parent_->getResource( "NFSStatCallsColor" ) ); setfieldcolor( 3, parent_->getResource( "NFSStatIdleColor" ) ); useGraph_ = parent_->isResourceTrue( "NFSStatGraph" ); dodecay_ = parent_->isResourceTrue( "NFSStatDecay" ); SetUsedFormat (parent_->getResource("NFSStatUsedFormat")); //SetUsedFormat ("autoscale"); //SetUsedFormat ("percent"); } void NFSStats::checkevent(void) { char buf[4096], name[64]; unsigned long calls = 0, retrns = 0, authrefresh = 0, maxpackets_; std::ifstream ifs(_statfile); if (!ifs) { // cerr <<"Can not open file : " <<_statfile <done(1); return; } fields_[0] = fields_[1] = fields_[2] = 0; stoptimer(); name[0] = '\0'; while (!ifs.eof()) { ifs.getline(buf, 4096, '\n'); if (strncmp("rpc", buf, strlen("rpc"))) continue; sscanf(buf, "%s %lu %lu %lu\n", name, &calls, &retrns, &authrefresh); break; } float t = 1000000.0 / usecs(); if (t < 0) t = 0.1; maxpackets_ = calls - _lastcalls; if (maxpackets_ == 0) { maxpackets_ = calls; } else { fields_[2] = (calls - _lastcalls) * t; fields_[1] = (authrefresh - _lastauthrefresh) * t; fields_[0] = (retrns - _lastretrns) * t; } total_ = fields_[0] + fields_[1] + fields_[2]; if (total_ > maxpackets_) fields_[3] = 0; else { total_ = maxpackets_; fields_[3] = total_ - fields_[2] - fields_[1] - fields_[0]; } if (total_) setUsed(fields_[0] + fields_[1] + fields_[2], total_); starttimer(); drawfields(); _lastcalls = calls; _lastretrns = retrns; _lastauthrefresh = authrefresh; } xosview-1.20/linux/nfsmeter.h000066400000000000000000000022471317735352700163150ustar00rootroot00000000000000// // // This file may be distributed under terms of the GPL // #ifndef _NFSMETER_H_ #define _NFSMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "timer.h" class NFSMeter : public FieldMeterGraph { public: NFSMeter( XOSView *parent, const char *name, int nfields, const char *files, const char *statfile); ~NFSMeter( void ); const char *name( void ) const { return _statname; } void checkResources( void ); void starttimer(void) { return _timer.start(); }; void stoptimer(void) { return _timer.stop(); }; double usecs(void) { return _timer.report_usecs(); }; protected: const char *_statname; const char *_statfile; private: Timer _timer; }; class NFSStats : public NFSMeter { public: NFSStats(XOSView *parent); ~NFSStats(void); void checkevent( void ); void checkResources( void ); private: unsigned long _lastcalls, _lastretrns, _lastauthrefresh; }; class NFSDStats : public NFSMeter { public: NFSDStats(XOSView *parent); ~NFSDStats(void); void checkevent( void ); void checkResources( void ); protected: float maxpackets_; private: unsigned long _lastTcp, _lastUdp, _lastNetCnt, _lastBad; }; #endif xosview-1.20/linux/pagemeter.cc000066400000000000000000000062241317735352700166000ustar00rootroot00000000000000// // Copyright (c) 1996, 2004 by Massimiliano Ghilardi ( ghilardi@cibs.sns.it ) // // This file may be distributed under terms of the GPL // #include "pagemeter.h" #include #include #include #include #include #include #define MAX_PROCSTAT_LENGTH 4096 PageMeter::PageMeter( XOSView *parent, float max ) : FieldMeterGraph( parent, 3, "PAGE", "IN/OUT/IDLE" ), _vmstat(false), _statFileName("/proc/stat"){ for ( int i = 0 ; i < 2 ; i++ ) for ( int j = 0 ; j < 2 ; j++ ) pageinfo_[j][i] = 0; maxspeed_ = max; pageindex_ = 0; struct stat buf; if (stat("/proc/vmstat", &buf) == 0 && buf.st_mode & S_IFREG) { _vmstat = true; _statFileName = "/proc/vmstat"; } } PageMeter::~PageMeter( void ){ } void PageMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "pageInColor" ) ); setfieldcolor( 1, parent_->getResource( "pageOutColor" ) ); setfieldcolor( 2, parent_->getResource( "pageIdleColor" ) ); priority_ = atoi (parent_->getResource( "pagePriority" ) ); maxspeed_ *= priority_ / 10.0; dodecay_ = parent_->isResourceTrue( "pageDecay" ); useGraph_ = parent_->isResourceTrue( "pageGraph" ); SetUsedFormat (parent_->getResource("pageUsedFormat")); } void PageMeter::checkevent( void ){ if (_vmstat) getvmpageinfo(); else getpageinfo(); drawfields(); } void PageMeter::updateinfo(void) { int oldindex = (pageindex_+1)%2; for ( int i = 0; i < 2; i++ ) { if ( pageinfo_[oldindex][i] == 0 ) pageinfo_[oldindex][i] = pageinfo_[pageindex_][i]; fields_[i] = pageinfo_[pageindex_][i] - pageinfo_[oldindex][i]; total_ += fields_[i]; } if ( total_ > maxspeed_ ) fields_[2] = 0.0; else { fields_[2] = maxspeed_ - total_; total_ = maxspeed_; } setUsed (total_ - fields_[2], maxspeed_); pageindex_ = (pageindex_ + 1) % 2; } void PageMeter::getvmpageinfo(void) { total_ = 0; char buf[MAX_PROCSTAT_LENGTH]; bool found_in = false, found_out = false; std::ifstream stats(_statFileName); if (!stats) { std::cerr <<"Cannot open file : " << _statFileName << std::endl; exit(1); } while (!stats.eof() && !(found_in && found_out)) { stats.getline(buf, MAX_PROCSTAT_LENGTH); if (!strncmp(buf, "pswpin", 6)) { pageinfo_[pageindex_][0] = strtoul(buf+7, NULL, 10); found_in = true; } if (!strncmp(buf, "pswpout", 7)) { pageinfo_[pageindex_][1] = strtoul(buf+8, NULL, 10); found_out = true; } } updateinfo(); } void PageMeter::getpageinfo( void ){ total_ = 0; char buf[MAX_PROCSTAT_LENGTH]; std::ifstream stats(_statFileName); if ( !stats ){ std::cerr <<"Cannot open file : " << _statFileName << std::endl; exit( 1 ); } do { stats >>buf; } while (!stats.eof() && strncasecmp(buf, "swap", 5)); stats >>pageinfo_[pageindex_][0] >>pageinfo_[pageindex_][1]; updateinfo(); } xosview-1.20/linux/pagemeter.h000066400000000000000000000013011317735352700164310ustar00rootroot00000000000000// // Copyright (c) 1996, 2007 by Massimiliano Ghilardi ( ghilardi@cibs.sns.it ) // // This file may be distributed under terms of the GPL // #ifndef _PAGEMETER_H_ #define _PAGEMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class PageMeter : public FieldMeterGraph { public: PageMeter( XOSView *parent, float max ); ~PageMeter( void ); const char *name( void ) const { return "PageMeter"; } void checkevent( void ); void checkResources( void ); protected: unsigned long pageinfo_[2][2]; int pageindex_; float maxspeed_; bool _vmstat; const char *_statFileName; void getpageinfo( void ); void getvmpageinfo( void ); void updateinfo(void); private: }; #endif xosview-1.20/linux/raidmeter.cc000066400000000000000000000065761317735352700166150ustar00rootroot00000000000000// // Copyright (c) 1999, 2006 by Thomas Waldmann ( ThomasWaldmann@gmx.de ) // based on work of Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "raidmeter.h" #include #include #include #include #include #include static const char *RAIDFILE = "/proc/mdstat"; RAIDMeter::RAIDMeter( XOSView *parent, int raiddev) : BitFieldMeter( parent, 1, 2, "RAID") { _raiddev = raiddev; getRAIDstate(); if(disknum<1) disableMeter(); std::ostringstream os; os << "MD" << raiddev << std::ends; legend(os.str().c_str()); if(disknum>=1){ setfieldlegend("Done/ToDo"); setNumBits(disknum); } total_ = 100.0; } RAIDMeter::~RAIDMeter( void ){ } void RAIDMeter::checkevent( void ){ getRAIDstate(); for ( int i = 0 ; i < disknum ; i++ ){ bits_[i] = (working_map[i]=='+'); } fields_[0]=100.0; sscanf(resync_state, "resync=%lf", &fields_[0] ); fields_[1] = total_ - fields_[1]; if(fields_[0]<100.0){ setfieldcolor(0,doneColor_); setfieldcolor(1,todoColor_); }else{ setfieldcolor(0,completeColor_); } setUsed(fields_[0], total_); BitFieldMeter::checkevent(); } void RAIDMeter::checkResources( void ){ BitFieldMeter::checkResources(); onColor_ = parent_->allocColor( parent_->getResource( "RAIDdiskOnlineColor" ) ); offColor_ = parent_->allocColor( parent_->getResource( "RAIDdiskFailureColor" ) ); doneColor_ = parent_->allocColor( parent_->getResource( "RAIDresyncdoneColor" ) ); todoColor_ = parent_->allocColor( parent_->getResource( "RAIDresynctodoColor" ) ); completeColor_= parent_->allocColor( parent_->getResource( "RAIDresynccompleteColor" ) ); priority_ = atoi(parent_->getResource("RAIDPriority")); setfieldcolor( 0, doneColor_ ); setfieldcolor( 1, todoColor_ ); SetUsedFormat(parent_->getResource( "RAIDUsedFormat" ) ); } // parser for /proc/mdstat int RAIDMeter::find1(const char *key, const char *findwhat, int num1){ char buf[80]; int rc; std::ostringstream os; os << findwhat << "." << num1 << std::ends; strncpy(buf, os.str().c_str(), 80); buf[79] = '\0'; rc=!strncmp(buf,key, 80); return rc; } int RAIDMeter::find2(const char *key, const char *findwhat, int num1, int num2){ char buf[80]; int rc; std::ostringstream os; os << findwhat << "." << num1 << "." << num2 << std::ends; strncpy(buf, os.str().c_str(), 80); buf[79] = '\0'; rc=!strncmp(buf,key, 80); return rc; } int RAIDMeter::raidparse(char *cp){ char *key, *val; key=strtok(cp," \n"); val=strtok(NULL," \n"); if(key==NULL) return 1; if(find1(key,"md_state",_raiddev)){ if(val) strcpy(state,val); }else if(find1(key,"md_type",_raiddev)){ if(val) strcpy(type,val); }else if(find1(key,"md_disk_count",_raiddev)){ if(val) disknum=atoi(val); }else if(find1(key,"md_working_disk_map",_raiddev)){ if(val) strcpy(working_map,val); }else if(find1(key,"md_resync_status",_raiddev)){ if(val) strcpy(resync_state,val); } return 0; } void RAIDMeter::getRAIDstate( void ){ std::ifstream raidfile( RAIDFILE ); char l[256]; if ( !raidfile ){ std::cerr <<"Can not open file : " < #include #include #include #include #include #include #include #include // This should go away after types.h gets fixed in the kernel. #ifdef __alpha__ typedef unsigned char u8; typedef signed short s16; typedef unsigned short u16; typedef signed int s32; typedef unsigned int u32; typedef signed long long s64; typedef unsigned long long u64; #endif #if defined(GNULIBC) || defined(__GLIBC__) #if !defined(__powerpc__) && !defined(__hppa__) && !defined(__mips__) && !defined(__sparc__) && !defined(__sh__) && !defined(__s390__) && !defined(__s390x__) && !defined(__m68k__) && !defined(__aarch64__) #include #endif #if !defined(__alpha__) && !defined(__sparc__) && !defined(__powerpc__) && !defined(__ia64__) && !defined(__hppa__) && !defined(__arm__) && !defined(__mips__) && !defined(__sh__) && !defined(__s390__) && !defined (__s390x__) && !defined(__m68k__) && !defined(__aarch64__) #include #define HAVE_IOPERM #endif #else #if !defined(__alpha__) && !defined(__sparc__) && !defined(__powerpc__) && !defined(__ia64__) && !defined(__m68k__) #include #endif #endif #include SerialMeter::SerialMeter( XOSView *parent, Device device ) : BitMeter( parent, getTitle(device), "LSR bits(0-7), MSR bits(0-7)", 16){ _device = device; _port = 0; } SerialMeter::~SerialMeter( void ){ } void SerialMeter::checkevent( void ){ getserial(); BitMeter::checkevent(); } void SerialMeter::checkResources( void ){ BitMeter::checkResources(); onColor_ = parent_->allocColor( parent_->getResource( "serialOnColor" ) ); offColor_ = parent_->allocColor( parent_->getResource( "serialOffColor" ) ); priority_ = atoi (parent_->getResource( "serialPriority" ) ); _port = getPortBase(_device); if (!getport(_port + UART_LSR) || !getport(_port + UART_MSR)){ std::cerr << "SerialMeter::SerialMeter() : " << "xosview must be suid root to use the serial meter." << std::endl; parent_->done(1); } } bool SerialMeter::getport(unsigned short int port){ #ifdef HAVE_IOPERM return ioperm(port, 1, 1) != -1; #else return -1 != -1; #endif } void SerialMeter::getserial( void ){ #ifdef HAVE_IOPERM // get the LSR and MSR unsigned char lsr = inb(_port + UART_LSR); unsigned char msr = inb(_port + UART_MSR); setBits(0, lsr); setBits(8, msr); #endif } const char *SerialMeter::getTitle(Device dev) const { static const char *names[] = { "ttyS0", "ttyS1", "ttyS2", "ttyS3", "ttyS4", "ttyS5", "ttyS6", "ttyS7", "ttyS8", "ttyS9" }; return names[dev]; } const char *SerialMeter::getResourceName(Device dev){ static const char *names[] = { "serial0", "serial1", "serial2", "serial3", "serial4", "serial5", "serial6", "serial7", "serial8", "serial9" }; return names[dev]; } unsigned short int SerialMeter::getPortBase(Device dev) const { static const char *deviceFile[] = { "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3", "/dev/ttyS4", "/dev/ttyS5", "/dev/ttyS6", "/dev/ttyS7", "/dev/ttyS8", "/dev/ttyS9"}; const char* res = parent_->getResource(getResourceName(dev)); if (!strncasecmp(res, "True", 5)){ // Autodetect portbase. int fd; struct serial_struct serinfo; // get the real serial port (code stolen from setserial 2.11) if ((fd = open(deviceFile[dev], O_RDONLY|O_NONBLOCK)) < 0) { std::cerr << "SerialMeter::SerialMeter() : " << "failed to open " << deviceFile[dev] <<"." <> std::hex >> tmp; return tmp; } return 0; } xosview-1.20/linux/serialmeter.h000066400000000000000000000016241317735352700170040ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _SERIALMETER_H_ #define _SERIALMETER_H_ // hack for not having linux/serial_reg.h, (Debian bug #427599) #define UART_LSR 5 #define UART_MSR 6 #include "bitmeter.h" #include "xosview.h" class SerialMeter : public BitMeter { public: enum Device { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9 }; static int numDevices(void) { return 10; } SerialMeter( XOSView *parent, Device device); ~SerialMeter( void ); static const char *getResourceName(Device dev); void checkevent( void ); void checkResources( void ); private: unsigned short int _port; Device _device; void getserial( void ); bool getport(unsigned short int port); const char *getTitle(Device dev) const; unsigned short int getPortBase(Device dev) const; }; #endif xosview-1.20/linux/swapmeter.cc000066400000000000000000000023221317735352700166310ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "swapmeter.h" #include #include SwapMeter::SwapMeter( XOSView *parent ) : FieldMeterGraph( parent, 2, "SWAP", "USED/FREE" ){ } SwapMeter::~SwapMeter( void ){ } void SwapMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource( "swapUsedColor" ) ); setfieldcolor( 1, parent_->getResource( "swapFreeColor" ) ); priority_ = atoi (parent_->getResource( "swapPriority" ) ); dodecay_ = parent_->isResourceTrue( "swapDecay" ); useGraph_ = parent_->isResourceTrue( "swapGraph" ); SetUsedFormat (parent_->getResource("swapUsedFormat")); } void SwapMeter::checkevent( void ){ getswapinfo(); drawfields(); } void SwapMeter::getswapinfo( void ){ struct sysinfo sinfo; typeof (sinfo.mem_unit) unit; sysinfo(&sinfo); unit = (sinfo.mem_unit ? sinfo.mem_unit : 1); total_ = (double)sinfo.totalswap * unit; fields_[0] = (double)(sinfo.totalswap - sinfo.freeswap) * unit; if ( total_ == 0 ){ total_ = 1; fields_[0] = 0; } if (total_) setUsed (fields_[0], total_); } xosview-1.20/linux/swapmeter.h000066400000000000000000000010131317735352700164670ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _SWAPMETER_H_ #define _SWAPMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" class SwapMeter : public FieldMeterGraph { public: SwapMeter( XOSView *parent ); ~SwapMeter( void ); const char *name( void ) const { return "SwapMeter"; } void checkevent( void ); void checkResources( void ); protected: void getswapinfo( void ); private: }; #endif xosview-1.20/linux/wirelessmeter.cc000066400000000000000000000060171317735352700175210ustar00rootroot00000000000000// // Copyright (c) 2001 by Tim Ehlers ( tehlers@gwdg.de ) // // This file may be distributed under terms of the GPL // // #include "wirelessmeter.h" #include #include #include #include #include WirelessMeter::WirelessMeter( XOSView *parent, int ID, const char *wlID) : FieldMeterGraph ( parent, 2, wlID, "LINK/LEVEL", 1, 1, 0 ), _number(ID) { _lastquality = -1; _lastlink = true; total_ = 0; } WirelessMeter::~WirelessMeter( void ){ } void WirelessMeter::checkResources( void ){ FieldMeterGraph::checkResources(); _poorqualcol = parent_->allocColor(parent_->getResource( "PoorQualityColor" )); _fairqualcol = parent_->allocColor(parent_->getResource( "FairQualityColor" )); _goodqualcol = parent_->allocColor(parent_->getResource( "GoodQualityColor" )); setfieldcolor( 1, parent_->getResource( "wirelessUsedColor" ) ); priority_ = atoi(parent_->getResource( "wirelessPriority" ) ); dodecay_ = parent_->isResourceTrue( "wirelessDecay" ); SetUsedFormat(parent_->getResource( "wirelessUsedFormat" ) ); } void WirelessMeter::checkevent( void ){ getpwrinfo(); drawfields(); } void WirelessMeter::getpwrinfo( void ){ std::ifstream loadinfo( WLFILENAME ); if ( !loadinfo ){ std::cerr << "Can not open file : " << WLFILENAME << std::endl; parent_->done(1); return; } char buff[16]; int linkq = 0, quality = 0; bool link = false; // skip the two header rows loadinfo.ignore(1024, '\n'); loadinfo.ignore(1024, '\n'); if ( _devname.empty() ) { // find devname on first run for (int i = 0; i < _number; i++) loadinfo.ignore(1024, '\n'); if ( loadinfo.good() ) loadinfo >> _devname >> buff >> linkq; } else { while ( !loadinfo.eof() ) { loadinfo >> buff; if ( _devname == buff ) { loadinfo >> buff >> linkq; link = true; break; } loadinfo.ignore(1024, '\n'); } } if ( linkq >= 250 ) linkq = 0; fields_[0] = linkq; if ( fields_[0] >= 15 ) quality = 2; else if ( fields_[0] >= 7 ) quality = 1; else quality = 0; if ( link && !_lastlink ) { legend("LINK/LEVEL"); drawlegend(); _lastlink = link; } else if ( !link && _lastlink ) { legend("NONE/LEVEL"); drawlegend(); _lastlink = link; } if ( quality != _lastquality ){ if ( quality == 0 ) setfieldcolor( 0, _poorqualcol ); else if ( quality == 1 ) setfieldcolor( 0, _fairqualcol ); else setfieldcolor( 0, _goodqualcol ); drawlegend(); _lastquality = quality; } if (fields_[0] >= total_) total_ = 30 * (int)(fields_[0] / 30 + 1); fields_[1] = total_ - fields_[0]; setUsed(fields_[0], total_); } int WirelessMeter::countdevices(void){ glob_t gbuf; glob("/sys/class/net/*/wireless", 0, NULL, &gbuf); int count = gbuf.gl_pathc; globfree(&gbuf); return count; } const char *WirelessMeter::wirelessStr(int num) { static char buffer[8] = "WL"; snprintf(buffer + 2, 5, "%d", num); buffer[7] = '\0'; return buffer; } xosview-1.20/linux/wirelessmeter.h000066400000000000000000000015241317735352700173610ustar00rootroot00000000000000// // Copyright (c) 1997 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // // #ifndef _WIRELESSMETER_H_ #define _WIRELESSMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include static const char WLFILENAME[] = "/proc/net/wireless"; class WirelessMeter : public FieldMeterGraph { public: WirelessMeter( XOSView *parent, int ID = 0, const char *wlID = "WL"); ~WirelessMeter( void ); const char *name( void ) const { return "WirelessMeter"; } void checkevent( void ); void checkResources( void ); static int countdevices(void); static const char *wirelessStr(int num); protected: void getpwrinfo( void ); private: unsigned long _poorqualcol, _fairqualcol, _goodqualcol; int _lastquality, _number; std::string _devname; bool _lastlink; }; #endif xosview-1.20/llist.cc000066400000000000000000000135761317735352700146270ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "llist.h" #include LList::LNode::LNode( void *data ){ data_ = data; next_ = NULL; prev_ = NULL; } LList::LList( void ){ n_ = 0; top_ = NULL; btm_ = NULL; for ( int i = 0 ; i < MAXCURR ; i++ ) curr_[i] = NULL; cmp_fun_ = NULL; } LList::LList( int ( *cmp_fun )( void *data, void *key ) ){ n_ = 0; top_ = NULL; btm_ = NULL; for ( int i = 0 ; i < MAXCURR ; i++ ) curr_[i] = NULL; cmp_fun_ = cmp_fun; } LList::~LList( void ){ while ( n_ ) pop(); } int LList::push( void *data ){ if ( !n_ ) { top_ = new LNode( data ); if ( top_ == NULL ) return ( 0 ); n_ = 1; btm_ = top_; return ( 1 ); } btm_->next_ = new LNode( data ); if ( btm_->next_ == NULL ) return ( 0 ); n_++; btm_->next_->prev_ = btm_; btm_ = btm_->next_; return ( 1 ); } void *LList::pop( void ){ void *temp; LNode *temp2; if ( !n_ ) return ( NULL ); temp = btm_->data_; if ( n_ == 1 ) { delete top_; top_ = NULL; btm_ = NULL; n_ = 0; return ( temp ); } n_--; temp2 = btm_->prev_; btm_->prev_->next_ = NULL; delete btm_; btm_ = temp2; return ( temp ); } void *LList::dequeue( void ){ void *temp; LNode *temp2; if ( !n_ ) return ( NULL ); if ( n_ == 1 ) { temp = top_->data_; n_ = 0; delete top_; top_ = NULL; btm_ = NULL; return ( temp ); } n_--; temp2 = top_->next_; temp = top_->data_; top_->next_->prev_ = NULL; delete top_; top_ = temp2; return ( temp ); } int LList::insert( void *data, void *key ){ LNode *current, *temp; current = top_; /* Empty List */ if ( !n_ ) { if ( ( top_ = new LNode( data ) ) == NULL ) return ( 0 ); btm_ = top_; n_++; return ( 1 ); } while ( ( cmp_fun_( current->data_, key ) < 0 ) && ( current->next_ != NULL ) ) current = current->next_; if ( ( temp = new LNode( data ) ) == NULL ) return ( 0 ); n_++; /* Add To End of List */ if ( ( current->next_ == NULL ) && ( cmp_fun_( current->data_, key ) < 0 ) ) { temp->prev_ = btm_; current->next_ = temp; btm_ = temp; return ( 1 ); } /* Add To Top of List */ if ( ( current->prev_ == NULL ) && ( cmp_fun_( current->data_, key ) > 0 ) ) { temp->next_ = current; current->prev_ = temp; top_ = temp; return ( 1 ); } /* Middle Of List */ temp->next_ = current; temp->prev_ = current->prev_; current->prev_->next_ = temp; current->prev_ = temp; return ( 1 ); } void *LList::find( void *key ){ LNode *temp; temp = findnode( key ); if ( temp == NULL ) return ( NULL ); return ( temp->data_ ); } void *LList::removematch( void *key ){ LNode *ptr; ptr = findnode( key ); if ( ptr == NULL ) return ( NULL ); return ( deletenode( ptr ) ); } int LList::putontop( void *data ){ LNode *buff; if ( ( buff = new LNode( data ) ) == NULL ) return ( 0 ); top_->prev_ = buff; buff->next_ = top_; top_ = buff; n_++; return ( 1 ); } void LList::remove( void *data ){ LNode *tmp; int found = 0; tmp = top_; while ( (!found) && (tmp != NULL) ) { if ( tmp->data_ == data ) found = 1; if ( !found ) tmp = tmp->next_; } if ( (tmp == NULL) || (!found) ) return; deletenode( tmp ); } void *LList::findn( int n ){ LNode *temp; temp = findnnode( n ); if ( temp == NULL ) return ( NULL ); return ( temp->data_ ); } int LList::index( void *data ){ int a = 1; LNode *tmp; tmp = top_; while ( tmp != NULL ) { if ( tmp->data_ == data ) return ( a ); a++; tmp = tmp->next_; } return ( 0 ); } void LList::setc( int n, int which ){ curr_[which] = findnnode( n ); } void LList::incc( int which ){ if ( curr_[which] != NULL ) curr_[which] = curr_[which]->next_; } void LList::decc( int which ){ if ( curr_[which] != NULL ) curr_[which] = curr_[which]->prev_; } void *LList::findc( int which ){ if ( curr_[which] == NULL ) return ( NULL ); return ( curr_[which]->data_ ); } void LList::save( int size, FILE *fp ){ int i; void *buf; fwrite( &n_, sizeof( int ), 1, fp ); /* save n */ setc( 1 ); for ( i = 1 ; i <= n_ ; i ++ ) { buf = findc(); fwrite ( buf, size, 1, fp ); incc(); } } int LList::restore( int size, FILE *fp ){ int i; void *buf; fread ( &i, sizeof ( int ), 1, fp ); for ( ; i > 0 ; i-- ) { if ( ( buf = new char[size] ) == NULL ) return ( 0 ); if ( ! push( buf ) ) return ( 0 ); } return ( 1 ); } void LList::kill( void ){ // while ( n_ ) { // delete pop(); // } } LList::LNode *LList::findnode( void *key ){ LNode *current; current = top_; if ( current == NULL ) return ( NULL ); while ( ( cmp_fun_( current->data_, key ) ) && ( current != NULL ) ) current = current->next_; if ( current == NULL ) return ( NULL ); return ( current ); } void *LList::deletenode( LNode *ptr ){ void *rtn; if ( ( top_ == NULL ) || ( ptr == NULL ) ) return ( NULL ); if ( n_ == 1 ) { rtn = top_->data_; n_ = 0; delete top_; top_ = btm_ = NULL; return ( rtn ); } n_--; if ( ptr->prev_ == NULL ) { rtn = ptr->data_; top_ = top_->next_; top_->prev_ = NULL; delete ptr; return ( rtn ); } if ( ptr->next_ == NULL ) { rtn = ptr->data_; btm_ = btm_->prev_; btm_->next_ = NULL; delete ptr; return ( rtn ); } ptr->prev_->next_ = ptr->next_; ptr->next_->prev_ = ptr->prev_; rtn = ptr->data_; delete ptr; return ( rtn ); } LList::LNode *LList::findnnode( int i ){ int j; LNode *current; if ( (i > n_) || (i < 1) ) return ( NULL ); if ( i <= n_ / 2 ) { current = top_; for ( j = 1 ; j < i ; j++ ) current = current->next_; return ( current ); } current = btm_; for ( j = n_ ; j > i ; j-- ) current = current->prev_; return ( current ); } xosview-1.20/llist.h000066400000000000000000000105321317735352700144560ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef __LLIST_H__ #define __LLIST_H__ #include #define MAXCURR 4 // number of 'current' pointers class LList { public: // The first constructor is used for unordered lists ( stacks, queques ). // The second constructor is used for ordered lists. It's // parameter is a pointer to the function to be used for ordering the // list. This function must behave in the following way: // int Cmp_Fun ( void *data, void *key ) // // *data is a pointer to the type of information // to be stored in the list. // // *key is a pointer to the location within the data // which will be used to order the list. In some // cases these two pointers will be of the same // type. // // function returns : // // 0.........*data = *key // > 0.......*data > *key // < 0.......*data < *key LList( void ); // for unordered lists LList( int ( *cmp_fun )( void *data, void *key ) ); // for ordered lists virtual ~LList( void ); // frees nodes but not data // Stack like functions. // pop returns NULL if the list is empty. // push returns 1 on sucess and 0 upon failure. int push( void *data ); void *pop( void ); // Queue like functions // dequeue returns NULL if the list is empty. // enqueue returns 1 on sucess and 0 upon failure. int enqueue( void *data ) { return( push( data ) ); } void *dequeue( void ); // Ordered list functions // for insert *key points to some part of *data used for sorting. // for find and removematch *key points to the "search" key. // - insert returns 1 on sucess and 0 on failure // - find and removematch return a pointer to the data stored in the list if // sucessful and NULL if not. int insert( void *data, void *key ); void *find( void *key ); void *removematch( void *key ); // Misc. llist functions int putontop( void *data ); // oposite of push void remove( void *data ); // removes *data from the list if it's there void *findn( int n ); // returns nth element if found or NULL if not void *operator[](int n) // returns nth element if found or NULL if not { return findn(n); } int index( void *data ); // returns the index of *data or 0 if not there // Sets the a pointer for the linked list to the nth element in // the list. This function and the three that follow are intended to // be used for a stepwise search of a linked list. This function sets // curr_ to the nth element in the list. incc sets the same pointer // to the next element in the list. decc sets it to the previous // element in the list. findc returns a pointer to the element // curr_ is "currently" pointing to. If n is not valid for the list // curr_ is set to NULL. void setc( int n, int which = 0 ); void incc( int which = 0 ); void decc( int which = 0 ); void *findc( int which = 0 ); // This function will save a linked list to the file pointed to // by *fp. The file should be binary. n is saved first and then // each item on the list is saved. size is the number of bytes of // each item on the list. The list will remain intact after this // function is called. void save( int size, FILE *fp ); // This function reads a linked list from the file pointed to // by *fp ( previously saved by the above function ). Space is // allocated for each item, and it is placed into the list in it's // old position. size is the number of bytes each item occupies. // This function will return 1 upon sucess and 0 upon failure. int restore( int size, FILE *fp ); // This function will remaove all of the elements in the linked // list pointed to by L and free the memory each element occupied. void kill( void ); int n( void ) const { return( n_ ); } // number of elements in the list protected: class LNode { public: LNode( void *data = NULL ); void *data_; LNode *next_; LNode *prev_; }; int n_; // number of nodes in the list LNode *top_, *btm_; // pointers to various nodes LNode *curr_[MAXCURR]; // a comparison function for ordered lists int ( *cmp_fun_ )( void *data, void *key ); LNode *findnode( void *key ); void *deletenode( LNode *ptr ); LNode *findnnode( int i ); private: }; #endif xosview-1.20/main.cc000066400000000000000000000011571317735352700144140ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006, 2007 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "xosview.h" #include int main( int argc, char *argv[] ) { /* Icky. Need to check for -name option here. */ char** argp = argv; const char* instanceName = "xosview"; // Default value. while (argp && *argp) { if (!strncmp(*argp, "-name", 6)) instanceName = argp[1]; argp++; } // instanceName will end up pointing to the last such -name option. XOSView xosview( instanceName, argc, argv ); xosview.run(); return 0; } xosview-1.20/meter.cc000066400000000000000000000053651317735352700146110ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "meter.h" #include Meter::Meter( XOSView *parent, const char *title, const char *legend, int docaptions, int dolegends, int dousedlegends ) { title_ = legend_ = NULL; Meter::title( title ); Meter::legend( legend ); parent_ = parent; docaptions_ = docaptions; dolegends_ = dolegends; dousedlegends_ = dousedlegends; priority_ = 1; counter_ = 0; resize( parent->xoff(), parent->newypos(), parent->width() - 10, 10 ); } Meter::~Meter( void ){ if ( title_ ) delete[] title_; if ( legend_ ) delete[] legend_; } void Meter::checkResources( void ){ textcolor_ = parent_->allocColor( parent_->getResource( "meterLabelColor") ); } void Meter::title( const char *title ){ if ( title_ ) delete[] title_; int len = strlen(title); title_ = new char[len + 1]; strncpy( title_, title, len ); title_[len] = '\0'; // strncpy() will not null terminate if s2 > len } void Meter::legend( const char *legend ){ if ( legend_ ) delete[] legend_; int len = strlen(legend); legend_ = new char[len + 1]; strncpy( legend_, legend, len ); legend_[len] = '\0'; // strncpy() will not null terminate if s2 > len } void Meter::resize( int x, int y, int width, int height ){ x_ = x; y_ = y; width_ = (width>=0) ? width : 0; // fix for cosmetical bug: height_ = (height>=0) ? height : 0; // beware of values < 0 ! width_ &= ~1; // only allow even width_ values } double Meter::scaleValue( double value, char *scale, bool metric ){ double scaled = ( value < 0 ? -value : value ); if (scaled >= 999.5*1e15){ scale[0] = 'E'; scaled = value / ( metric ? 1e18 : 1ULL<<60 ); } else if (scaled >= 999.5*1e12){ scale[0] = 'P'; scaled = value / ( metric ? 1e15 : 1ULL<<50 ); } else if (scaled >= 999.5*1e9){ scale[0] = 'T'; scaled = value / ( metric ? 1e12 : 1ULL<<40 ); } else if (scaled >= 999.5*1e6){ scale[0] = 'G'; scaled = value / ( metric ? 1e9 : 1UL<<30 ); } else if (scaled >= 999.5*1e3){ scale[0] = 'M'; scaled = value / ( metric ? 1e6 : 1UL<<20 ); } else if (scaled >= 999.5){ scale[0] = ( metric ? 'k' : 'K' ); scaled = value / ( metric ? 1e3 : 1UL<<10 ); } else if (scaled < 0.9995 && metric){ if (scaled >= 0.9995/1e3){ scale[0] = 'm'; scaled = value * 1e3; } else if (scaled >= 0.9995/1e6){ scale[0] = '\265'; scaled = value * 1e6; } else { scale[0] = 'n'; scaled = value * 1e9; } // add more if needed } else { scale[0] = '\0'; scaled = value; } scale[1] = '\0'; return scaled; } xosview-1.20/meter.h000066400000000000000000000035041317735352700144440ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _METER_H_ #define _METER_H_ #include "xosview.h" #include class Meter { public: Meter( XOSView *parent, const char *title = "", const char *legend ="", int docaptions = 0, int dolegends = 0, int dousedlegends = 0 ); virtual ~Meter( void ); virtual const char *name( void ) const { return "Meter"; } void resize( int x, int y, int width, int height ); virtual void checkevent( void ) = 0; virtual void draw( void ) = 0; void title( const char *title ); const char *title( void ) { return title_; } void legend( const char *legend ); const char *legend( void ) { return legend_; } void docaptions( int val ) { docaptions_ = val; } void dolegends( int val ) { dolegends_ = val; } void dousedlegends( int val ) { dousedlegends_ = val; } int requestevent( void ){ if (priority_ == 0) { std::cerr << "Warning: meter " << name() << " had an invalid priority " << "of 0. Resetting to 1..." << std::endl; priority_ = 1; } int rval = counter_ % priority_; counter_ = (counter_ + 1) % priority_; return !rval; } int getX() const { return x_; } int getY() const { return y_; } int getWidth() const { return width_; } int getHeight() const { return height_; } virtual void checkResources( void ); static double scaleValue( double value, char *scale, bool metric ); protected: XOSView *parent_; int x_, y_, width_, height_, docaptions_, dolegends_, dousedlegends_; int priority_, counter_; char *title_, *legend_; unsigned long textcolor_; double samplesPerSecond() { return 1.0*MAX_SAMPLES_PER_SECOND/priority_; } double secondsPerSample() { return 1.0/samplesPerSecond(); } private: }; #endif xosview-1.20/mkdist000077500000000000000000000003331317735352700143750ustar00rootroot00000000000000#!/bin/sh # # Make an xosview distribution from a Git repo # set -e V=`git describe` D="xosview-$V" mkdir -p dist A="dist/$D.tar.gz" git archive --prefix="$D/" HEAD | gzip --best > "$A" echo "Created $A" >&2 exit 0 xosview-1.20/pllist.h000066400000000000000000000054471317735352700146470ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _pllist_h #define _pllist_h #include "llist.h" //------------------------------------------------------------------------- // // Pointer Linked list. T is some pointer type. // //------------------------------------------------------------------------- template class PLList : public LList { public: PLList(void) : LList(){} // PLList(int(*cmp_fun)(T data, K key)) : LList(cmp_fun){} int push(const T data) { return LList::push((void *)data); } T pop(void) { return (T)LList::pop(); } int enqueue(const T data) { return LList::enqueue((void *)data); } T dequeue(void) { return (T)LList::dequeue(); } // int insert(const T data, const K key) // { return LList::insert((void *)data, (void *)key); } // T find(const K key) { return (T)LList::find((void *)key); } // T removematch(const K key) // { return (T)LList::removematch((void *)key); } int putontop(const T data) { return LList::putontop((void *)data); } void remove(const T data) { LList::remove((void *)data); } T findn(int n) { return (T)LList::findn(n); } T operator[](int n) { return findn(n); } int index(const T data) { return LList::index((void *)data); } T findc(int which = 0) { return (T)LList::findc(which); } }; //------------------------------------------------------------------------- // // Sorted Pointer List. T is some type of pointer and K is a pointer to // the key type for this list. // //------------------------------------------------------------------------- template class PSLList : public LList { public: PSLList(void) : LList(){} PSLList(int(*cmp_fun)(T data, K key)) : LList(cmp_fun){} int push(const T data) { return LList::push((void *)data); } T pop(void) { return (T)LList::pop(); } int enqueue(const T data) { return LList::enqueue((void *)data); } T dequeue(void) { return (T)LList::dequeue(); } int insert(const T data, const K key) { return LList::insert((void *)data, (void *)key); } T find(const K key) { return (T)LList::find((void *)key); } T removematch(const K key) { return (T)LList::removematch((void *)key); } int putontop(const T data) { return LList::putontop((void *)data); } void remove(const T data) { LList::remove((void *)data); } T findn(int n) { return (T)LList::findn(n); } T operator[](int n) { return findn(n); } int index(const T data) { return LList::index((void *)data); } T findc(int which = 0) { return (T)LList::findc(which); } }; #endif xosview-1.20/sensorfieldmeter.cc000066400000000000000000000132241317735352700170400ustar00rootroot00000000000000// // Copyright (c) 2014 by Tomi Tapper // // This file may be distributed under terms of the GPL // // Put code common to *BSD and Linux sensor meters here. // #include "sensorfieldmeter.h" #include #include #include SensorFieldMeter::SensorFieldMeter( XOSView *parent, const char *title, const char *legend, int docaptions, int dolegends, int dousedlegends ) : FieldMeter( parent, 3, title, legend, docaptions, dolegends, dousedlegends ){ metric_ = true; negative_ = false; unit_[0] = '\0'; high_ = low_ = 0.0; has_low_ = has_high_ = false; } SensorFieldMeter::~SensorFieldMeter( void ){ } void SensorFieldMeter::updateLegend( void ){ char l[32], lscale[2], tscale[2]; double limit = ( negative_ ? low_ : high_ ), total; total = scaleValue(total_, tscale, true); if ( (!negative_ && has_high_) || (negative_ && has_low_) ) { if ( ( 0.1 <= fabs(total_) && fabs(total_) < 9.95 ) || ( 0.1 <= fabs(limit) && fabs(limit) < 9.95 ) ) { if ( strlen(unit_) ) snprintf(l, 32, "ACT(%s)/%.1f/%.1f", unit_, limit, total_); else snprintf(l, 32, "ACT/%.1f/%.1f", limit, total_); } else if ( ( 9.95 <= fabs(total_) && fabs(total_) < 10000 ) || ( 9.95 <= fabs(limit) && fabs(limit) < 10000 ) ) { if ( strlen(unit_) ) snprintf(l, 32, "ACT(%s)/%.0f/%.0f", unit_, limit, total_); else snprintf(l, 32, "ACT/%.0f/%0.f", limit, total_); } else { limit = scaleValue(limit, lscale, true); if ( strlen(unit_) ) snprintf(l, 32, "ACT(%s)/%.0f%s/%.0f%s", unit_, limit, lscale, total, tscale); else snprintf(l, 32, "ACT/%.0f%s/%.0f%s", limit, lscale, total, tscale); } } else { if ( ( 0.1 <= fabs(total_) && fabs(total_) < 9.95 ) || ( 0.1 <= fabs(limit) && fabs(limit) < 9.95 ) ) { if ( strlen(unit_) ) snprintf(l, 32, "ACT(%s)/%s/%.1f", unit_, ( negative_ ? "LOW" : "HIGH" ), total_); else snprintf(l, 32, "ACT/%s/%.1f", ( negative_ ? "LOW" : "HIGH" ), total_); } else if ( ( 9.95 <= fabs(total_) && fabs(total_) < 10000 ) || ( 9.95 <= fabs(limit) && fabs(limit) < 10000 ) ) { if ( strlen(unit_) ) snprintf(l, 32, "ACT(%s)/%s/%.0f", unit_, ( negative_ ? "LOW" : "HIGH" ), total_); else snprintf(l, 32, "ACT/%s/%.0f", ( negative_ ? "LOW" : "HIGH" ), total_); } else { if ( strlen(unit_) ) snprintf(l, 32, "ACT(%s)/%s/%.0f%s", unit_, ( negative_ ? "LOW" : "HIGH" ), total, tscale); else snprintf(l, 32, "ACT/%s/%.0f%s", ( negative_ ? "LOW" : "HIGH" ), total, tscale); } } legend(l); } /* Check if meter needs to be flipped, or total/limits changed. */ /* Check also if alarm limit is reached. */ /* This is to be called after the values have been read. */ void SensorFieldMeter::checkFields( double low, double high ){ // Most sensors stay at either positive or negative values. Consider the // actual value and alarm limits when deciding should the meter be showing // positive or negative scale. bool do_legend = false; if (negative_) { // negative at previous run if (fields_[0] >= 0 || low > 0) { // flip to positive negative_ = false; total_ = fabs(total_); high_ = ( has_high_ ? high : total_ ); low_ = ( has_low_ ? low : 0 ); setfieldcolor( 2, highcolor_ ); do_legend = true; } else { if (has_low_ && low != low_) { low_ = low; do_legend = true; } if (has_high_ && high != high_) high_ = high; } } else { // positive at previous run if ( fields_[0] < 0 && // flip to negative if value and either limit is below 0 ( (!has_low_ && !has_high_) || low < 0 || high < 0 ) ) { negative_ = true; total_ = -fabs(total_); high_ = ( has_high_ ? high : 0 ); low_ = ( has_low_ ? low : total_ ); setfieldcolor( 2, lowcolor_ ); do_legend = true; } else { if (has_high_ && high != high_) { high_ = high; do_legend = true; } if (has_low_ && low != low_) low_ = low; } } // change total if value or alarms won't fit double highest = fabs(high_); if ( fabs(fields_[0]) > highest ) highest = fabs(fields_[0]); if ( fabs(low_) > highest ) highest = fabs(low_); if ( highest > fabs(total_) ) { do_legend = true; int scale = floor(log10(highest)); total_ = ceil((highest / pow(10, scale)) * 1.25) * pow(10, scale); if (negative_) { total_ = -fabs(total_); if (!has_low_) low_ = total_; if (!has_high_) high_ = 0; } else { if (!has_low_) low_ = 0; if (!has_high_) high_ = total_; } } if (do_legend) updateLegend(); // check for alarms if (fields_[0] > high_) { // alarm: T > max if (colors_[0] != highcolor_) { setfieldcolor( 0, highcolor_ ); do_legend = true; } } else if (fields_[0] < low_) { // alarm: T < min if (colors_[0] != lowcolor_) { setfieldcolor( 0, lowcolor_ ); do_legend = true; } } else { if (colors_[0] != actcolor_) { setfieldcolor( 0, actcolor_ ); do_legend = true; } } setUsed(fields_[0], total_); if (negative_) fields_[1] = ( fields_[0] < low_ ? 0 : low_ - fields_[0] ); else { if (fields_[0] < 0) fields_[0] = 0; fields_[1] = ( fields_[0] > high_ ? 0 : high_ - fields_[0] ); } fields_[2] = total_ - fields_[1] - fields_[0]; if (do_legend) { drawlegend(); drawfields(1); // force drawing in case only limit has changed } } xosview-1.20/sensorfieldmeter.h000066400000000000000000000014451317735352700167040ustar00rootroot00000000000000// // Copyright (c) 2014 by Tomi Tapper // // This file may be distributed under terms of the GPL // // Put code common to *BSD and Linux sensor meters here. // #ifndef _SENSORFIELDMETER_H_ #define _SENSORFIELDMETER_H_ #include "fieldmeter.h" #include "xosview.h" class SensorFieldMeter : public FieldMeter { public: SensorFieldMeter( XOSView *parent, const char *title = "", const char *legend = "", int docaptions = 0, int dolegends = 0, int dousedlegends = 0 ); ~SensorFieldMeter( void ); protected: void updateLegend( void ); void checkFields( double low, double high ); char unit_[8]; double high_, low_; bool has_high_, has_low_, negative_; unsigned long actcolor_, highcolor_, lowcolor_; private: }; #endif xosview-1.20/sunos5/000077500000000000000000000000001317735352700144115ustar00rootroot00000000000000xosview-1.20/sunos5/MeterMaker.cc000066400000000000000000000037751317735352700167700ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #include "MeterMaker.h" #include "xosview.h" #include "kstats.h" #include "cpumeter.h" #include "memmeter.h" #include "swapmeter.h" #include "loadmeter.h" #include "pagemeter.h" #include "diskmeter.h" #include "netmeter.h" #include "intratemeter.h" #include #include #include MeterMaker::MeterMaker(XOSView *xos) { _xos = xos; } void MeterMaker::makeMeters(void) { kstat_ctl_t *kc; kc = kstat_open(); if (kc == NULL) return; if (_xos->isResourceTrue("load")) push(new LoadMeter(_xos, kc)); // Standard meters (usually added, but users could turn them off) if (_xos->isResourceTrue("cpu")) { bool single, both, all; int cpuCount = sysconf(_SC_NPROCESSORS_ONLN); single = (strncmp(_xos->getResource("cpuFormat"), "single", 2) == 0); both = (strncmp(_xos->getResource("cpuFormat"), "both", 2) == 0); all = (strncmp(_xos->getResource("cpuFormat"), "all", 2) == 0); if (strncmp(_xos->getResource("cpuFormat"), "auto", 2) == 0) { if (cpuCount == 1 || cpuCount > 4) single = true; else all = true; } if (single || both) push(new CPUMeter(_xos, kc, -1)); if (all || both) { KStatList *cpulist = KStatList::getList(kc, KStatList::CPU_STAT); for (unsigned int i = 0; i < cpulist->count(); i++) push(new CPUMeter(_xos, kc, (*cpulist)[i]->ks_instance)); } } if (_xos->isResourceTrue("mem")) push(new MemMeter(_xos, kc)); if (_xos->isResourceTrue("disk")) push(new DiskMeter(_xos, kc, atof(_xos->getResource("diskBandwidth")))); if (_xos->isResourceTrue("swap")) push(new SwapMeter(_xos, kc)); if (_xos->isResourceTrue("page")) push(new PageMeter(_xos, kc, atof(_xos->getResource("pageBandwidth")))); if (_xos->isResourceTrue("net")) push(new NetMeter(_xos, kc, atof(_xos->getResource("netBandwidth")))); if (_xos->isResourceTrue("irqrate")) push(new IrqRateMeter(_xos, kc)); } xosview-1.20/sunos5/MeterMaker.h000066400000000000000000000004731317735352700166220ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #ifndef _MeterMaker_h #define _MeterMaker_h #include "pllist.h" class Meter; class XOSView; class MeterMaker : public PLList { public: MeterMaker(XOSView *xos); void makeMeters(void); private: XOSView *_xos; }; #endif xosview-1.20/sunos5/cpumeter.cc000066400000000000000000000050701317735352700165460ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #include "cpumeter.h" #include #include #include #include CPUMeter::CPUMeter(XOSView *parent, kstat_ctl_t *_kc, int cpuid) : FieldMeterGraph(parent, CPU_STATES, cpuStr(cpuid), "USER/SYS/WAIT/IDLE") { kc = _kc; aggregate = ( cpuid < 0 ); for (int i = 0 ; i < 2 ; i++) for (int j = 0 ; j < CPU_STATES ; j++) cputime_[i][j] = 0; cpuindex_ = 0; cpustats = KStatList::getList(kc, KStatList::CPU_STAT); if (!aggregate) for (unsigned int i = 0; i < cpustats->count(); i++) if ((*cpustats)[i]->ks_instance == cpuid) ksp = (*cpustats)[i]; } CPUMeter::~CPUMeter(void) { } void CPUMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("cpuUserColor")); setfieldcolor(1, parent_->getResource("cpuSystemColor")); setfieldcolor(2, parent_->getResource("cpuInterruptColor")); setfieldcolor(3, parent_->getResource("cpuFreeColor")); priority_ = atoi(parent_->getResource("cpuPriority")); dodecay_ = parent_->isResourceTrue("cpuDecay"); useGraph_ = parent_->isResourceTrue("cpuGraph"); SetUsedFormat(parent_->getResource("cpuUsedFormat")); } void CPUMeter::checkevent(void) { getcputime(); drawfields(); } void CPUMeter::getcputime(void) { total_ = 0; cpu_stat_t cs; if (aggregate) { cpustats->update(kc); bzero(cputime_[cpuindex_], CPU_STATES * sizeof(cputime_[cpuindex_][0])); for (unsigned int i = 0; i < cpustats->count(); i++) { if (kstat_read(kc, (*cpustats)[i], &cs) == -1) { parent_->done(1); return; } cputime_[cpuindex_][0] += cs.cpu_sysinfo.cpu[CPU_USER]; cputime_[cpuindex_][1] += cs.cpu_sysinfo.cpu[CPU_KERNEL]; cputime_[cpuindex_][2] += cs.cpu_sysinfo.cpu[CPU_WAIT]; cputime_[cpuindex_][3] += cs.cpu_sysinfo.cpu[CPU_IDLE]; } } else { if (kstat_read(kc, ksp, &cs) == -1) { parent_->done(1); return; } cputime_[cpuindex_][0] = cs.cpu_sysinfo.cpu[CPU_USER]; cputime_[cpuindex_][1] = cs.cpu_sysinfo.cpu[CPU_KERNEL]; cputime_[cpuindex_][2] = cs.cpu_sysinfo.cpu[CPU_WAIT]; cputime_[cpuindex_][3] = cs.cpu_sysinfo.cpu[CPU_IDLE]; } int oldindex = (cpuindex_ + 1) % 2; for (int i = 0 ; i < CPU_STATES ; i++) { fields_[i] = cputime_[cpuindex_][i] - cputime_[oldindex][i]; total_ += fields_[i]; } cpuindex_ = (cpuindex_ + 1) % 2; if (total_) setUsed(total_ - fields_[3], total_); } const char *CPUMeter::cpuStr(int num) { static char buffer[8] = "CPU"; if (num >= 0) snprintf(buffer + 3, 4, "%d", num); buffer[7] = '\0'; return buffer; } xosview-1.20/sunos5/cpumeter.h000066400000000000000000000012601317735352700164050ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #ifndef _CPUMETER_H_ #define _CPUMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "kstats.h" #include #include class CPUMeter : public FieldMeterGraph { public: CPUMeter(XOSView *parent, kstat_ctl_t *kcp, int cpuid = 0); ~CPUMeter(void); const char *name(void) const { return "CPUMeter"; } void checkevent(void); void checkResources(void); static const char *cpuStr(int num); protected: float cputime_[2][CPU_STATES]; int cpuindex_; void getcputime(void); private: KStatList *cpustats; bool aggregate; kstat_ctl_t *kc; kstat_t *ksp; }; #endif xosview-1.20/sunos5/diskmeter.cc000066400000000000000000000041671317735352700167170ustar00rootroot00000000000000// // Rewritten for Solaris by Arno Augustin 1999 // augustin@informatik.uni-erlangen.de // #include "diskmeter.h" #include DiskMeter::DiskMeter( XOSView *parent, kstat_ctl_t *kc, float max ) : FieldMeterGraph( parent, 3, "DISK", "READ/WRITE/IDLE" ) { _kc = kc; _read_prev = _write_prev = 0; _maxspeed = max; _disks = KStatList::getList(_kc, KStatList::DISKS); } DiskMeter::~DiskMeter( void ) { } void DiskMeter::checkResources( void ) { FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("diskReadColor") ); setfieldcolor( 1, parent_->getResource("diskWriteColor") ); setfieldcolor( 2, parent_->getResource("diskIdleColor") ); priority_ = atoi( parent_->getResource("diskPriority") ); dodecay_ = parent_->isResourceTrue("diskDecay"); useGraph_ = parent_->isResourceTrue("diskGraph"); SetUsedFormat( parent_->getResource("diskUsedFormat") ); } void DiskMeter::checkevent( void ) { getdiskinfo(); drawfields(); } void DiskMeter::getdiskinfo( void ) { total_ = _maxspeed; kstat_io_t kio; uint64_t read_curr = 0, write_curr = 0; _disks->update(_kc); IntervalTimerStop(); for (unsigned int i = 0; i < _disks->count(); i++) { if ( kstat_read(_kc, (*_disks)[i], &kio) == -1 ) continue; XOSDEBUG("%s: %llu bytes read %llu bytes written.\n", (*_disks)[i]->ks_name, kio.nread, kio.nwritten); read_curr += kio.nread; write_curr += kio.nwritten; } if (_read_prev == 0) _read_prev = read_curr; if (_write_prev == 0) _write_prev = write_curr; double t = IntervalTimeInSecs(); fields_[0] = (double)(read_curr - _read_prev) / t; fields_[1] = (double)(write_curr - _write_prev) / t; IntervalTimerStart(); _read_prev = read_curr; _write_prev = write_curr; if (fields_[0] < 0) fields_[0] = 0; if (fields_[1] < 0) fields_[1] = 0; if (fields_[0] + fields_[1] > total_) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - (fields_[0] + fields_[1]); setUsed(fields_[0] + fields_[1], total_); } xosview-1.20/sunos5/diskmeter.h000066400000000000000000000012671317735352700165570ustar00rootroot00000000000000// // Copyright (c) 1999 by Mike Romberg (romberg@fsl.noaa.gov) // // This file may be distributed under terms of the GPL // #ifndef _DISKMETER_H_ #define _DISKMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "kstats.h" #include class DiskMeter : public FieldMeterGraph { public: DiskMeter( XOSView *parent, kstat_ctl_t *kc, float max ); ~DiskMeter( void ); const char *name( void ) const { return "DiskMeter"; } void checkevent( void ); void checkResources( void ); protected: void getdiskinfo( void ); private: uint64_t _read_prev, _write_prev; float _maxspeed; kstat_ctl_t *_kc; KStatList *_disks; }; #endif xosview-1.20/sunos5/intratemeter.cc000066400000000000000000000032631317735352700174270ustar00rootroot00000000000000// // Copyright (c) 2014 by Tomi Tapper // // File based on bsd/intratemeter.* by // Copyright (c) 1999 by Brian Grayson (bgrayson@netbsd.org) // // This file may be distributed under terms of the GPL // // #include "intratemeter.h" #include IrqRateMeter::IrqRateMeter(XOSView *parent, kstat_ctl_t *kc) : FieldMeterGraph(parent, 2, "IRQs", "IRQs per sec/IDLE", 1, 1, 0) { _lastirqcount = 0; _kc = kc; _cpus = KStatList::getList(_kc, KStatList::CPU_SYS); } IrqRateMeter::~IrqRateMeter(void) { } void IrqRateMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("irqrateUsedColor")); setfieldcolor(1, parent_->getResource("irqrateIdleColor")); priority_ = atoi(parent_->getResource("irqratePriority")); dodecay_ = parent_->isResourceTrue("irqrateDecay"); useGraph_ = parent_->isResourceTrue("irqrateGraph"); SetUsedFormat(parent_->getResource("irqrateUsedFormat")); total_ = 2000; } void IrqRateMeter::checkevent(void) { getinfo(); drawfields(); } void IrqRateMeter::getinfo(void) { kstat_named_t *k; uint64_t irqcount = 0; _cpus->update(_kc); IntervalTimerStop(); for (size_t i = 0; i < _cpus->count(); i++) { if (kstat_read(_kc, (*_cpus)[i], NULL) == -1) { parent_->done(1); return; } k = (kstat_named_t *)kstat_data_lookup((*_cpus)[i], "intr"); if (k == NULL) { parent_->done(1); return; } irqcount += kstat_to_ui64(k); } if (_lastirqcount == 0) _lastirqcount = irqcount; fields_[0] = (irqcount - _lastirqcount) / IntervalTimeInSecs(); _lastirqcount = irqcount; IntervalTimerStart(); if (fields_[0] > total_) total_ = fields_[0]; setUsed(fields_[0], total_); } xosview-1.20/sunos5/intratemeter.h000066400000000000000000000013321317735352700172640ustar00rootroot00000000000000// // Copyright (c) 2014 by Tomi Tapper // // File based on bsd/intratemeter.* by // Copyright (c) 1999 by Brian Grayson (bgrayson@netbsd.org) // // This file may be distributed under terms of the GPL // // #ifndef _IRQRATEMETER_H_ #define _IRQRATEMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "kstats.h" #include class IrqRateMeter : public FieldMeterGraph { public: IrqRateMeter(XOSView *parent, kstat_ctl_t *kc); ~IrqRateMeter(void); const char *name(void) const { return "IrqRateMeter"; } void checkevent(void); void checkResources(void); protected: void getinfo(void); private: uint64_t _lastirqcount; kstat_ctl_t *_kc; KStatList *_cpus; }; #endif xosview-1.20/sunos5/kstats.h000066400000000000000000000072261317735352700161020ustar00rootroot00000000000000#ifndef _KStatList_H_ #define _KStatList_H_ #include #include #include #include #include #include #include // Helper to keep track of kstats. class KStatList { public: enum module { // module:instance:name (class) CPU_STAT, // *:*:cpu_stat* CPU_INFO, // *:*:cpu_info* CPU_SYS, // cpu:*:sys DISKS, // *:*:* (disk) NETS // {link,lo}:*:* (net) }; static KStatList *getList(kstat_ctl_t *kcp, module m) { switch (m) { case CPU_STAT: static KStatList cpu_stats(kcp, m); return &cpu_stats; case CPU_INFO: static KStatList cpu_infos(kcp, m); return &cpu_infos; case CPU_SYS: static KStatList cpu_sys(kcp, m); return &cpu_sys; case DISKS: static KStatList disks(kcp, m); return &disks; case NETS: static KStatList nets(kcp, m); return &nets; default: return NULL; } } kstat_t *operator[](size_t i) { return ( i < _stats.size() ? _stats[i] : NULL ); } size_t count(void) { return _stats.size(); } void update(kstat_ctl_t *kcp) { if (kstat_chain_update(kcp) > 0 || _chain != kcp->kc_chain_id) { XOSDEBUG("kstat chain id changed to %d\n", kcp->kc_chain_id); _chain = kcp->kc_chain_id; _stats.clear(); getstats(kcp); } } private: KStatList(const KStatList &); ~KStatList(void) {} KStatList &operator=(const KStatList &); KStatList(kstat_ctl_t *kcp, module m) { _chain = kcp->kc_chain_id; _m = m; getstats(kcp); } void getstats(kstat_ctl_t *kcp) { for (kstat_t *ksp = kcp->kc_chain; ksp != NULL; ksp = ksp->ks_next) { if (_m == CPU_STAT && strncmp(ksp->ks_name, "cpu_stat", 8) == 0) _stats.push_back(ksp); if (_m == CPU_INFO && strncmp(ksp->ks_name, "cpu_info", 8) == 0) _stats.push_back(ksp); if (_m == CPU_SYS && ksp->ks_type == KSTAT_TYPE_NAMED && strncmp(ksp->ks_module, "cpu", 3) == 0 && strncmp(ksp->ks_name, "sys", 3) == 0) _stats.push_back(ksp); if (_m == DISKS && ksp->ks_type == KSTAT_TYPE_IO && strncmp(ksp->ks_class, "disk", 4) == 0) _stats.push_back(ksp); if (_m == NETS && ksp->ks_type == KSTAT_TYPE_NAMED && strncmp(ksp->ks_class, "net", 3) == 0 && ( strncmp(ksp->ks_module, "link", 4) == 0 || strncmp(ksp->ks_module, "lo", 2) == 0 )) _stats.push_back(ksp); } } kid_t _chain; module _m; std::vector _stats; }; // Read the correct value from "named" type kstat. inline double kstat_to_double(kstat_named_t *k) { switch (k->data_type) { case KSTAT_DATA_INT32: return k->value.i32; case KSTAT_DATA_UINT32: return k->value.ui32; #if defined(_INT64_TYPE) case KSTAT_DATA_INT64: return k->value.i64; case KSTAT_DATA_UINT64: return k->value.ui64; #endif case KSTAT_DATA_FLOAT: return k->value.f; case KSTAT_DATA_DOUBLE: return k->value.d; case KSTAT_DATA_CHAR: case KSTAT_DATA_STRING: default: std::cerr << "kstat data type " << k->data_type << " can not be converted to number." << std::endl; exit(1); } } inline unsigned long long kstat_to_ui64(kstat_named_t *k) { switch (k->data_type) { case KSTAT_DATA_INT32: return k->value.i32; case KSTAT_DATA_UINT32: return k->value.ui32; #if defined(_INT64_TYPE) case KSTAT_DATA_INT64: return k->value.i64; case KSTAT_DATA_UINT64: return k->value.ui64; #endif case KSTAT_DATA_FLOAT: return k->value.f; case KSTAT_DATA_DOUBLE: return k->value.d; case KSTAT_DATA_CHAR: case KSTAT_DATA_STRING: default: std::cerr << "kstat data type " << k->data_type << " can not be converted to number." << std::endl; exit(1); } } #endif xosview-1.20/sunos5/loadmeter.cc000066400000000000000000000114331317735352700166760ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #include "loadmeter.h" #include #include #include #include #include #ifdef NO_GETLOADAVG #ifndef FSCALE #define FSCALE (1<<8) #endif #else #include #endif LoadMeter::LoadMeter(XOSView *parent, kstat_ctl_t *_kc) : FieldMeterGraph(parent, 2, "LOAD", "PROCS/MIN", 1, 1, 0) { kc = _kc; cpulist = KStatList::getList(kc, KStatList::CPU_INFO); #ifdef NO_GETLOADAVG ksp = kstat_lookup(kc, "unix", 0, "system_misc"); if (ksp == NULL) { parent_->done(1); return; } #endif total_ = -1; lastalarmstate = -1; old_cpu_speed = cur_cpu_speed = 0; } LoadMeter::~LoadMeter(void) { } void LoadMeter::checkResources(void) { FieldMeterGraph::checkResources(); warnloadcol = parent_->allocColor(parent_->getResource("loadWarnColor")); procloadcol = parent_->allocColor(parent_->getResource("loadProcColor")); critloadcol = parent_->allocColor(parent_->getResource("loadCritColor")); setfieldcolor(0, procloadcol); setfieldcolor(1, parent_->getResource("loadIdleColor")); priority_ = atoi (parent_->getResource("loadPriority")); dodecay_ = parent_->isResourceTrue("loadDecay"); useGraph_ = parent_->isResourceTrue("loadGraph"); SetUsedFormat(parent_->getResource("loadUsedFormat")); do_cpu_speed = parent_->isResourceTrue("loadCpuSpeed"); const char *warn = parent_->getResource("loadWarnThreshold"); if (strncmp(warn, "auto", 2) == 0) warnThreshold = sysconf(_SC_NPROCESSORS_ONLN); else warnThreshold = atoi(warn); const char *crit = parent_->getResource("loadCritThreshold"); if (strncmp(crit, "auto", 2) == 0) critThreshold = warnThreshold * 4; else critThreshold = atoi(crit); if (dodecay_){ /* * Warning: Since the loadmeter changes scale * occasionally, old decay values need to be rescaled. * However, if they are rescaled, they could go off the * edge of the screen. Thus, for now, to prevent this * whole problem, the load meter can not be a decay * meter. The load is a decaying average kind of thing * anyway, so having a decaying load average is * redundant. */ std::cerr << "Warning: The loadmeter can not be configured as a decay\n" << " meter. See the source code (" << __FILE__ << ") for further\n" << " details.\n"; dodecay_ = 0; } } void LoadMeter::checkevent(void) { getloadinfo(); if (do_cpu_speed) { getspeedinfo(); if (old_cpu_speed != cur_cpu_speed) { // update the legend: char l[32]; snprintf(l, 32, "PROCS/MIN %d MHz", cur_cpu_speed); legend(l); drawlegend(); } } drawfields(); } void LoadMeter::getloadinfo(void) { int alarmstate; #ifdef NO_GETLOADAVG // This code is mainly for Solaris 6 and earlier, but should work on // any version. kstat_named_t *k; if (kstat_read(kc, ksp, NULL) == -1) { parent_->done(1); return; } k = (kstat_named_t *)kstat_data_lookup(ksp, "avenrun_1min"); if (k == NULL) { parent_->done(1); return; } fields_[0] = kstat_to_double(k) / FSCALE; #else // getloadavg() if found on Solaris 7 and newer. getloadavg(&fields_[0], 1); #endif if (fields_[0] < warnThreshold) alarmstate = 0; else if (fields_[0] >= critThreshold) alarmstate = 2; else /* if fields_[0] >= warnThreshold */ alarmstate = 1; if (alarmstate != lastalarmstate) { if (alarmstate == 0) setfieldcolor(0, procloadcol); else if (alarmstate == 1) setfieldcolor(0, warnloadcol); else /* if alarmstate == 2 */ setfieldcolor(0, critloadcol); drawlegend(); lastalarmstate = alarmstate; } // Adjust total to next power-of-two of the current load. if ( (fields_[0]*5.0 < total_ && total_ > 1.0) || fields_[0] > total_ ) { unsigned int i = fields_[0]; i |= i >> 1; i |= i >> 2; i |= i >> 4; i |= i >> 8; i |= i >> 16; // i = 2^n - 1 total_ = i + 1; } fields_[1] = total_ - fields_[0]; setUsed(fields_[0], total_); } void LoadMeter::getspeedinfo(void) { unsigned int total_mhz = 0, i = 0; kstat_named_t *k; kstat_t *cpu; cpulist->update(kc); for (i = 0; i < cpulist->count(); i++) { cpu = (*cpulist)[i]; if (kstat_read(kc, cpu, NULL) == -1) { parent_->done(1); return; } // Try current_clock_Hz first (needs frequency scaling support), // then clock_MHz. k = (kstat_named_t *)kstat_data_lookup(cpu, "current_clock_Hz"); if (k == NULL) { k = (kstat_named_t *)kstat_data_lookup(cpu, "clock_MHz"); if (k == NULL) { std::cerr << "CPU speed is not available." << std::endl; parent_->done(1); return; } XOSDEBUG("Speed of cpu %d is %lld MHz\n", i, kstat_to_ui64(k)); total_mhz += kstat_to_ui64(k); } else { XOSDEBUG("Speed of cpu %d is %lld Hz\n", i, kstat_to_ui64(k)); total_mhz += ( kstat_to_ui64(k) / 1000000 ); } } old_cpu_speed = cur_cpu_speed; cur_cpu_speed = ( i > 0 ? total_mhz / i : 0 ); } xosview-1.20/sunos5/loadmeter.h000066400000000000000000000014241317735352700165370ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #ifndef _LOADMETER_H_ #define _LOADMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "kstats.h" #include class LoadMeter : public FieldMeterGraph { public: LoadMeter(XOSView *parent, kstat_ctl_t *kcp); ~LoadMeter(void); const char *name(void) const { return "LoadMeter"; } void checkevent(void); void checkResources(void); protected: void getloadinfo(void); void getspeedinfo(void); private: unsigned long procloadcol, warnloadcol, critloadcol; unsigned int warnThreshold, critThreshold; unsigned int old_cpu_speed, cur_cpu_speed; int lastalarmstate; bool do_cpu_speed; KStatList *cpulist; kstat_ctl_t *kc; #ifdef NO_GETLOADAVG kstat_t *ksp; #endif }; #endif xosview-1.20/sunos5/memmeter.cc000066400000000000000000000054431317735352700165410ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #include "memmeter.h" #include "kstats.h" #include #include #include MemMeter::MemMeter(XOSView *parent, kstat_ctl_t *_kc) : FieldMeterGraph(parent, 4, "MEM", "SYS/ZFS/OTHER/FREE") { kc = _kc; pageSize = sysconf(_SC_PAGESIZE); total_ = sysconf(_SC_PHYS_PAGES); ksp_sp = kstat_lookup(kc, "unix", 0, "system_pages"); ksp_zfs = kstat_lookup(kc, "vmem", -1, "zfs_file_data_buf"); if (ksp_sp == NULL) { // ZFS cache may be missing std::cerr << "Can not find unix:0:system_pages kstat." << std::endl; parent_->done(1); return; } } void MemMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("memKernelColor")); setfieldcolor(1, parent_->getResource("memCacheColor")); setfieldcolor(2, parent_->getResource("memUsedColor")); setfieldcolor(3, parent_->getResource("memFreeColor")); priority_ = atoi(parent_->getResource("memPriority")); dodecay_ = parent_->isResourceTrue("memDecay"); useGraph_ = parent_->isResourceTrue("memGraph"); SetUsedFormat(parent_->getResource("memUsedFormat")); } MemMeter::~MemMeter(void) { } void MemMeter::checkevent(void) { getmeminfo(); drawfields(); } void MemMeter::getmeminfo(void) { kstat_named_t *k; fields_[1] = 0; if (ksp_zfs) { if (kstat_read(kc, ksp_zfs, NULL) == -1) { std::cerr << "Can not read vmem::zfs_file_data_buf kstat." << std::endl; parent_->done(1); return; } k = (kstat_named_t *)kstat_data_lookup(ksp_zfs, "mem_inuse"); if (k == NULL) { std::cerr << "Can not read vmem::zfs_file_data_buf:mem_inuse kstat." << std::endl; parent_->done(1); return; } fields_[1] = kstat_to_double(k) / pageSize; } if (kstat_read(kc, ksp_sp, NULL) == -1) { std::cerr << "Can not read unix:0:system_pages kstat." << std::endl; parent_->done(1); return; } k = (kstat_named_t *)kstat_data_lookup(ksp_sp, "pp_kernel"); if (k == NULL) { std::cerr << "Can not read unix:0:system_pages:pp_kernel kstat." << std::endl; parent_->done(1); return; } fields_[0] = kstat_to_double(k) - fields_[1]; k = (kstat_named_t *)kstat_data_lookup(ksp_sp, "freemem"); if (k == NULL) { std::cerr << "Can not read unix:0:system_pages:freemem kstat." << std::endl; parent_->done(1); return; } fields_[3] = kstat_to_double(k); fields_[2] = total_ - (fields_[0] + fields_[1] + fields_[3]); XOSDEBUG("kernel: %llu kB zfs: %llu kB other: %llu kB free: %llu kB\n", (unsigned long long)(fields_[0] * pageSize / 1024), (unsigned long long)(fields_[1] * pageSize / 1024), (unsigned long long)(fields_[2] * pageSize / 1024), (unsigned long long)(fields_[3] * pageSize / 1024)); setUsed((fields_[0] + fields_[1] + fields_[2]) * pageSize, total_ * pageSize); } xosview-1.20/sunos5/memmeter.h000066400000000000000000000010301317735352700163670ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #ifndef _MEMMETER_H_ #define _MEMMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include class MemMeter : public FieldMeterGraph { public: MemMeter(XOSView *parent, kstat_ctl_t *kcp); ~MemMeter(void); const char *name(void) const { return "MemMeter"; } void checkevent( void ); void checkResources(void); protected: void getmeminfo( void ); private: int pageSize; kstat_ctl_t *kc; kstat_t *ksp_sp, *ksp_zfs; }; #endif xosview-1.20/sunos5/netmeter.cc000066400000000000000000000115451317735352700165510ustar00rootroot00000000000000// // Rewritten for Solaris by Arno Augustin 1999 // augustin@informatik.uni-erlangen.de // #include "netmeter.h" #include #include #include #include #include #include #include #include #ifdef DEBUG #include #endif NetMeter::NetMeter( XOSView *parent, kstat_ctl_t *kc, float max ) : FieldMeterGraph( parent, 3, "NET", "IN/OUT/IDLE" ){ _kc = kc; _ignored = false; _maxpackets = max; _lastBytesIn = _lastBytesOut = 0; _nets = KStatList::getList(_kc, KStatList::NETS); if ( (_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { std::cerr << "Opening socket failed." << std::endl; parent_->done(1); return; } } NetMeter::~NetMeter( void ){ close(_socket); } void NetMeter::checkResources( void ){ FieldMeterGraph::checkResources(); setfieldcolor( 0, parent_->getResource("netInColor") ); setfieldcolor( 1, parent_->getResource("netOutColor") ); setfieldcolor( 2, parent_->getResource("netBackground") ); priority_ = atoi( parent_->getResource("netPriority") ); dodecay_ = parent_->isResourceTrue("netDecay"); useGraph_ = parent_->isResourceTrue("netGraph"); SetUsedFormat( parent_->getResource("netUsedFormat") ); _netIface = parent_->getResource("netIface"); if (_netIface[0] == '-') { _ignored = true; _netIface.erase(0, _netIface.find_first_not_of("- ")); } } void NetMeter::checkevent( void ){ getnetstats(); drawfields(); } void NetMeter::getnetstats( void ){ uint64_t nowBytesIn = 0, nowBytesOut = 0; kstat_named_t *k; kstat_t *ksp; total_ = _maxpackets; _nets->update(_kc); IntervalTimerStop(); for (unsigned int i = 0; i < _nets->count(); i++) { #ifdef DEBUG std::stringstream msg; #endif ksp = (*_nets)[i]; if ( _netIface != "False" && ( (!_ignored && ksp->ks_name != _netIface) || ( _ignored && ksp->ks_name == _netIface) ) ) continue; if ( kstat_read(_kc, ksp, NULL) == -1 ) continue; #ifdef DEBUG msg << ksp->ks_name << ": "; #endif // try 64-bit byte counter first, then 32-bit one, then packet counter if ( (k = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes64")) == NULL ) { if ( (k = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes")) == NULL ) { if ( (k = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets")) == NULL ) continue; // for packet counter, mtu is needed strncpy(_lfr.lifr_name, ksp->ks_name, sizeof(_lfr.lifr_name)); if ( ioctl(_socket, SIOCGLIFMTU, (caddr_t)&_lfr) < 0 ) continue; nowBytesIn += kstat_to_ui64(k) * _lfr.lifr_mtu; // not exactly, but must do #ifdef DEBUG msg << kstat_to_ui64(k) << " packets received "; #endif } else { nowBytesIn += kstat_to_ui64(k); #ifdef DEBUG msg << kstat_to_ui64(k) << " bytes received "; #endif } } else { nowBytesIn += kstat_to_ui64(k); #ifdef DEBUG msg << kstat_to_ui64(k) << " bytes received "; #endif } if ( (k = (kstat_named_t *)kstat_data_lookup(ksp, "obytes64")) == NULL ) { if ( (k = (kstat_named_t *)kstat_data_lookup(ksp, "obytes")) == NULL ) { if ( (k = (kstat_named_t *)kstat_data_lookup(ksp, "opackets")) == NULL ) continue; strncpy(_lfr.lifr_name, ksp->ks_name, sizeof(_lfr.lifr_name)); if ( ioctl(_socket, SIOCGLIFMTU, (caddr_t)&_lfr) < 0 ) continue; nowBytesOut += kstat_to_ui64(k) * _lfr.lifr_mtu; #ifdef DEBUG msg << kstat_to_ui64(k) << " packets sent "; #endif } else { nowBytesOut += kstat_to_ui64(k); #ifdef DEBUG msg << kstat_to_ui64(k) << " bytes sent "; #endif } } else { nowBytesOut += kstat_to_ui64(k); #ifdef DEBUG msg << kstat_to_ui64(k) << " bytes sent "; #endif } #ifdef DEBUG msg << std::ends; XOSDEBUG("%s\n", msg.str().c_str()) #endif } uint64_t correction = 0x10000000; correction *= 0x10; /* Deal with 32-bit wrap by making last value 2^32 less. Yes, * this is a better idea than adding to nowBytesIn -- the * latter would only work for the first wrap (1+2^32 vs. 1) * but not for the second (1+2*2^32 vs. 1) -- 1+2^32 - * (1+2^32) is still too big. */ if (nowBytesIn < _lastBytesIn) _lastBytesIn -= correction; if (nowBytesOut < _lastBytesOut) _lastBytesOut -= correction; if(_lastBytesIn == 0) _lastBytesIn = nowBytesIn; if(_lastBytesOut == 0) _lastBytesOut = nowBytesOut; double t = IntervalTimeInSecs(); fields_[0] = (double)(nowBytesIn - _lastBytesIn) / t; fields_[1] = (double)(nowBytesOut - _lastBytesOut) / t; IntervalTimerStart(); _lastBytesIn = nowBytesIn; _lastBytesOut = nowBytesOut; if (total_ < fields_[0] + fields_[1]) total_ = fields_[0] + fields_[1]; fields_[2] = total_ - fields_[0] - fields_[1]; setUsed(fields_[0] + fields_[1], total_); } xosview-1.20/sunos5/netmeter.h000066400000000000000000000014341317735352700164070ustar00rootroot00000000000000// // Copyright (c) 1994, 1995 by Mike Romberg ( romberg@fsl.noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _NETMETER_H_ #define _NETMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "kstats.h" #include #include #include class NetMeter : public FieldMeterGraph { public: NetMeter( XOSView *parent, kstat_ctl_t *kc, float max ); ~NetMeter( void ); const char *name( void ) const { return "NetMeter"; } void checkevent( void ); void checkResources( void ); protected: void getnetstats( void ); private: float _maxpackets; uint64_t _lastBytesIn, _lastBytesOut; kstat_ctl_t *_kc; KStatList *_nets; std::string _netIface; bool _ignored; struct lifreq _lfr; int _socket; }; #endif xosview-1.20/sunos5/pagemeter.cc000066400000000000000000000035611317735352700166760ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #include "pagemeter.h" #include #include PageMeter::PageMeter(XOSView *parent, kstat_ctl_t *_kc, float max) : FieldMeterGraph( parent, 3, "PAGE", "IN/OUT/IDLE") { kc = _kc; for (int i = 0 ; i < 2 ; i++) for (int j = 0 ; j < 2 ; j++) pageinfo_[j][i] = 0; maxspeed_ = max; pageindex_ = 0; cpustats = KStatList::getList(kc, KStatList::CPU_STAT); } PageMeter::~PageMeter(void) { } void PageMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("pageInColor")); setfieldcolor(1, parent_->getResource("pageOutColor")); setfieldcolor(2, parent_->getResource("pageIdleColor")); priority_ = atoi(parent_->getResource("pagePriority")); maxspeed_ *= priority_ / 10.0; dodecay_ = parent_->isResourceTrue("pageDecay"); useGraph_ = parent_->isResourceTrue("pageGraph"); SetUsedFormat(parent_->getResource("pageUsedFormat")); } void PageMeter::checkevent(void) { getpageinfo(); drawfields(); } void PageMeter::getpageinfo(void) { cpu_stat_t cs; total_ = 0; pageinfo_[pageindex_][0] = 0; // pgin pageinfo_[pageindex_][1] = 0; // pgout cpustats->update(kc); for (unsigned int i = 0; i < cpustats->count(); i++) { if (kstat_read(kc, (*cpustats)[i], &cs) == -1) continue; pageinfo_[pageindex_][0] += cs.cpu_vminfo.pgpgin; pageinfo_[pageindex_][1] += cs.cpu_vminfo.pgpgout; } int oldindex = (pageindex_ + 1) % 2; for (int i = 0; i < 2; i++) { if (pageinfo_[oldindex][i] == 0) pageinfo_[oldindex][i] = pageinfo_[pageindex_][i]; fields_[i] = pageinfo_[pageindex_][i] - pageinfo_[oldindex][i]; total_ += fields_[i]; } if (total_ > maxspeed_) fields_[2] = 0.0; else { fields_[2] = maxspeed_ - total_; total_ = maxspeed_; } setUsed(total_ - fields_[2], maxspeed_); pageindex_ = (pageindex_ + 1) % 2; } xosview-1.20/sunos5/pagemeter.h000066400000000000000000000011401317735352700165270ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #ifndef _PAGEMETER_H_ #define _PAGEMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include "kstats.h" #include class PageMeter : public FieldMeterGraph { public: PageMeter(XOSView *parent, kstat_ctl_t *kcp, float max); ~PageMeter(void); const char *name(void) const { return "PageMeter"; } void checkevent(void); void checkResources(void); protected: float pageinfo_[2][2]; int pageindex_; float maxspeed_; void getpageinfo(void); private: KStatList *cpustats; kstat_ctl_t *kc; }; #endif xosview-1.20/sunos5/swapmeter.cc000066400000000000000000000041241317735352700167300ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #include "swapmeter.h" #include #include #include #include #include #include SwapMeter::SwapMeter(XOSView *parent, kstat_ctl_t *_kc) : FieldMeterGraph(parent, 2, "SWAP", "USED/FREE") { pagesize = sysconf(_SC_PAGESIZE); } SwapMeter::~SwapMeter(void) { } void SwapMeter::checkResources(void) { FieldMeterGraph::checkResources(); setfieldcolor(0, parent_->getResource("swapUsedColor")); setfieldcolor(1, parent_->getResource("swapFreeColor")); priority_ = atoi(parent_->getResource("swapPriority")); dodecay_ = parent_->isResourceTrue("swapDecay"); useGraph_ = parent_->isResourceTrue("swapGraph"); SetUsedFormat(parent_->getResource("swapUsedFormat")); } void SwapMeter::checkevent(void) { getswapinfo(); drawfields(); } void SwapMeter::getswapinfo(void) { swaptbl_t *swaps; char *names; total_ = fields_[0] = fields_[1] = 0; int numswap = swapctl(SC_GETNSWP, NULL); if (numswap < 0) { std::cerr << "Can not determine number of swap spaces." << std::endl; parent_->done(1); return; } if (numswap > 0) { swaps = (swaptbl_t *)malloc(sizeof(swaptbl_t) + numswap * sizeof(swapent_t)); names = (char *)calloc(numswap + 1, PATH_MAX); if (!swaps || !names) { std::cerr << "malloc failed." << std::endl; parent_->done(1); return; } swaps->swt_n = numswap; for (int i = 0; i <= numswap; i++) swaps->swt_ent[i].ste_path = names + (i * PATH_MAX); if (swapctl(SC_LIST, swaps) < 0) { std::cerr << "Can not get list of swap spaces." << std::endl; parent_->done(1); return; } for (int i = 0; i < numswap; i++) { total_ += swaps->swt_ent[i].ste_pages; fields_[1] += swaps->swt_ent[i].ste_free; XOSDEBUG("%s: %ld kB (%ld kB free)\n", swaps->swt_ent[i].ste_path, swaps->swt_ent[i].ste_pages * (pagesize / 1024), swaps->swt_ent[i].ste_free * (pagesize / 1024)); } fields_[0] = total_ - fields_[1]; free(swaps); free(names); } setUsed(fields_[0] * pagesize, total_ * pagesize); } xosview-1.20/sunos5/swapmeter.h000066400000000000000000000007621317735352700165760ustar00rootroot00000000000000// // Initial port performed by Greg Onufer (exodus@cheers.bungi.com) // #ifndef _SWAPMETER_H_ #define _SWAPMETER_H_ #include "fieldmetergraph.h" #include "xosview.h" #include class SwapMeter : public FieldMeterGraph { public: SwapMeter(XOSView *parent, kstat_ctl_t *kcp); ~SwapMeter(void); const char *name(void) const { return "SwapMeter"; } void checkevent(void); void checkResources(void); protected: void getswapinfo(void); private: size_t pagesize; }; #endif xosview-1.20/targets/000077500000000000000000000000001317735352700146265ustar00rootroot00000000000000xosview-1.20/targets/dragonflybsd000066400000000000000000000002051317735352700172240ustar00rootroot00000000000000PLATFORM = bsd CPPFLAGS += -I/usr/pkg/include -I/usr/local/include LDLIBS += -lkvm -lkinfo -ldevstat -L/usr/pkg/lib -L/usr/local/lib xosview-1.20/targets/freebsd000066400000000000000000000001461317735352700161640ustar00rootroot00000000000000PLATFORM = bsd CXX = c++ CPPFLAGS += -I/usr/local/include LDFLAGS += -ldevstat -lkvm -L/usr/local/lib xosview-1.20/targets/netbsd000066400000000000000000000001631317735352700160300ustar00rootroot00000000000000PLATFORM = bsd CPPFLAGS += -I/usr/X11R7/include LDLIBS += -lkvm -lprop -L/usr/X11R7/lib -Wl,--rpath=/usr/X11R7/lib xosview-1.20/targets/openbsd000066400000000000000000000001211317735352700161750ustar00rootroot00000000000000PLATFORM = bsd CPPFLAGS += -I/usr/X11R6/include LDLIBS += -lkvm -L/usr/X11R6/lib xosview-1.20/timer.h000066400000000000000000000023701317735352700144500ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _TIMER_H_ #define _TIMER_H_ // // General purpose interval timer class // // Implemented using BSD derived function gettimeofday for greater resolution // // Author : Mike Romberg #include "timeval.h" #include #include class Timer { public: Timer( int start = 0 ) { if ( start ) Timer::start(); } ~Timer( void ){} void start( void ) { gettimeofday( &starttime_, NULL ); } void stop( void ) { gettimeofday( &stoptime_, NULL ); } // This one uses doubles as the return value, to avoid // overflow/sign problems. double report_usecs(void) const { return (stoptime_.tv_sec - starttime_.tv_sec) * 1000000.0 + stoptime_.tv_usec - starttime_.tv_usec; } std::ostream &printOn(std::ostream &os) const { return os <<"Timer : [" <<"starttime_ = " < #include class TimeVal { public: TimeVal(unsigned long sec = 0, unsigned long usec = 0) { _val.tv_sec = (int)sec; _val.tv_usec = usec; } TimeVal(const struct timeval &val) { _val = val; } unsigned long sec(void) const { return _val.tv_sec; } unsigned long usec(void) const { return _val.tv_usec; } void sec(unsigned long s) { _val.tv_sec = (int)s; } void usec(unsigned long us) { _val.tv_usec = us; } operator struct timeval(void) const { return _val; } std::ostream &printOn(std::ostream &os) const { return os <<"(" < where one will invoke this macro with .xx .\" The macro definition ends with the .. line. .\" I don't know what macro abbreviations are free, so I just chose a few, .\" and haven't noticed a problem so far! bgrayson .\" There are several paragraphs that are repeated in the resource section. .\" Rather than typing the whole stuff out each time, we define a few macros. .\" The .pp macro takes a single argument (net, disk, etc), and .\" prints a paragraph description of a Priority resource. Only the .\" header (xosview*diskPriority: \fIpriority\fP) needs to be specified in .\" addition to the .pp macro. .\" Usage: .pp load .de pp xosview*\\$1Priority: \fIpriority\fP .RS This number (which must be an integer >= 1) sets the number of tenths of a second that the \\$1 meter waits between updates. A value of 1 has xosview update the meter 10 times per second (the fastest). A value of 600 would cause xosview to update the meter once a minute. .RE .. .\" The .dc macro is similar to the .pp macro, except that it is for .\" the decay resource paragraphs. .\" Usage: .dc net .de dc xosview*\\$1Decay: (True or False) .RS If True then the \\$1 meter will be split vertically in two. The top half will show the instantaneous state, while the bottom half will display a decaying average of the state. .RE .. .\" The .dg macro is similar to the .dc macro, except that it is for .\" the scrolling graph resource paragraphs. .\" Usage: .dg net .de dg xosview*\\$1Graph: (True or False) .RS If this is set to True then the \\$1 meter will be drawn as a horizontally scrolling bargraph showing the state value verses time. .RE .. .\" The .pm macro is for ``plus/minus'' -- for the .\" enable/disable command-line options. .de pm -\\$1 .RS This option overrides the xosview*\\$1 resource. It is equivalent to setting xosview*\\$1 to "False". .RE +\\$1 .RS This option overrides the xosview*\\$1 resource. It is equivalent to setting xosview*\\$1 to "True". .RE .. .\" The .xt macro is for ``Xresource true'' -- for enabling a .\" meter, like the .pm macro/-+foo. .de xt xosview*\\$1: (True or False) .RS If True then xosview will display a \\$1 meter. .RE .. .\" The .uf macro is for the ``used format'' stuff. .de uf xosview*\\$1UsedFormat: (float, percent or autoscale) .RS This resource tells xosview how to display "used" labels. The formats work as follows: \fBfloat\fP: .RS Display the value as a floating point number. .RE \fBpercent\fP: .RS Display the value as a percentage of the total. .RE \fBautoscale\fP: .RS Display the absolute value and automatically print the units (K, M, or G) as appropriate. .RE .RE .. .\" Define a color macro for the various xosview*fooXXXColor: resources. .\" Usage: .cc swap Used used "swap space" <-- keep 'swap \" space' as one arg. .de cc xosview*\\$1\\$2Color: \fIcolor\fP .RS The \\$1 meter will use this color to display the \\$3 field. .RE .. .\" ================ End of Macros ============================= .SH DESCRIPTION \fIxosview\fP is a monitor which displays the status of several system parameters. These include CPU usage, load average, memory, swap space, network usage and more. Each resource is displayed as a horizontal bar which is separated into color coded regions showing how much of the resource is being put to a particular use. \fIxosview\fP runs on several platforms (Linux, NetBSD, FreeBSD, OpenBSD, DragonflyBSD, some Solaris systems, IRIX 6.5, HPUX and GNU). Not all of the meters described below are supported on all platforms. Some of the meters may appear different depending upon the platform \fIxosview\fP is running on. Note that *BSD is used as an abbreviation for all the supported BSD operating systems (NetBSD, FreeBSD, OpenBSD, DragonflyBSD). \fBLoad\fP: Kernel reported load average all platforms : load Linux : load | CPU frequency *BSD : load | CPU frequency SunOS5 : load | CPU frequency \fBCPU Usage\fP Linux : user | nice | system | soft-interrupt | interrupt | io-wait | guest | niced guest | stolen | idle *BSD : user | nice | system | interrupt | idle SunOS5 : user | system | wait | idle IRIX : user | system | interrupt | wait | idle HPUX : user | nice | system | interrupt | idle \fBMemory Usage\fP Linux : used | buffers | slab | map | cache | free FreeBSD: active | inactive | wired | cache | free DFBSD : active | inactive | wired | cache | free OpenBSD: active | inactive | wired | free NetBSD : active | inactive | wired | free SunOS5 : kernel | zfs | other | free IRIX : kernel | fs | user | free HPUX : text | used | other | free GNU : active | inactive | wired | free \fBSwap Usage\fP Linux : used | free *BSD : used | free SunOS5 : used | free HPUX : used | free GNU : used | free \fBDisk Usage\fP: Throughput to/from local disk, per second Linux : in | out | idle *BSD : in | out | idle SunOS5 : in | out | idle \fBPage Swapping\fP: Pages to/from swap, per second Linux : in | out | idle *BSD : in | out | idle SunOS5 : in | out | idle HPUX : in | out | idle GNU : in | out | idle \fBNetwork Usage\fP Linux : in | out | idle *BSD : in | out | idle SunOS5 : in | out | idle \fBGFX Usage\fP: Framebuffer exchanges, per second IRIX : swapbuffers \fBInterrupts\fP: "leds" which blink when an interrupt occurs Linux : IRQs *BSD : IRQs \fBInterrupt Rate\fP: Per second Linux : interrupts | free *BSD : interrupts | free SunOS5 : interrupts | free \fBSerial Port Status\fP: "leds" which show the serial port parameters Linux : LSR and MSR \fBBattery Level\fP: charge and status of batteries Linux : available | used *BSD : available | used \fBRAID\fP: State of disks in a software RAID array Linux : disk0 disk1 disk2 ... diskN | rebuild \fBWireless Link\fP Linux : quality \fBSensors\fP: Readings from sensors Linux : I2C/hwmon sensors (lmstemp) Intel Core/AMD K8+/VIA C7 temperature (coretemp) ACPI thermal zones (acpitemp) *BSD : I2C sensors (bsdsensor) Intel Core/AMD K8+ temperature (coretemp) Typing a 'q' in the window will terminate xosview. .SH OPTIONS Most of these command line options are just a convenient way to set one or more of \fIxosview\fP's resources. Please see the \fBRESOURCES\fP section for more details on what the resource is for. \-v .RS Displays the version number. .RE \-name \fIname\fP .RS Sets the Resource name xosview will use (same as the \-name option for typical X applications like xterm). When performing resource lookups, xosview will look under \fIname\fP, and then under ``xosview''. For an example, perform the following (as documented in README.netbsd): .RS xrdb \-merge Xdefaults.stipple xosview \-name xosvstipple & xosview \-name xosvstipplebw & .RE .RE \-display \fIdisplay\fP .RS Sets the X display to \fIdisplay\fP. This option overrides the xosview*display resource. .RE \-font \fIfont\fP .RS Specifies the font xosview will use for labels. This option overrides the xosview*font resource. .RE \-title \fItitle\fP .RS This option sets the name xosview will tell the window manager to use for the X window and icon. This option overrides the xosview*title resource. .RE \-geometry \fIgeometry_string\fP .RS Sets the X geometry to \fIgeometry_string\fP. This option overrides the xosview*geometry resource. .RE .pm captions .pm labels .pm usedlabels .pm cpu \-cpus .RS Force the display of a single meter for all CPUs in the system. This option is equivalent to setting xosview*cpuFormat to "single". .RE \+cpus .RS Force the display of all CPUs in the system. This option is equivalent to setting xosview*cpuFormat to "all". .RE .pm load .pm mem .pm swap .pm battery .pm gfx .pm wireless .pm net \-network \fImaxbandwidth\fP .RE \-networkBW \fImaxbandwidth\fP .RE \-networkBandwidth \fImaxbandwidth\fP .RS These options override the xosview*netBandwidth resource. They cause xosview to display a meter that will shows network usage, with a maximum bandwidth of \fBmaxbandwidth\fP. Notice that setting the bandwidth to 0 no longer disables the meter \-\- use the ``\-net'' option instead. .RE .pm page \-pagespeed \fIval\fP .RS This option overrides the xosview*pageBandWidth resource. The resource xosview*pageBandWidth will be set to \fIval\fP. .RE .pm disk .pm int \-ints +ints .RE \-interrupts +interrupts .RS Equivalent to \-int and +int. .RE .pm irqrate \-intrate +intrate .RS Equivalent to \-irqrate and +irqrate. .RE .pm lmstemp .pm coretemp .pm acpitemp .pm bsdsensor .RE \-xrm \fIresource_string\fP .RS This switch allows any of xosview's resources to be set on the command line. An example of how the xosview*memFreeColor could be set using this option is shown below (Note the use of " to prevent the shell from expanding \'*\' or from creating two separate arguments, \'xosview*memfreeColor:\' and \'purple\'): .RS \-xrm "xosview*memFreeColor: purple" .RE .RE .SH X RESOURCES The following is a list of X resources supported by \fIxosview\fP. Each has a default value assigned to it. These values can be found in the file Xdefaults which can be obtained in the source distribution of xosview. They can be overridden in the usual places (/usr/lib/X11/app-defaults/XOsview, $HOME/.Xdefaults, etc.). It should be noted that it is OK to have a resource defined for a port of xosview that does not support the feature the resource configures. Xosview will simply ignore the resources that are set for it but not supported on a given platform. \fBGeneral Resources\fP xosview*title: \fIname\fP .RS The string that xosview will use for the X window title. Normally xosview will use 'xosview@machine_name' for a title. This resource overrides the default behavior. .RE xosview*geometry: \fIgeometry_string\fP .RS This is a standard X geometry string that defines the size and location of the X window used by xosview. .RE xosview*display: \fIname\fP .RS The name of the display where xosview will contact the X server for drawing its window. .RE xosview*pixmapName: \fIname\fP .RS The filename of an X pixmap (xpm) file for use as a background image. .RE xosview*captions: (True or False) .RS If True then xosview will display meter captions. .RE xosview*labels: (True or False) .RS If True then xosview will display meter labels. .RE xosview*meterLabelColor: \fIcolor\fP .RS The color to use for the meter labels. .RE xosview*usedlabels: (True or False) .RS If True then xosview will display labels that show the percentage of the resource (or absolute amount, depending on the meter) being used. This option requires that the labels option also be set to True. .RE xosview*usedLabelColor: \fIcolor\fP .RS The color to use for "used" labels. .RE xosview*borderwidth: \fIwidth\fP .RS The width of the border for the xosview window. .RE xosview*font: \fIfont\fP .RS This is the font that xosview will use. .RE xosview*background: \fIcolor\fP .RS This is the color that will be used for the background. .RE xosview*foreground: \fIcolor\fP .RS This is the color that will be used for the foreground. .RE xosview*enableStipple: (True or False) .RS Change to true to try stipple support. This is primarily for users stuck with 1-bit monitors/display cards. Try setting enableStipple true. Please give us feedback on this, if you use it. It needs some more work, but no one has given us any feedback so far. .RE xosview*graphNumCols: \fInumber\fP .RS This defines the number of sample bars drawn when a meter is in scrolling graph mode. This also has the side-effect of defining the width of the graph columns. This is only used by meters which have graph mode enabled. .RE \fBLoad Meter Resources\fP .\" Do the load: True resource. .xt load xosview*loadProcColor: \fIcolor\fP .RS This is the color that the load meter will use to display the load average when it is below the warning threshold. .RE xosview*loadWarnColor: \fIcolor\fP .RS This is the color that the load meter will use once the load average is above the warning but below the critical load threshold. .RE xosview*loadCritColor: \fIcolor\fP .RS This is the color that the load meter will use once the load average is above critical load threshold. .RE .\" loadIdleColor .cc load Idle idle .\" Do the priority resource .pp load xosview*loadWarnThreshold: \fIint\fP .RS This number (which must be an integer >= 1) sets the value at which the loadmeter changes its status and color from "normal" to "warning". The default value is the number of processors. .RE xosview*loadCritThreshold: \fIint\fP .RS This number (which must be an integer >= 1) sets the value at which the loadmeter changes its status and color from "warning" to "critical". The default value is four times the warning threshold. .RE xosview*loadDecay: (True or False) .RS You should probably leave this at the default value (False). The load is already a time-averaged value! .RE .dg load .\" loadUsedFormat resource .uf load xosview*loadCpuSpeed: (True or False) .RS Display the current CPU speed in the load meter. .RE \fBCPU Meter Resources\fP xosview*cpu: (True or False) .RS If True then xosview will display a cpu meter. On Linux, *BSD, Solaris and IRIX SMP machines, the resource cpuFormat defines how meters are created for multiple CPUs. .RE .\" cpuUserColor, cpuNiceColor, cpuSystemColor, cpuInterruptColor, cpuFreeColor .cc cpu User "cpu user time" .cc cpu Nice "cpu nice time" .cc cpu System "cpu system time" .cc cpu Interrupt "cpu hard interrupt time" .cc cpu SInterrupt "cpu soft interrupt time" .cc cpu Wait "cpu IO waiting time" .cc cpu Guest "cpu virtualization guest time" .cc cpu NiceGuest "cpu niced virtualization guest time" .cc cpu Stolen "cpu involuntary wait time" .cc cpu Free "cpu idle time" .\" Priority, decay, usedFormat resources: .pp cpu .dc cpu .dg cpu .uf cpu xosview*cpuFormat: (single, all, both or auto) .RS If `single', only a cumulative meter for all CPU usage is created. `all' creates a meter for each CPU, but no cumulative meter. `both' creates one cumulative meter and one for each CPU. `auto' makes a choice based on the number of CPUs found. .RE xosview*cpuFields: USED/USR/NIC/SYS/INT/SI/HI/WIO/GST/NGS/STL/IDLE .RS The set of fields to show in Linux CPU meter instead of the default. Possible fields are: \fBUSED\fP: .RS Combine all used CPU time into one field. This is the sum of user, nice, system, soft and hard interrupts, guest, niced guest and stolen times. None of these, except stolen, may be defined together with `USED'. .RE \fBIDLE\fP: .RS Time spent doing nothing. Includes I/O wait if it is not defined separately. .RE \fBUSR\fP: .RS Time spent in user mode processes. Includes nice, guest and niced guest if those are not defined separately. .RE \fBNIC\fP: .RS Time spent in niced user mode processes. Includes niced guest if neither it nor guest is not defined separately. .RE \fBSYS\fP: .RS Time spent in kernel code. Includes soft and hard interrupt as well as stolen time if those are not defined separately. .RE \fBINT\fP: .RS Combines soft and hard interrupt handling times into one field. .RE \fBSI\fP: .RS Time the kernel used to handle soft interrupts. Available on Linux kernel 2.6.0 and higher. .RE \fBHI\fP: .RS Time the kernel used to handle hard interrupts. Available on Linux kernel 2.6.0 and higher. .RE \fBWIO\fP: .RS Time spent waiting for I/O to complete. Available on Linux kernel 2.6.0 and higher. .RE \fBGST\fP: .RS Time spent running guest OS in virtual machine. Includes niced guest if it is not defined separately. Available on Linux kernel 2.6.24 and higher. .RE \fBNGS\fP: .RS Time spent running niced guest OS in virtual machine. Available on Linux kernel 2.6.32 and higher. .RE \fBSTL\fP: .RS Involuntary wait time when running as guest in virtual machine. Available on Linux kernel 2.6.11 and higher. .RE Most combinations are possible (see above for restrictions), but at least `USED' or `USR' and `SYS' need to be defined. `IDLE' field is added automatically. .RE \fBMemory Meter Resources\fP .\" Do the mem: True resource. .xt mem .\" mem{Used,Share,Buffer,...}Color resources .cc mem Used "used memory" .cc mem Shared "shared memory" .cc mem Buffer "buffer memory" .cc mem Cache "cache memory" .cc mem Free "free memory" .cc mem Kernel "kernel memory" .cc mem Shared "shared memory" .cc mem Text "HP text memory" .cc mem Other "HP ``other'' memory" .cc mem Active "*BSD active memory" .cc mem Inactive "*BSD inactive memory" .cc mem Wired "*BSD wired memory" .cc mem Slab "Linux in-kernel data structures" .cc mem Map "Linux memory mapped files" .\" Priority, decay, usedFormat resources: .pp mem .dc mem .dg mem .uf mem \fBSwap Meter Resources\fP .\" Do the swap: True resource. .xt swap .\" swap{Used,Free}Color resources. .cc swap Used "used swap" .cc swap Free "free swap" .\" Priority, decay, usedFormat resources: .pp swap .dc swap .dg swap .uf swap \fBPage Swapping Meter Resources\fP .\" Do the page: True resource. .xt page xosview*pageBandWidth: \fImaxEvents\fP .RS This number is used to specify the expected maximum bandwidth (in events / sec) for the page meter. When the expected maximum bandwidth (\fImaxEvents\fP) is exceeded then the page meter will display the relative percentage of page swapping (25% in, 75% out). .RE .\" page{In,Out,Idle}Color: .cc page In page-in .cc page Out page-out .cc page Idle idle .\" Priority, decay, usedFormat resources: .pp page .dc page .dg page .uf page \fBGfx Meter Resources\fP xosview*gfx: (True or False) .RS If True xosview will display the GfxMeter. The value is sampled once per second, due to the usage of sadc to sample data. .RE xosview*gfxWarnColor: \fIcolor\fP .RS This is the color that the gfx meter will use once the warn state is reached. .RE xosview*gfxAlarmColor: \fIcolor\fP .RS This is the color that the gfx meter will use once the alarm state is reached. .RE xosview*gfxSwapColor: \fIcolor\fP .RS This is the color that the gfx meter will use in normal state .RE .\" gfxIdleColor .cc gfx Idle idle .\" Do the priority resource .pp gfx xosview*gfxWarnThreshold: \fIint\fP .RS This number (which must be an integer >= 1) of swapbuffers per second and pipe at which the gfxmeter changes its status and color from "normal" to "warn". The default value is 60. .RE xosview*gfxAlarmThreshold: \fIint\fP .RS This number (which must be an integer >= gfxWarnThreshold) of swapbuffers per second and pipe at which the gfxmeter changes its status and color from "warn" to "alarm". The default value is 120. .RE xosview*gfxDecay: (True or False) .RS You should probably leave this at the default value (False). The gfx does not work in decay mode. .RE .dg gfx .\" gfxUsedFormat resource .uf gfx \fBNetwork Meter Resources\fP xosview*net: (True or False) .RS If True xosview will display the NetMeter. Linux users will have to configure their kernels and setup some ip accounting rules to make this work. See the file README.linux which comes with the xosview distribution for details. .RE xosview*netBandwidth: \fImaxBytes\fP .RS This number is used to specify the expected maximum bandwidth (in bytes / sec) for the meter. When the expected maximum bandwidth (\fImaxBytes\fP) is exceeded then the network meter will display the relative percentage of network usage (25% incoming, 75% outgoing). .RE xosview*netIface: \fIinterface\fP .RS If False, xosview will display the data received/transmitted by any of the network interfaces. Otherwise, xosview will only display the data received/transmitted by the specified network interface. If the name is prepended with '-' sign, the data in that interface is ignored. .RE .\" net{In,Out}Color: .cc net In incoming .cc net Out outgoing .\" FIXME XXX Change the netBackground resource to be netIdleColor. xosview*netBackground: \fIcolor\fP .RS This is the color that the network meter will use for the "idle" field. .RE .\" Priority, decay, usedFormat resources: .pp net .dc net .dg net .uf net \fBNFSStats (Client) Resources\fP xosview*NFSStats: (True or False) .RS If True then xosview will display a meter to monitor NFS client stats. .RE xosview*NFSStatReTransColor: \fIcolor\fP .RS The color to be used for retransmit stats. .RE xosview*NFSStatAuthRefrshColor: \fIcolor\fP .RS The color to be used for auth refresh stats. .RE xosview*NFSStatCallsColor: \fIcolor\fP .RS The color to be used for call stats. .RE xosview*NFSStatIdleColor: \fIcolor\fP .RS The color to be used for idle stats. .RE \fBNFSDStats (Server) Resources\fP xosview*NFSDStats: (True or False) .RS If True xosview will display a meter for NFS server/daemon stats. .RE xosview*NFSDStatCallsColor: \fIcolor\fP .RS The color to be used for call stats. .RE xosview*NFSDStatBadCallsColor: \fIcolor\fP .RS The color to be used for bad stats. .RE xosview*NFSDStatUDPColor: \fIcolor\fP .RS The color to be used for UDP stats. .RE xosview*NFSDStatTCPColor: \fIcolor\fP .RS The color to be used for TCP stats. .RE xosview*NFSDStatIdleColor: \fIcolor\fP .RS The color to be used for idle stats. .RE \fBSerial Meter Resources\fP xosview*serial(0-9): (True, False, or portBase) .RS If True then xosview will display a serial meter for ttySx. The portbase will be autodetected. Because autodetection can fail, (if the port is locked by ppp/slip for example) you can specify the portbase instead of "True". If a portBase is used then xosview will use it instead of trying to autodetect. For this to work on Linux xosview needs to be suid root in order to have access to the ports. See the file README.linux which comes with the xosview distribution for more details. .RE xosview*serialOnColor: \fIcolor\fP .RS This is the color the serial meter will use for bits that are set. .RE xosview*serialOffColor: \fIcolor\fP .RS This is the color the serial meter will use for bits that are not set. .RE .\" Do the priority resource .pp serial \fBInterrupt Meter Resources\fP xosview*interrupts: (True or False) .RS If True then xosview will display an interrupt meter. .RE xosview*intSeparate: (True of False) .RS If True then xosview will display one interrupt meter per CPU on SMP machines. If False only one meter is displayed. Default: True. .RE xosview*intOnColor: \fIcolor\fP .RS This is the color that will be used to show "active" interrupts. .RE xosview*intOffColor: \fIcolor\fP .RS This is the color that will be used to show "inactive" interrupts. .RE .\" Do the priority resource .pp int \fBInterrupt Rate Meter Resources\fP xosview*irqrate: (True or False) .RS If True then xosview will display an interrupt rate meter. .RE xosview*irqrateUsedColor: \fIcolor\fP .RS This is the color that will be used to show the interrupt rate. .RE .cc irqrate Idle idle .\" Priority, decay, usedFormat resources: .pp irqrate .dc irqrate .dg irqrate .uf irqrate \fBLm Sensors Resources\fP .xt lmstemp xosview*lmstempHighest: \fInumber\fP .RS Highest value displayed. If not given, or too small, the meter will adjust to fit actual and alarm values. Can be overridden for any meter with lmstempHighest\fIN\fP. .RE xosview*lmstempActColor: \fIcolor\fP .RS Color of actual value. .RE xosview*lmstempHighColor: \fIcolor\fP .RS Color above high alarm value, also used to indicate alarm. .RE xosview*lmstempLowColor: \fIcolor\fP .RS Color of actual value, when it is below low alarm value. .RE xosview*lmstempIdleColor: \fIcolor\fP .RS Color between actual and high alarm values. .RE xosview*lmstemp\fIN\fP: \fIfilename\fP .RS Name of input file from /proc/sys/dev/sensors/*/* or /sys/class/hwmon/*/{,device}/, N=1,2,3,... Can also be absolute path. For example, .br xosview*lmstemp1: temp1 .br xosview*lmstemp2: temp2_input .br \fBNote:\fP Many sensors have the value and alarm threshold in files named "*_input" and "*_max"/"*_min", respectively. In such case, specifying the base name such as "temp1" here will be enough for having both files used. .br \fBNote:\fP If the same file name as lmstemp\fIN\fP, lmshigh\fIN\fP or lmslow\fIN\fP exists in other sensor directories, then lmsname\fIN\fP needs to be specified, or absolute path used, to find the correct one. .RE xosview*lmshigh\fIN\fP: \fIfilename\fP or \fInumber\fP .RS Optional high alarm value or name of file from /sys/class/hwmon/*/{,device}/, N=1,2,3,... Can also be absolute path. If not given, lmstempHighest is used as both maximum and high alarm. For example, .br xosview*lmshigh1: 70 .br xosview*lmshigh2: temp1_crit_hyst .RE xosview*lmslow\fIN\fP: \fIfilename\fP or \fInumber\fP .RS Optional low alarm value or name of file from /sys/class/hwmon/*/{,device}/, N=1,2,3,... Can also be absolute path. Default is 0. For example, .br xosview*lmslow1: 1.5 .br xosview*lmslow2: fan1_min .RE xosview*lmsname\fIN\fP: \fIname\fP .RS Optional name of the sensor device to use when finding the filename(s) given in lmstemp\fIN\fP, lmshigh\fIN\fP and lmslow\fIN\fP. See /sys/class/hwmon/*/{,device}/name for the names of your sensors. This has no effect to files given as absolute paths. For example, .br xosview*lmsname1: nct6779 .br xosview*lmsname2: radeon .RE xosview*lmstempLabel\fIN\fP: \fIstring\fP .RS N-th label for above values, default is TMP. .RE xosview*lmstempHighest\fIN\fP: \fInumber\fP .RS Override default lmstempHighest for meter N. .RE xosview*lmstempUsedFormat\fIN\fP: (float, percent or autoscale) .RS Override default lmstempUsedFormat for meter N. .RE .pp lmstemp .uf lmstemp \fBACPI Temperature Resources\fP .xt acpitemp xosview*acpitempHighest: 100 .RS Highest temp value displayed, default 100. If acpihigh\fIN\fP is given, the value is read from there instead. .RE xosview*acpitempActColor: \fIcolor\fP .RS Color of actual temperature. .RE xosview*acpitempHighColor: \fIcolor\fP .RS Color above alarm temperature, also used to indicate alarm. .RE xosview*acpitempIdleColor: \fIcolor\fP .RS Color between actual and alarm temperatures. .RE xosview*acpitemp\fIN\fP: \fIfilename\fP .RS Name of temperature file from /proc/acpi/thermal_zone or /sys/devices/virtual/thermal. Note that the last directory part must be given, e.g. TZ0/temperature. Absolute path can also be used. .RE xosview*acpihigh\fIN\fP: \fIfilename\fP .RS Name of high value/trip point file from /proc/acpi/thermal_zone or /sys/devices/virtual/thermal, or an absolute path to one. .RE xosview*acpitempLabel\fIN\fP: \fILabelstring\fP .RS N-th label for above temperatures, default is TMP. .RE .pp acpitemp .uf acpitemp \fBIntel Core / AMD K8+ / VIA C7 Temperature Sensor Resources\fP .xt coretemp xosview*coretempHighest: 100 .RS Highest temp value displayed, default 100. If CPU throttling temperature (tjMax) is supplied by the operating system, it is used instead. .RE xosview*coretempHigh: \fInumber\fP .RS Value to use as alarm temperature, default is coretempHighest. If a usable value, such as the temperature for which maximum cooling is required, is supplied by the operating system, it is used instead. .RE xosview*coretempActColor: \fIcolor\fP .RS Color of actual temperature. .RE xosview*coretempHighColor: \fIcolor\fP .RS Color above alarm temperature, also used to indicate alarm. .RE xosview*coretempIdleColor: \fIcolor\fP .RS Color between actual and alarm temperatures. .RE xosview*coretempDisplayType: (separate, average or maximum) .RS This resource tells xosview how to display the CPU temperature. The formats work as follows: \fBseparate\fP: .RS Display one meter for each CPU core of a multi-core CPU. This is the default. .RE \fBaverage\fP: .RS Display the average of core temperatures of a multi-core CPU. On multi-socket machines, one meter per physical CPU is displayed. .RE \fBmaximum\fP: .RS Display the highest core temperature of a multi-core CPU. On multi-socket machines, one meter per physical CPU is displayed. .RE .RE .pp coretemp .uf coretemp \fB*BSD Sensor Resources\fP .xt bsdsensor xosview*bsdsensorHighest: \fInumber\fP .RS Highest value displayed. If not given, or too small, the meter will adjust to fit actual and alarm values. Can be overridden for any meter with bsdsensorHighest\fIN\fP. .RE xosview*bsdsensorActColor: \fIcolor\fP .RS Color of actual value. .RE xosview*bsdsensorHighColor: \fIcolor\fP .RS Color above high alarm value, also used to indicate alarm. .RE xosview*bsdsensorLowColor: \fIcolor\fP .RS Color of actual value, when it is below low alarm value. .RE xosview*bsdsensorIdleColor: \fIcolor\fP .RS Color between actual and high alarm values. .RE xosview*bsdsensor\fIN\fP: \fIname.type\fP .br xosview*bsdsensorHigh\fIN\fP: \fIname.type\fP .br xosview*bsdsensorLow\fIN\fP: \fIname.type\fP .RS These define where the actual value, high alarm value and low alarm value for meter N=1,2,3,... will be read from. The name is the sensor driver, and type is the wanted value. Both alarm values are optional, and can also be given as static numerical values. .br You can find the correct pair for OpenBSD and DragonFly BSD with systat command, e.g. .br xosview*bsdsensor1: it0.temp1 .br xosview*bsdsensorHigh1: 100 On NetBSD, you can find the driver name with envstat command. Value name for the actual reading is typically 'cur-value' and for high alarm 'critical-max' and for low alarm 'critical-min', e.g. .br xosview*bsdsensor2: coretemp0.cur-value .br xosview*bsdsensorHigh2: coretemp0.critical-max For all possible NetBSD value names, refer to envstat source code. FreeBSD has no usable sensor drivers as of version 9.0. However, ACPI thermal zones can be used by defining the sysctl node below hw.acpi.thermal, e.g. .br xosview*bsdsensor1: tz0.temperature .br xosview*bsdsensorHigh1: tz0._CRT .br ACPI thermal zones can be used like this on DragonFly BSD as well. .RE xosview*bsdsensorLabel\fIN\fP: \fIstring\fP .RS N-th label for above meters, default is SEN\fIN\fP. .RE xosview*bsdsensorHighest\fIN\fP: \fInumber\fP .RS Override default bsdsensorHighest for meter N. .RE xosview*bsdsensorUsedFormat\fIN\fP: (float, percent or autoscale) .RS Override default bsdsensorUsedFormat for meter N. .RE .pp bsdsensor .uf bsdsensor \fBBattery Meter Resources\fP xosview*battery: (True or False) .RS If True then xosview will display a battery meter. Linux users will need to have APM or ACPI support in their kernels for this to work. For both APM and ACPI, xosview shows the status/sum of all batteries. Additionally - the legend text gets changed/adjusted to reflect the current state (charging/low/critical/etc.) of the battery/batteries. .RE xosview*batteryLeftColor: \fIcolor\fP .RS This is the color that will be used to show the amount of battery power left. .RE xosview*batteryUsedColor: \fIcolor\fP .RS This is the color that will be used to show the amount of battery power used. .RE xosview*batteryChargeColor: \fIcolor\fP .RS This is the color that will be used as 'left' - if the batteries get charged. .RE xosview*batteryFullColor: \fIcolor\fP .RS This is the color that will be used as 'left' - if the batteries are fully charged. APM and ACPI does provide this info, but not all machines actually do so. .RE xosview*batteryLowColor: \fIcolor\fP .RS APM only - the 'left' color that will indicate a low battery. Depends on the machine - e.g. below 25% remaining capacity. .RE xosview*batteryCritColor: \fIcolor\fP .RS APM case: the 'left' color if APM indicates 'critical' state. (less than 5%) ACPI case: the 'left' color if the remaining capacity is below the alarm value. (which can be set by the user in /proc/acpi/battery/BAT[01]/alarm ) .RE xosview*batteryNoneColor: \fIcolor\fP .RS If no battery is present - or all batteries get removed (while on AC). .RE .\" Do the priority resource .pp battery .uf battery \fBWireless Meter Resources\fP xosview*wireless: (True or False) .RS If True then xosview will display the link quality of each wireless connection. Note that the graph will *never* show up, if you don't have any wireless devices, or no wireless extensions in the kernel (/proc/net/wireless). Default is true. .RE xosview*PoorQualityColor: \fIcolor\fP .RS This is the color for the quality field when between 0 and 6. .RE xosview*FairQualityColor: \fIcolor\fP .RS This is the color for the quality field when between 7 and 14. .RE xosview*GoodQualityColor: \fIcolor\fP .RS This is the color for the quality field when higher than 14. .RE xosview*wirelessUsedColor: \fIcolor\fP .RS This is the background color. .RE .\" Do the priority resource .pp wireless .dc wireless .uf wireless \fBDisk Meter Resources\fP .\" Do the disk: True resource. .xt disk .\" disk colors .cc disk In reads .cc disk Out writes .cc disk Idle idle xosview*diskBandwidth: \fIbandwidth\fP .RS This number is used to specify the expected maximum bandwidth in bytes per second for the disk meter. .RE xosview*diskWriteColor: \fIcolor\fP .RS This color will be used for the linux meter to show writes. .RE xosview*diskReadColor: \fIcolor\fP .RS This color will be used for the linux meter to show reads. .RE .\" Priority, decay, usedFormat resources: .pp disk .dc disk .dg disk .uf disk \fBRAID Meter Resources\fP .\" Do the RAID: True resource. .xt RAID xosview*RAIDdevicecount: \fIint\fP .RS Please enter your RAID device count (n) here or 0 if you don't have any supported RAID devices. xosview then will display n RAID state displays. .RE xosview*RAIDdiskOnlineColor: \fIcolor\fP xosview*RAIDdiskFailureColor: \fIcolor\fP .RS These colors will be used for indicating working/online or failed/offline disks. The order (from left to right) is the same as in /proc/mdstat. .RE xosview*RAIDresyncdoneColor: \fIcolor\fP xosview*RAIDresynctodoColor: \fIcolor\fP xosview*RAIDresynccompleteColor: \fIcolor\fP .RS If a resync/rebuild of the RAID array is in progress, the "done" and "todo" colors will be used. If no rebuild/resync is running, then the "complete" color will be shown. .RE .\" RAIDpriority resource .pp RAID .\" RAIDUsedFormat resource .uf RAID .SH OBTAINING This version of xosview is distributed from the following site: .RS http://www.pogo.org.uk/~mark/xosview/ .RE .SH AUTHORS Mike Romberg .RS Original author, Linux and HPUX ports. .RE Brian Grayson .RS NetBSD port and most of the nice enhancements for version 1.4, initial work on FreeBSD port. .RE Scott McNab .RS Added the scrolling graph mode. .RE Tom Pavel .RS Most of the FreeBSD support, more resource-handling improvements. .RE Greg Onufer .RS SunOS port. .RE Stefan Eilemann .RS IRIX 6.5 port. .RE Sheldon Hearn .RS FreeBSD libdevstat-based diskmeter support. .RE David W. Talmage .RS Added battery-meter support to NetBSD. .RE Oleg Safiullin .RS OpenBSD interrupt-meter support. .RE Werner Fink .RS Originator of the loadmeter. .RE Massimiliano Ghilardi .RS Linux pagemeter. .RE Carsten Schabacker .RS Made extensions to the serial-meter. .RE Paal Beyer .RS Ported the linux memstat kernel module to linux-2.1 .RE Jerome Forissier .RS Author of the Linux SMP kernel patch which xosview uses to display meters for each CPU. .RE Tomer Klainer .RS Initial port to BSDI. .RE Arno Augustin .RS Solaris disk and network meters. .RE Alberto BARSELLA .RS Fixes for linux diskmeter + ip_chains support .RE Thomas Waldmann .RS Linux raid meter, bitfieldmeter. Many cosmetic fixes. .RE Leopold Toetsch .RS Linux lms temp meter. .RE David O'Brien .RS FreeBSD 4.* updates, and a few other suggestions. .RE Christos Zoulas .RS C++ standard compliance and other NetBSD fixes. .RE Tim Ehlers .RS Wireless Link-Meter for Linux. .RE Mark Hills .RS Bug fixes and general caretaking. .RE Tomi Tapper .RS Temperature sensor, and FreeBSD updates. .RE Raymond S Brand (rsbx@acm.org) .RS Misc fixes. .RE And many others who have sent in small fixes and improvements. xosview-1.20/xosview.cc000066400000000000000000000262101317735352700151710ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #include "xosview.h" #include "meter.h" #include "MeterMaker.h" #if ( defined(XOSVIEW_NETBSD) || defined(XOSVIEW_FREEBSD) || \ defined(XOSVIEW_OPENBSD) || defined(XOSVIEW_DFBSD) ) # include "kernel.h" #endif #include #include #include #include #include static const char * const versionString = "xosview version: Git"; static const char NAME[] = "xosview@"; #if !defined(__GNUC__) #define MIN(x,y) \ ( \ x < y ? x : y \ ) #define MAX(x,y) \ ( \ x > y ? x : y \ ) #else #define MIN(x,y) \ ({ \ const typeof(x) _x = x; \ const typeof(y) _y = y; \ \ (void) (&_x == &_y); \ \ _x < _y ? _x : _y; \ }) #define MAX(x,y) \ ({ \ const typeof(x) _x = x; \ const typeof(y) _y = y; \ \ (void) (&_x == &_y); \ \ _x > _y ? _x : _y; \ }) #endif // sgi double MAX_SAMPLES_PER_SECOND = 10; XOSView::XOSView( const char * instName, int argc, char *argv[] ) : XWin(), xrm(Xrm("xosview", instName)){ // Check for version arguments first. This allows // them to work without the need for a connection // to the X server checkVersion(argc, argv); setDisplayName (xrm.getDisplayName( argc, argv)); openDisplay(); // So that the Xrm class can contact the display for its // default values. // The resources need to be initialized before calling XWinInit, because // XWinInit looks at the geometry resource for its geometry. BCG xrm.loadAndMergeResources (argc, argv, display_); XWinInit (argc, argv, NULL, &xrm); #if 1 // Don't enable this yet. MAX_SAMPLES_PER_SECOND = atof(getResource("samplesPerSec")); if (!MAX_SAMPLES_PER_SECOND) MAX_SAMPLES_PER_SECOND = 10; #endif usleeptime_ = (unsigned long) (1000000/MAX_SAMPLES_PER_SECOND); if (usleeptime_ >= 1000000) { /* The syscall usleep() only takes times less than 1 sec, so * split into a sleep time and a usleep time if needed. */ sleeptime_ = usleeptime_ / 1000000; usleeptime_ = usleeptime_ % 1000000; } else { sleeptime_ = 0; } #if ( defined(XOSVIEW_NETBSD) || defined(XOSVIEW_FREEBSD) || \ defined(XOSVIEW_OPENBSD) || defined(XOSVIEW_DFBSD) ) BSDInit(); /* Needs to be done before processing of -N option. */ #endif hmargin_ = atoi(getResource("horizontalMargin")); vmargin_ = atoi(getResource("verticalMargin")); vspacing_ = atoi(getResource("verticalSpacing")); hmargin_ = MAX(0, hmargin_); vmargin_ = MAX(0, vmargin_); vspacing_ = MAX(0, vspacing_); checkArgs (argc, argv); // Check for any other unhandled args. xoff_ = hmargin_; yoff_ = 0; nummeters_ = 0; meters_ = NULL; name_ = const_cast("xosview"); _deferred_resize = true; _deferred_redraw = true; windowVisibility = OBSCURED; // set up the X events addEvent( new Event( this, ConfigureNotify, (EventCallBack)&XOSView::resizeEvent ) ); addEvent( new Event( this, Expose, (EventCallBack)&XOSView::exposeEvent ) ); addEvent( new Event( this, KeyPress, (EventCallBack)&XOSView::keyPressEvent ) ); addEvent( new Event( this, VisibilityNotify, (EventCallBack)&XOSView::visibilityEvent ) ); addEvent( new Event( this, UnmapNotify, (EventCallBack)&XOSView::unmapEvent ) ); // add or change the Resources MeterMaker mm(this); // see if legends are to be used checkOverallResources (); // add in the meters mm.makeMeters(); for (int i = 1 ; i <= mm.n() ; i++) addmeter(mm[i]); if (nummeters_ == 0) { std::cerr << "No meters were enabled! Exiting..." << std::endl; exit (0); } // Have the meters re-check the resources. checkMeterResources(); // determine the width and height of the window then create it figureSize(); init( argc, argv ); title( winname() ); iconname( winname() ); dolegends(); } void XOSView::checkVersion(int argc, char *argv[]) const { for (int i = 0 ; i < argc ; i++) if (!strncasecmp(argv[i], "-v", 2) || !strncasecmp(argv[i], "--version", 10)) { std::cerr << versionString << std::endl; exit(0); } } void XOSView::figureSize ( void ) { if ( legend_ ){ if ( !usedlabels_ ) xoff_ = textWidth( "XXXXXX" ); else xoff_ = textWidth( "XXXXXXXXXX" ); yoff_ = caption_ ? textHeight() + textHeight() / 4 : 0; } static int firsttime = 1; if (firsttime) { firsttime = 0; width_ = findx(); height_ = findy(); } else { } } void XOSView::checkMeterResources( void ){ MeterNode *tmp = meters_; while ( tmp != NULL ){ tmp->meter_->checkResources(); tmp = tmp->next_; } } int XOSView::newypos( void ){ return 15 + 25 * nummeters_; } void XOSView::dolegends( void ){ MeterNode *tmp = meters_; while ( tmp != NULL ){ tmp->meter_->docaptions( caption_ ); tmp->meter_->dolegends( legend_ ); tmp->meter_->dousedlegends( usedlabels_ ); tmp = tmp->next_; } } void XOSView::addmeter( Meter *fm ){ MeterNode *tmp = meters_; if ( meters_ == NULL ) meters_ = new MeterNode( fm ); else { while ( tmp->next_ != NULL ) tmp = tmp->next_; tmp->next_ = new MeterNode( fm ); } nummeters_++; } int XOSView::findx( void ){ if ( legend_ ){ if ( !usedlabels_ ) return textWidth( "XXXXXXXXXXXXXXXXXXXXXXXX" ); else return textWidth( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ); } return 80; } int XOSView::findy( void ){ if ( legend_ ) return 10 + textHeight() * nummeters_ * ( caption_ ? 2 : 1 ); return 15 * nummeters_; } void XOSView::checkOverallResources() { // Check various resource values. // Set 'off' value. This is not necessarily a default value -- // the value in the defaultXResourceString is the default value. usedlabels_ = legend_ = caption_ = 0; setFont(); // use captions if ( isResourceTrue("captions") ) caption_ = 1; // use labels if ( isResourceTrue("labels") ) legend_ = 1; // use "free" labels if ( isResourceTrue("usedlabels") ) usedlabels_ = 1; } const char *XOSView::winname( void ){ char host[100]; gethostname( host, 99 ); static char name[101]; /* We return a pointer to this, so it can't be local. */ snprintf( name, 100, "%s%s", NAME, host); // Allow overriding of this name through the -title option. return getResourceOrUseDefault ("title", name); } void XOSView::resize( void ){ int spacing = vspacing_+1; int topmargin = vmargin_; int rightmargin = hmargin_; int newwidth = width_ - xoff_ - rightmargin; int newheight = (height_ - (topmargin + topmargin + (nummeters_-1)*spacing + nummeters_*yoff_) ) / nummeters_; newheight = (newheight >= 2) ? newheight : 2; int counter = 1; MeterNode *tmp = meters_; while ( tmp != NULL ) { tmp->meter_->resize( xoff_, topmargin + counter*yoff_ + (counter-1)*(newheight+spacing), newwidth, newheight ); tmp = tmp->next_; counter++; } } XOSView::~XOSView( void ){ MeterNode *tmp = meters_; while ( tmp != NULL ){ MeterNode *save = tmp->next_; delete tmp->meter_; delete tmp; tmp = save; } } void XOSView::draw(void) { if (windowVisibility != OBSCURED) { MeterNode *tmp = meters_; XOSDEBUG("Doing draw.\n"); clear(); while (tmp != NULL) { tmp->meter_->draw(); tmp = tmp->next_; } } else { XOSDEBUG("Skipping draw: not visible.\n"); } } void XOSView::run( void ){ while(!done_) { // Check for X11 events checkevent(); // Check if the window has been resized (at least once) if (_deferred_resize) { resize(); _deferred_resize = false; _deferred_redraw = true; } // redraw everything if needed if (_deferred_redraw) { draw(); _deferred_redraw = false; } // Update the metrics & meters MeterNode *tmp = meters_; while ( tmp != NULL ){ if ( tmp->meter_->requestevent() ) tmp->meter_->checkevent(); tmp = tmp->next_; } flush(); /* First, sleep for the proper integral number of seconds -- * usleep only deals with times less than 1 sec. */ if (sleeptime_) sleep((unsigned int)sleeptime_); if (usleeptime_) usleep( (unsigned int)usleeptime_); } } void XOSView::keyPressEvent( XKeyEvent &event ){ char c = 0; KeySym key; XLookupString( &event, &c, 1, &key, NULL ); if ( (c == 'q') || (c == 'Q') ) done_ = 1; } void XOSView::checkArgs (int argc, char** argv) const { // The XWin constructor call in the XOSView constructor above // modifies argc and argv, so by this // point, all XResource arguments should be removed. Since we currently // don't have any other command-line arguments, perform a check here // to make sure we don't get any more. if (argc == 1) return; // No arguments besides X resources. // Skip to the first real argument. argc--; argv++; while (argc > 0 && argv && *argv) { switch (argv[0][1]) { case 'n': // Check for -name option that was already parsed // and acted upon by main(). if (!strncasecmp(*argv, "-name", 6)) { argv++; // Skip arg to -name. argc--; } break; #if ( defined(XOSVIEW_NETBSD) || defined(XOSVIEW_FREEBSD) || \ defined(XOSVIEW_OPENBSD) || defined(XOSVIEW_DFBSD) ) case 'N': if (strlen(argv[0]) > 2) SetKernelName(argv[0]+2); else { SetKernelName(argv[1]); argc--; argv++; } break; #endif /* Fall through to default/error case. */ default: std::cerr << "Ignoring unknown option '" << argv[0] << "'.\n"; break; } argc--; argv++; } } void XOSView::exposeEvent(XExposeEvent &event) { _deferred_redraw = true; XOSDEBUG("Got expose event.\n"); } /* * All window changes come in via XConfigureEvent (not * XResizeRequestEvent) */ void XOSView::resizeEvent( XConfigureEvent &event ) { XOSDEBUG("Got configure event.\n"); if (event.width == width_ && event.height == height_) return; XOSDEBUG("Window has resized\n"); width(event.width); height(event.height); _deferred_resize = true; } void XOSView::visibilityEvent(XVisibilityEvent &event) { if (event.state == VisibilityPartiallyObscured) { if (windowVisibility != FULLY_VISIBLE) _deferred_redraw = true; windowVisibility = PARTIALLY_VISIBILE; } else if (event.state == VisibilityFullyObscured) { windowVisibility = OBSCURED; _deferred_redraw = false; } else { if (windowVisibility != FULLY_VISIBLE) _deferred_redraw = true; windowVisibility = FULLY_VISIBLE; } XOSDEBUG("Got visibility event: %s\n", (windowVisibility == FULLY_VISIBLE) ? "Full" : (windowVisibility == PARTIALLY_VISIBILE) ? "Partial" : "Obscured" ); } void XOSView::unmapEvent( XUnmapEvent & ev ){ /* unclutter creates a subwindow of our window if it hides the cursor, we get the unmap event if the cursor is moved again. Don't treat it as main window unmap */ if(ev.window == window_) windowVisibility = OBSCURED; } xosview-1.20/xosview.desktop000066400000000000000000000002701317735352700162530ustar00rootroot00000000000000[Desktop Entry] Name=Xosview Comment=X based system monitor Exec=xosview Terminal=false Type=Application Icon=xosview Categories=System;Monitor; Keywords=System;Utility;System Monitor xosview-1.20/xosview.h000066400000000000000000000037621317735352700150420ustar00rootroot00000000000000// // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov ) // // This file may be distributed under terms of the GPL // #ifndef _XOSVIEW_H_ #define _XOSVIEW_H_ #include "xwin.h" #include "Xrm.h" // For Xrm resource manager class. #include /* Take at most n samples per second (default of 10) */ extern double MAX_SAMPLES_PER_SECOND; class Meter; class XOSView : public XWin { public: XOSView( const char* instName, int argc, char *argv[] ); ~XOSView( void ); void figureSize ( void ); void resize( void ); void draw ( void ); void run( void ); const char *winname( void ); // used by meter makers int xoff(void) const { return xoff_; } int newypos( void ); enum windowVisibilityState { FULLY_VISIBLE, PARTIALLY_VISIBILE, OBSCURED }; enum windowVisibilityState getWindowVisibilityState(void) { return windowVisibility; } protected: Xrm xrm; void checkArgs (int argc, char** argv) const; class MeterNode { public: MeterNode( Meter *fm ) { meter_ = fm; next_ = NULL; } Meter *meter_; MeterNode *next_; }; MeterNode *meters_; int caption_, legend_, xoff_, yoff_, nummeters_, usedlabels_; int hmargin_, vmargin_, vspacing_; unsigned long sleeptime_, usleeptime_; void usleep_via_select( unsigned long usec ); void addmeter( Meter *fm ); void checkMeterResources( void ); int findx( void ); int findy( void ); void dolegends( void ); void checkOverallResources(); void resizeEvent( XConfigureEvent &event ); void exposeEvent( XExposeEvent &event ); void keyPressEvent( XKeyEvent &event ); void visibilityEvent( XVisibilityEvent &event ); void unmapEvent( XUnmapEvent &event); void checkVersion(int argc, char *argv[]) const; private: bool _deferred_resize; bool _deferred_redraw; enum windowVisibilityState windowVisibility; }; #ifdef DEBUG #define XOSDEBUG(...) { \ fprintf(stderr, "%s:%d: ", __func__, __LINE__); \ fprintf(stderr, __VA_ARGS__); \ } #else #define XOSDEBUG(...) #endif #endif xosview-1.20/xosview.png000066400000000000000000000044141317735352700153720ustar00rootroot00000000000000PNG  IHDR szzgAMA a cHRMz&u0`:pQ<bKGDCtIME  9GIDATXÅɏ\G?zt{xI !QHIK" q"qB܂HNHW$J "& !"c{Y{z*=n3SnU_}~K};o߲ ƴ0>s݆X[?}rgigM[EL]2XE;$+eM0cfÎVn(iMeKa R'.0]뢔eYbIv>I/͡}箱3n /mc E4tIe' -TB]Π~ ܋E(pe%kIl+z̞4`-pfe ЉVi,AZ԰41 y5D9[N^ӏ:[G,ղf>fFo`(s2:qF" IRD<% >2_ .[wfYXLOj&Z^Ё5i'%#=x-V9jy<>鋻y׆1k៳}r 'E;11IlH yaKLP Uq%d7i?1ِ6@`הKuf&BZʧT!ȩ f9F1fsh/ŒmףuK BRb<ٱeo/'͠Zvp]aq5%|My@iI0_?~{wsj7xw},/l Гe(ň匧ϊ0\{փ_F"Q`=pfRP2 * {JUjHnڠWdc 0s8L‚C?2%39L:UW&؊f-"pdYYscKpp'ZP? z{BPq<6C00G'.CEs-!kZť8,H n7penJ8$1[ Z 3=ř xPo|ƑIbPJCd F{~ H ,->>gҨՌvN[!j C3:Z/in|F)&gxl1/XXN(9daZ̞2YXk5 K!>{`PJ|v1U &+{y#L(\q[ɷkc[ ܪ1WS.|I\LN*)dYv4}Bc@cs=C{AbRzR)Q=Ė0y̍uMkʥQwI.g\4LѠdvAkg&5&Y+[XM)Pܐs )KEj4!5d^QMp>1l.F:`{B _H:e v:CdXg)hܱ̎]Z2V}MUܜ̐Gl}iOajűoMu-(͘ 7 ?ٔ|7zSѴbӗr'dmW:4wLɕ2>jVVSWx"Icq9Թh=W(sģ%<0A߸(e‚lèVms -nNL ^|ZPs"!)/poDZrȕ C^{m)~ocʹxsbgs9V)!ze*!r6T%tEXtdate:create2017-09-28T13:57:31+02:00Ws %tEXtdate:modify2017-09-28T13:57:31+02:00&.9IENDB`xosview-1.20/xosview.xpm000066400000000000000000000262671317735352700154240ustar00rootroot00000000000000/* XPM */ static char * xosview_xpm[] = { "25 32 604 2", " c None", ". c #00A0A1", "+ c #038A8D", "@ c #048588", "# c #028B8F", "$ c #028B8E", "% c #038B8E", "& c #028A8E", "* c #019495", "= c #00007E", "- c #00007F", "; c #01007D", "> c #1C0B70", ", c #200D6E", "' c #1F0D6E", ") c #1D0B70", "! c #0E0582", "~ c #0A0F87", "{ c #111D8B", "] c #080A85", "^ c #00588D", "/ c #0C0482", "( c #1B1986", "_ c #191785", ": c #090881", "< c #070681", "[ c #070783", "} c #130F7C", "| c #6E494C", "1 c #895A3F", "2 c #8B5C3E", "3 c #704A4A", "4 c #5B4A7C", "5 c #5690A3", "6 c #487298", "7 c #426694", "8 c #130975", "9 c #171078", "0 c #140C7B", "a c #005B8C", "b c #058789", "c c #3B2F8C", "d c #796E99", "e c #6E6397", "f c #292588", "g c #272388", "h c #302B8A", "i c #694A63", "j c #845C57", "k c #815B57", "l c #805A58", "m c #835B53", "n c #855650", "o c #855851", "p c #865A50", "q c #896254", "r c #896153", "s c #8A6152", "t c #8B5F51", "u c #8A5F51", "v c #8B6151", "w c #8E6350", "x c #7A6068", "y c #045A8A", "z c #038C8F", "A c #0E0682", "B c #0B0A82", "C c #0A0982", "D c #050581", "E c #0C0B82", "F c #080980", "G c #403E68", "H c #524F5F", "I c #564966", "J c #816A53", "K c #745E52", "L c #675158", "M c #6D5657", "N c #6F5063", "O c #714C51", "P c #6F4C59", "Q c #65546D", "R c #626478", "S c #646778", "T c #585272", "U c #4B3667", "V c #402F72", "W c #015D8D", "X c #038C8E", "Y c #1E1486", "Z c #37328B", "` c #242087", " . c #181685", ".. c #221F87", "+. c #151583", "@. c #193276", "#. c #1F3F73", "$. c #293986", "%. c #636362", "&. c #5D5F5C", "*. c #4A4B65", "=. c #535367", "-. c #4A3E7B", ";. c #533B5E", ">. c #503C6A", ",. c #38428B", "'. c #2D559D", "). c #3464A1", "!. c #2C4994", "~. c #111585", "{. c #0A0882", "]. c #005C8D", "^. c #048C8E", "/. c #3A2E8C", "(. c #4C4490", "_. c #49438F", ":. c #312C8A", "<. c #443E8E", "[. c #46408F", "}. c #34308A", "|. c #817F56", "1. c #A4A045", "2. c #979B55", "3. c #9A9749", "4. c #A2A249", "5. c #A6A345", "6. c #A1A04B", "7. c #98994C", "8. c #9C9A4B", "9. c #8C9151", "0. c #537268", "a. c #356073", "b. c #336377", "c. c #8D9652", "d. c #6D815F", "e. c #435E78", "f. c #080181", "g. c #070781", "h. c #090882", "i. c #0C0D80", "j. c #344868", "k. c #405761", "l. c #3B496C", "m. c #7D7B54", "n. c #6B6B50", "o. c #5D5D56", "p. c #666454", "q. c #675B64", "r. c #6A554E", "s. c #625258", "t. c #374C81", "u. c #305F90", "v. c #2F6292", "w. c #435D7D", "x. c #242E75", "y. c #131A7B", "z. c #201786", "A. c #302C8A", "B. c #1C1A86", "C. c #181585", "D. c #1D1A86", "E. c #2A2588", "F. c #151483", "G. c #031578", "H. c #031D75", "I. c #161C84", "J. c #393465", "K. c #3D395E", "L. c #2B2768", "M. c #332D6B", "N. c #24157C", "O. c #2F1663", "P. c #2B1770", "Q. c #1C1C87", "R. c #0A2798", "S. c #153A9D", "T. c #0D2293", "U. c #000085", "V. c #000082", "W. c #005B8D", "X. c #048D8E", "Y. c #42368D", "Z. c #575092", "`. c #4C448F", " + c #47408F", ".+ c #574E92", "++ c #5C5393", "@+ c #45408E", "#+ c #507F74", "$+ c #5E9F6D", "%+ c #5F9D6F", "&+ c #609E6C", "*+ c #68A069", "=+ c #66A16A", "-+ c #609D6D", ";+ c #5E9C6E", ">+ c #5F9B6C", ",+ c #7AA966", "'+ c #C3D54F", ")+ c #E5EE43", "!+ c #EDF341", "~+ c #7BB065", "{+ c #A3C155", "]+ c #D8D14E", "^+ c #04608C", "/+ c #000080", "(+ c #01037F", "_+ c #081978", ":+ c #0A1C78", "<+ c #05117B", "[+ c #081679", "}+ c #091C78", "|+ c #0A2077", "1+ c #0F1979", "2+ c #352672", "3+ c #352264", "4+ c #372463", "5+ c #1E1A7B", "6+ c #270872", "7+ c #3B0062", "8+ c #2E0169", "9+ c #3A0062", "0+ c #095B89", "a+ c #110883", "b+ c #1E1C86", "c+ c #080781", "d+ c #141184", "e+ c #110F84", "f+ c #0E0F82", "g+ c #112F73", "h+ c #153E6E", "i+ c #102E73", "j+ c #163E6E", "k+ c #113072", "l+ c #153E6F", "m+ c #20496A", "n+ c #353B74", "o+ c #5E3A5D", "p+ c #6F4348", "q+ c #5A3551", "r+ c #36297A", "s+ c #4E0E65", "t+ c #7E0040", "u+ c #540157", "v+ c #770348", "w+ c #0D5C86", "x+ c #058E8F", "y+ c #85719B", "z+ c #6C6296", "A+ c #4F4790", "B+ c #39338C", "C+ c #7E729A", "D+ c #877A9C", "E+ c #625994", "F+ c #385D75", "G+ c #3C706E", "H+ c #3B6D6F", "I+ c #3D7170", "J+ c #41706D", "K+ c #B2773E", "L+ c #B9363B", "M+ c #B4173C", "N+ c #B3193D", "O+ c #B51A3D", "P+ c #B71B3A", "Q+ c #B51D3B", "R+ c #B31C3D", "S+ c #B12743", "T+ c #6C98AC", "U+ c #015F8F", "V+ c #00007C", "W+ c #00007D", "X+ c #1B2A7B", "Y+ c #223879", "Z+ c #213579", "`+ c #2C3481", " @ c #30468F", ".@ c #324C91", "+@ c #3E508D", "@@ c #322D84", "#@ c #240F7B", "$@ c #26127C", "%@ c #25137D", "&@ c #1D1A87", "*@ c #1E1485", "=@ c #36318B", "-@ c #2C2889", ";@ c #100F83", ">@ c #121183", ",@ c #1B1886", "'@ c #171884", ")@ c #234B7D", "!@ c #295B7C", "~@ c #214980", "{@ c #48638D", "]@ c #355E9F", "^@ c #4684AB", "/@ c #407AA9", "(@ c #254597", "_@ c #13238C", ":@ c #15268D", "<@ c #161C89", "[@ c #45388E", "}@ c #6F6497", "|@ c #5D5493", "1@ c #252188", "2@ c #423B8E", "3@ c #37328C", "4@ c #486AA1", "5@ c #5483AA", "6@ c #5484A9", "7@ c #5082A6", "8@ c #5383A6", "9@ c #517FA7", "0@ c #517DA6", "a@ c #5380A7", "b@ c #5789A9", "c@ c #588AAA", "d@ c #588BAA", "e@ c #598CAB", "f@ c #577BA5", "g@ c #015E8E", "h@ c #050080", "i@ c #030380", "j@ c #040380", "k@ c #111083", "l@ c #060480", "m@ c #3754A3", "n@ c #4669A9", "o@ c #4757A5", "p@ c #4A57B8", "q@ c #3F4DAE", "r@ c #405196", "s@ c #3F73A5", "t@ c #4782A9", "u@ c #2D4D98", "v@ c #223891", "w@ c #1F318F", "x@ c #1F328F", "y@ c #1F338F", "z@ c #1F298D", "A@ c #3F328C", "B@ c #433D8E", "C@ c #110F83", "D@ c #141183", "E@ c #32459F", "F@ c #42519F", "G@ c #38379A", "H@ c #403DAE", "I@ c #3230A0", "J@ c #37388D", "K@ c #3A619E", "L@ c #406AA1", "M@ c #2B4093", "N@ c #1B2189", "O@ c #171886", "P@ c #171986", "Q@ c #171A86", "R@ c #161385", "S@ c #34288A", "T@ c #5B5292", "U@ c #4D4690", "V@ c #171484", "W@ c #2A2889", "X@ c #588DAB", "Y@ c #6CB2B7", "Z@ c #66ACB5", "`@ c #68AEB6", " # c #67ADB4", ".# c #6AB0B6", "+# c #69AFB6", "@# c #6AB2B7", "## c #69AEB6", "$# c #69B0B7", "%# c #699BAF", "&# c #025F8E", "*# c #010180", "=# c #02017F", "-# c #2C45A0", ";# c #2C489F", "># c #3F47A0", ",# c #3B3EB1", "'# c #3136A9", ")# c #2F398E", "!# c #31619F", "~# c #386DA3", "{# c #1E3892", "]# c #13228B", "^# c #0D1787", "/# c #0E1987", "(# c #0E1286", "_# c #2E2489", ":# c #252288", "<# c #181584", "[# c #0E0D83", "}# c #0A0881", "|# c #192897", "1# c #303997", "2# c #120D8F", "3# c #241BA6", "4# c #130B94", "5# c #1B1684", "6# c #1D3F95", "7# c #244B99", "8# c #0E1F8A", "9# c #715F96", "0# c #423C8D", "a# c #201E87", "b# c #201C86", "c# c #3C388D", "d# c #83C6BC", "e# c #9EFACD", "f# c #9CF7CC", "g# c #9CF6CB", "h# c #9CF6CC", "i# c #9DF7CC", "j# c #9DF9CC", "k# c #9CDDC3", "l# c #03608F", "m# c #000181", "n# c #182595", "o# c #121C91", "p# c #192596", "q# c #17188A", "r# c #1B1299", "s# c #160D99", "t# c #120995", "u# c #160C99", "v# c #0B0A85", "w# c #1F318E", "x# c #0F238C", "y# c #000381", "z# c #00007B", "A# c #281E87", "B# c #262288", "C# c #060581", "D# c #0B0982", "E# c #121386", "F# c #3C5DAB", "G# c #3B5EAA", "H# c #4169B1", "I# c #5064A3", "J# c #4145B7", "K# c #3B43B2", "L# c #2F38A6", "M# c #3E44B0", "N# c #3A4B9A", "O# c #34619E", "P# c #386CA3", "Q# c #3769A2", "R# c #1C3490", "S# c #111D89", "T# c #121F89", "U# c #121888", "V# c #058D8F", "W# c #685895", "X# c #4E4790", "Y# c #635A94", "Z# c #181684", "`# c #231F87", " $ c #5784A6", ".$ c #67A8B2", "+$ c #64A4B1", "@$ c #61A5B3", "#$ c #64A3B3", "$$ c #62A7B2", "%$ c #64A9B3", "&$ c #68A7AF", "*$ c #66A7B2", "=$ c #63A5B3", "-$ c #64A4B2", ";$ c #64A4B3", ">$ c #66A9B4", ",$ c #67ABB5", "'$ c #67ACB5", ")$ c #6897AE", "!$ c #000081", "~$ c #4A1469", "{$ c #5A1864", "]$ c #44176E", "^$ c #21177F", "/$ c #351377", "($ c #44156F", "_$ c #29177B", ":$ c #501969", "<$ c #411A71", "[$ c #1C1682", "}$ c #141786", "|$ c #151686", "1$ c #151786", "2$ c #141085", "3$ c #281D87", "4$ c #463F8F", "5$ c #2B2789", "6$ c #0D0C83", "7$ c #010381", "8$ c #63175E", "9$ c #743267", "0$ c #593676", "a$ c #363688", "b$ c #4D367D", "c$ c #603673", "d$ c #433480", "e$ c #6A1E60", "f$ c #64175F", "g$ c #32398C", "h$ c #253690", "i$ c #263690", "j$ c #27368F", "k$ c #253790", "l$ c #252D8D", "m$ c #038D8F", "n$ c #392D8B", "o$ c #504991", "p$ c #141384", "q$ c #10087E", "r$ c #573E7F", "s$ c #5B7EA6", "t$ c #5489AE", "u$ c #5B88AA", "v$ c #5D87AA", "w$ c #5288AF", "x$ c #6183A6", "y$ c #6D5181", "z$ c #7A4071", "A$ c #5C8EAE", "B$ c #6188A8", "C$ c #6288A7", "D$ c #6088A8", "E$ c #5E8AAA", "F$ c #5E78A3", "G$ c #048285", "H$ c #030080", "I$ c #000182", "J$ c #5B0D5B", "K$ c #761C57", "L$ c #4E1F6C", "M$ c #211F83", "N$ c #411E73", "O$ c #5D1F65", "P$ c #331D79", "Q$ c #5E115C", "R$ c #560D5E", "S$ c #232083", "T$ c #131E8A", "U$ c #151E89", "V$ c #141F89", "W$ c #141887", "X$ c #015688", "Y$ c #048D8F", "Z$ c #30258A", "`$ c #504890", " % c #020381", ".% c #4F1669", "+% c #56236F", "@% c #4A2475", "#% c #2F2482", "$% c #3B247C", "%% c #422479", "&% c #332480", "*% c #581D69", "=% c #4B1B6E", "-% c #252588", ";% c #20248A", ">% c #21248A", ",% c #212489", "'% c #21258A", ")% c #1F1D88", "!% c #015E8F", "~% c #36288A", "{% c #49418F", "]% c #2C2689", "^% c #171284", "/% c #14077D", "(% c #854B71", "_% c #8BA4A7", ":% c #7AB5B6", "<% c #78B4B7", "[% c #81B1B4", "}% c #83ACAF", "|% c #A26473", "1% c #B04C5F", "2% c #78BCBD", "3% c #7BB3B6", "4% c #7DB2B5", "5% c #7AB4B7", "6% c #77B6B8", "7% c #789FB0", "8% c #025F8F", "9% c #028D8F", "0% c #012589", "a% c #012989", "b% c #012787", "c% c #00298A", "d% c #002889", "e% c #002989", "f% c #032A89", "g% c #032D8A", "h% c #032D8B", "i% c #042B89", "j% c #042B88", "k% c #032E8B", "l% c #032A8A", "m% c #006B90", ". + + @ # $ $ $ % % % % % $ % $ $ $ $ $ # @ + & * ", "+ = - - - - - ; > , ' ) ! ~ { ] = - - - - - - = ^ ", "+ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 9 9 9 9 9 0 a ", "b c d e f g h g i j k l m n o p q r s t u v w x y ", "z A B C D E B F G H I J K L M N O P Q R S T U V W ", "X Y Z ` ...g +.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].", "^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.W ", "% f.D E g.B h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.].", "X z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.", "X.Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+", "$ - /+/+/+/+/+(+_+:+_+<+[+}+|+1+2+3+4+5+6+7+8+9+0+", "X a+b+D c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+", "x+y+z+A+B+C+D+E+F+G+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+", "$ V+W+= = W+W+= X+Y+Z+`+ @.@+@@@#@$@$@$@$@$@%@&@].", "X *@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@:@:@:@:@:@<@].", "X.[@}@|@1@Z 2@3@4@5@6@7@8@9@0@a@b@c@d@d@d@d@e@f@g@", "% h@/+i@j@k@C l@m@n@o@p@q@r@s@t@u@v@w@x@x@x@y@z@].", "X.A@B@:.h.= C@D@E@F@G@H@I@J@K@L@M@N@O@P@P@P@Q@R@].", "X S@T@U@c+- V@W@X@Y@Z@`@ #`@.#+#@#+#########$#%#&#", "$ - < < /+- *#=#-#;#>#,#'#)#!#~#{#]#^#/#/#/#/#(#].", "X _#:#<#- - [#}#|#1#2#3#4#5#6#7#8#- W+W+W+W+W+V+W.", "x+9#0#a#- - b#c#d#e#f#g#g#h#g#g#g#i#i#i#g#g#j#k#l#", "$ = - - /+/+- m#n#o#p#q#r#s#t#u#v#w#x#8#y#z#V+V+W.", "X A#B#B#C#- D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#].", "V#W#X#Y#Z#= `#3@ $.$+$@$#$$$%$&$*$=$-$;$>$,$'$)$&#", "$ V+W+W+- /+- !$~${$]$^$/$($_$:$<$[$}$|$|$1$1$2$].", "X 3$4$5$6$- /+7$8$9$0$a$b$c$d$e$f$g$h$i$j$i$k$l$].", "m$n$o$=@p$- /+q$r$s$t$u$v$w$x$y$z$A$B$B$C$D$E$F$g@", "G$H$- /+*#- /+I$J$K$L$M$N$O$P$Q$R$S$T$U$U$U$V$W$X$", "Y$Z$`$B+6$- /+ %.%+%@%#%$%%%&%*%=%-%;%>%,%>%'%)%!%", "Y$~%{%]%^%= - /%(%_%:%<%[%<%}%|%1%2%3%3%4%5%6%7%8%", "9%0%a%b%c%d%d%e%f%g%h%h%h%h%h%i%j%k%h%h%k%j%g%l%m%"}; xosview-1.20/xwin.cc000066400000000000000000000332571317735352700144630ustar00rootroot00000000000000#include "xwin.h" #include "Xrm.h" #include #include #include #include #include #include //----------------------------------------------------------------------------- // argc is a reference, so that the changes to argc by XrmParseCommand are // noticed by the caller (XOSView, in this case). BCG XWin::XWin() { } //----------------------------------------------------------------------------- XWin::XWin( int argc, char *argv[], int x, int y, int width, int height ) { std::cerr << "This constructor call is not supported! (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; exit (-1); // FIXME BCG This constructor needs to do much of the work of the above // one. Or, we need to drop this as a constructor. As it is, it is // VERY MUCH out of date. x_ = x; y_ = y; width_ = width; height_ = height; (void) argc; (void) argv; } //----------------------------------------------------------------------------- void XWin::XWinInit (int argc, char** argv, char* geometry, Xrm* xrm) { (void) argc; (void) argv; // Avoid gcc warnings about unused variables. // Eventually, we may want to have XWin handle some arguments other // than resources, so argc and argv are left as parameters. BCG geometry_ = geometry; // Save for later use. width_ = height_ = x_ = y_ = 0; xrmptr_ = xrm; name_ = (char *)malloc(0); font_ = NULL; done_ = 0; // Set up the default Events events_ = NULL; addEvent( new Event( this, ClientMessage, &XWin::deleteEvent ) ); addEvent( new Event( this, MappingNotify, &XWin::mappingNotify ) ); //openDisplay(); // Done explicitly in xosview.cc. } XWin::~XWin( void ){ // delete the events Event *event = events_; while ( event != NULL ){ Event *save = event->next_; delete event; event = save; } XFree( title_.value ); XFree( iconname_.value ); XFree( sizehints_ ); XFree( wmhints_ ); XFree( classhints_ ); XFreeGC( display_, gc_ ); XFreeFont( display_, font_ ); XDestroyWindow( display_, window_ ); // close the connection to the display XCloseDisplay( display_ ); } //----------------------------------------------------------------------------- void XWin::init( int argc, char **argv ){ XGCValues gcv; XSetWindowAttributes xswa; Pixmap background_pixmap; setFont(); setColors(); getGeometry(); borderwidth_ = atoi(getResourceOrUseDefault("borderwidth", "1")); window_ = XCreateSimpleWindow(display_, DefaultRootWindow(display_), sizehints_->x, sizehints_->y, sizehints_->width, sizehints_->height, borderwidth_, fgcolor_, bgcolor_); setHints( argc, argv ); // Finally, create a graphics context for the main window gcv.font = font_->fid; gcv.foreground = fgcolor_; gcv.background = bgcolor_; gc_ = XCreateGC(display_, window_, (GCFont | GCForeground | GCBackground), &gcv); // Set main window's attributes (colormap, bit_gravity) xswa.colormap = colormap_; xswa.bit_gravity = NorthWestGravity; XChangeWindowAttributes(display_, window_, (CWColormap | CWBitGravity), &xswa); // If there is a pixmap file, set it as the background if (getPixmap(&background_pixmap)) XSetWindowBackgroundPixmap(display_,window_,background_pixmap); // add the events Event *tmp = events_; while ( tmp != NULL ){ selectEvents( tmp->mask_ ); tmp = tmp->next_; } // Map the main window map(); flush(); if(XGetWindowAttributes(display_, window_, &attr_) == 0){ std::cerr <<"Error getting attributes of Main." <res_name = (char*) xrmptr_->instanceName(); classhints_->res_class = (char*) xrmptr_->className(); // Set up the window manager hints if((wmhints_ = XAllocWMHints()) == NULL){ std::cerr <<"Error allocating Window Manager hints!" <flags = (InputHint|StateHint); wmhints_->input = True; wmhints_->initial_state = NormalState; // Set up XTextProperty for window name and icon name if(XStringListToTextProperty(&name_, 1, &title_) == 0){ std::cerr <<"Error creating XTextProperty!" <flags = PSize; sizehints_->height = height_; sizehints_->min_height = sizehints_->height; sizehints_->width = width_; sizehints_->min_width = sizehints_->width; sizehints_->x = x_; sizehints_->y = y_; // Construct a default geometry string snprintf(default_geometry, 80, "%dx%d+%d+%d", sizehints_->width, sizehints_->height, sizehints_->x, sizehints_->y); // Process the geometry specification bitmask = XGeometry(display_, DefaultScreen(display_), getResourceOrUseDefault("geometry", geometry_), default_geometry, 0, 1, 1, 0, 0, &(sizehints_->x), &(sizehints_->y), &(sizehints_->width), &(sizehints_->height)); // Check bitmask and set flags in XSizeHints structure if (bitmask & (WidthValue | HeightValue)){ sizehints_->flags |= PPosition; width_ = sizehints_->width; height_ = sizehints_->height; } if (bitmask & (XValue | YValue)){ sizehints_->flags |= USPosition; x_ = sizehints_->x; y_ = sizehints_->y; } } //----------------------------------------------------------------------------- void XWin::selectEvents( long mask ){ XWindowAttributes xAttr; XSetWindowAttributes xSwAttr; if ( XGetWindowAttributes( display_, window_, &xAttr ) != 0 ){ xSwAttr.event_mask = xAttr.your_event_mask | mask; XChangeWindowAttributes( display_, window_, CWEventMask, &xSwAttr ); } } void XWin::ignoreEvents( long mask ){ XWindowAttributes xAttr; XSetWindowAttributes xSwAttr; if ( XGetWindowAttributes( display_, window_, &xAttr ) != 0 ){ xSwAttr.event_mask = xAttr.your_event_mask & mask; XChangeWindowAttributes( display_, window_, CWEventMask, &xSwAttr ); } } //----------------------------------------------------------------------------- void XWin::checkevent( void ){ XEvent event; while ( XEventsQueued( display_, QueuedAfterReading ) ){ XNextEvent( display_, &event ); // call all of the Event's call back functions to process this event Event *tmp = events_; while ( tmp != NULL ){ tmp->callBack( event ); tmp = tmp->next_; } } } //----------------------------------------------------------------------------- void XWin::addEvent( Event *event ){ Event *tmp = events_; if ( events_ == NULL ) events_ = event; else { while ( tmp->next_ != NULL ) tmp = tmp->next_; tmp->next_ = event; } } //----------------------------------------------------------------------------- const char *XWin::getResourceOrUseDefault( const char *name, const char* defaultVal ){ const char* retval = xrmptr_->getResource (name); if (retval) return retval; else return defaultVal; } //----------------------------------------------------------------------------- const char *XWin::getResource( const char *name ){ const char* retval = xrmptr_->getResource (name); if (retval) return retval; else { std::cerr << "Error: Couldn't find '" << name << "' resource in the resource database!\n"; exit (-1); /* Some compilers aren't smart enough to know that exit() exits. */ return NULL; } } //----------------------------------------------------------------------------- void XWin::dumpResources( std::ostream &os ){ std::cerr << "Function not implemented!\n"; // BCG FIXME Need to make this. (void) os; // Keep gcc happy. } //----------------------------------------------------------------------------- unsigned long XWin::allocColor( const char *name ){ XColor exact, closest; if ( XAllocNamedColor( display_, colormap(), name, &closest, &exact ) == 0 ) std::cerr <<"XWin::allocColor() : failed to alloc : " < #include #include #include class XWin; typedef void (XWin::*EventCallBack)( XEvent &event ); class XWin { public: XWin (); XWin( int argc, char *argv[], int x, int y, int width, int height ); //XWin( int& argc, char *argv[], char *geometry ); virtual ~XWin( void ); void XWinInit ( int argc, char* argv[], char* geometry, Xrm* xrmp ); int width( void ) { return width_; } void width( int val ) { width_ = val; } int height( void ) { return height_; } void height( int val ) { height_ = val; } Display *display( void ) { return display_; } Window window( void ) { return window_; } int done( void ) { return done_; } void done( int val ) { done_ = val; } void title( const char *str ) { XStoreName( display_, window_, str ); } void iconname( const char *str ) { XSetIconName( display_, window_, str ); } void clear( void ) { XClearWindow( display_, window_ ); } void clear( int x, int y, int width, int height ) { XClearArea( display_, window_, x, y, width, height, False ); } unsigned long allocColor( const char *name ); void setForeground( unsigned long pixelvalue ) { XSetForeground( display_, gc_, pixelvalue ); } void setBackground( unsigned long pixelvalue ) { XSetBackground( display_, gc_, pixelvalue ); } void setStipple( Pixmap stipple) { if (!doStippling_) return; XSetStipple(display_, gc_, stipple); XGCValues xgcv; xgcv.fill_style = FillOpaqueStippled; XChangeGC (display_, gc_, GCFillStyle, &xgcv); } void setStippleN (int n) {setStipple(stipples_[n]); } Pixmap createPixmap(const char* data, unsigned int w, unsigned int h) { return XCreatePixmapFromBitmapData(display_, window_, const_cast(data), w, h, 0, 1, 1); } unsigned long foreground( void ) { return fgcolor_; } unsigned long background( void ) { return bgcolor_; } void resize( int width, int height ) { XResizeWindow( display_, window_, width, height ); } void lineWidth( int width ) { XGCValues xgcv; xgcv.line_width = width; XChangeGC( display_, gc_, GCLineWidth, &xgcv ); } void drawLine( int x1, int y1, int x2, int y2 ) { XDrawLine( display_, window_, gc_, x1, y1, x2, y2 ); } void drawRectangle( int x, int y, int width, int height ) { XDrawRectangle( display_, window_, gc_, x, y, width, height ); } void drawFilledRectangle( int x, int y, int width, int height ) { XFillRectangle( display_, window_, gc_, x, y, width + 1, height + 1 ); } void drawString( int x, int y, const char *str ) { XDrawString( display_, window_, gc_, x, y, str, strlen( str ) ); } void copyArea( int src_x, int src_y, int width, int height, int dest_x, int dest_y ) { XCopyArea( display_, window_, window_, gc_, src_x, src_y, width, height, dest_x, dest_y ); } int textWidth( const char *str, int n ) { return XTextWidth( font_, str, n ); } int textWidth( const char *str ) { return textWidth( str, strlen( str ) ); } int textAscent( void ) { return font_->ascent; } int textDescent( void ) { return font_->descent; } int textHeight( void ) { return textAscent() + textDescent(); } virtual void checkevent( void ); void map( void ) { XMapWindow( display_, window_ ); } void unmap( void ) { XUnmapWindow( display_, window_ ); } void flush( void ) { XFlush( display_ ); } const char *getResource( const char *name ); const char *getResourceOrUseDefault( const char *name, const char* defaultVal ); int isResourceTrue( const char* name ) { return (!strncasecmp(getResource(name),"True", 5)); } void dumpResources(std::ostream &os ); protected: class Event { public: Event( XWin *parent, int event, EventCallBack callBack ); virtual ~Event( void ){} friend class XWin; void callBack( XEvent &event ) { if ( event.type == event_ ) (parent_->*callBack_)( event ); } protected: XWin *parent_; EventCallBack callBack_; int event_; long mask_; private: Event *next_; }; int borderwidth_; // width of border int x_, y_; // position of the window int width_, height_; // width and height of the window Display *display_; // Connection to X display Window window_; // Application's main window GC gc_; // The graphics context for the window XFontStruct *font_; // Info on the default font char *name_; // Application's name XTextProperty title_; // Window name for title bar XTextProperty iconname_; // Icon name for icon label unsigned long fgcolor_; // Foreground color of the window unsigned long bgcolor_; // Background color of the window XWindowAttributes attr_; // Attributes of the window XWMHints *wmhints_; // Hints for the window manager XSizeHints *sizehints_; // Size hints for window manager XClassHint *classhints_; // Class hint for window manager Event *events_; // List of Events for this window int done_; // If true the application is finished. Atom wm_, wmdelete_; // Used to handle delete Events Colormap colormap_; // The colormap char display_name_[256]; // Display name string. char* geometry_; // geometry string. Xrm* xrmptr_; // Pointer to the XOSView xrm. FIXME??? int doStippling_; // Either 0 or 1. Pixmap stipples_[4]; // Array of Stipple masks. void init( int argc, char *argv[] ); void getGeometry( void ); int getPixmap(Pixmap *); void setDisplayName (const char* new_display_name) { strncpy (display_name_, new_display_name, 256); } const char* displayName () { return display_name_; } void addEvent( Event *event ); void setColors( void ); void openDisplay( void ); void setHints( int argc, char *argv[] ); void setFont( void ); void selectEvents( long mask ); void ignoreEvents( long mask ); void configureEvent( XEvent &event ); void mappingNotify( XEvent &event ) { XRefreshKeyboardMapping( &event.xmapping ); } void deleteEvent( XEvent &event ); //void usage( void ); Colormap colormap( void ) { return colormap_; } int screen( void ) { return DefaultScreen( display_ ); } private: }; #endif