/* * Copyright (c) 1999 * Chris D. Faulhaber . 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 as * the first lines of this file unmodified. * 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. * * THIS SOFTWARE IS PROVIDED BY CHRIS D. FAULHABER ``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 CHRIS D. FAULHABER 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. * * Portions of this software derived from examples (c) 1998 Takanori Watanabe. * * $Id: wmlmmon.c,v 1.14 1999/11/03 00:27:31 jedgar Exp $ */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SMB #include #endif #include "wmgeneral.h" #include "wmlmmon.h" #include "wmlmmon-mask.xbm" #include "wmlmmon-master.xpm" void usage() { (void)fprintf(stderr, "%s%s\n%s\n", "wmlmmon v", WMLMMON_VERSION, "usage: wmlmmon [-cfhikv] [-d display]"); exit(1); } u_char get_data(int smbdev, u_char command, int interface) { u_char return_val; return_val = 0; #ifdef HAVE_SMB if (interface == INTERFACE_SMB) { struct smbcmd cmd; u_char byte; byte = 0; /* Initialize the struct */ bzero(&cmd, sizeof(cmd)); cmd.data.byte_ptr = &byte; cmd.slave = 0x5a; cmd.cmd = command; /* Send the command */ if (ioctl(smbdev, SMB_READB, (caddr_t)&cmd) == -1) { perror("IOCTL"); exit(1); } /* Return the value */ return_val = byte; } else if (interface == INTERFACE_IO) { #endif /* HAVE_SMB */ outb(WBIO1, command); return_val = inb(WBIO2); #ifdef HAVE_SMB } #endif return return_val; } int main(int argc, char *argv[]) { double voltage; char *device_name; int byte, ch, current, delay, digit, i, scale, smbdev; int fandiv[3], fanspeed, temperature, changed, interface; XEvent Event; changed = 1; current = DISPLAY_VOLT_2; delay = DELAY; interface = INTERFACE_SMB; scale = TEMP_C; /* Get command-line options */ while ((ch = getopt(argc, argv, "cfhikvd:")) != -1) switch(ch) { case 'i': interface = INTERFACE_IO; break; case 'c': scale = TEMP_C; break; case 'f': scale = TEMP_F; break; case 'k': scale = TEMP_K; break; case 'd': break; default: usage(); break; } argc -= optind; argv += optind; if (delay < 1) delay = 1; #ifndef HAVE_SMB interface = INTERFACE_IO; #endif /* Open the device */ switch(interface) { case INTERFACE_SMB: device_name = SMB_DEV; break; default: device_name = IO_DEV; break; } if ((smbdev = open(device_name, O_RDWR)) == -1) { fprintf(stderr, "Failed to open device %s.\n", device_name); if (!strncmp(device_name, "/dev/smb", 8)) { fprintf(stderr, "If your system does not support intpm(4),\n"); fprintf(stderr, "try to use /dev/io (-i flag) or check\n"); } else { fprintf(stderr, "Check "); } fprintf(stderr, "the permissions of %s.\n", device_name); exit(1); } /* Get fan divisors */ byte = get_data(smbdev, LM78_FANDIV, interface); fandiv[0] = LM78_DIV_FROM_DATA((byte >> 4) & 0x03); fandiv[1] = LM78_DIV_FROM_DATA(byte >> 6); fandiv[2] = LM78_DIV_FROM_DATA(1); /* Create the app image */ openXwindow(argc, argv, wmlmmon_master_xpm, wmlmmon_mask_bits, wmlmmon_mask_width, wmlmmon_mask_height); /* Add regions for mouse clicks */ AddMouseRegion(0, 5, 5, 30, 19); AddMouseRegion(1, 34, 5, 59, 19); AddMouseRegion(2, 5, 17, 59, 59); /* Start our loop */ while (1) { while(XPending(display)) { XNextEvent(display,&Event); switch (Event.type) { case Expose: RedrawWindow(); break; case DestroyNotify: XCloseDisplay(display); close(smbdev); exit(0); break; case ButtonPress: i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y); switch(i) { case 1: scale = scale < 2 ? scale + 1 : 0; changed = 1; break; default: current = current < 2 ? current + 1 : 0; changed = 1; break; } break; } } /* Get motherboard temp */ temperature = LM78_TEMP_FROM_DATA(get_data(smbdev, LM78_TEMP, interface), scale); #ifdef DEBUG printf("MB temp:\n"); printf(" "); printf("%i\n", temperature); #endif if (changed) switch(scale) { case TEMP_C: copyXPMArea(13, 74, 5, 9, 53, 5); break; case TEMP_F: copyXPMArea( 1, 74, 5, 9, 53, 5); break; case TEMP_K: copyXPMArea( 7, 74, 5, 9, 53, 5); break; } digit = (int)(temperature % 10); /* 1's digit */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 47, 5); digit = (int)((temperature % 100) - digit) / 10; /* 10's digit */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 41, 5); digit = (int)((temperature % 1000) - digit) / 100; /* 100's digit */ if (digit) copyXPMArea((digit * 6) + 1, 64, 5, 9, 35, 5); else copyXPMArea(61, 64, 5, 9, 35, 5); switch(current) { case DISPLAY_FANS: if (changed) { /* Clean unused areas */ copyXPMArea(27, 85, 23, 7, 6, 50); copyXPMArea(27, 85, 23, 7, 35, 50); copyXPMArea(68, 70, 3, 3, 31, 52); /* Show 'FANS' */ copyXPMArea(43, 75, 23, 7, 6, 6); } /* Get fan speeds */ for (i = 0; i < 3; i++) { fanspeed = LM78_FAN_FROM_DATA(get_data(smbdev, LM78_FAN(i), interface), fandiv[i]); #ifdef DEBUG printf(" %i : %4d rpm\n", i + 1, fanspeed); #endif /* Clean unused areas */ if (changed) { copyXPMArea(27, 85, 23, 7, 6, (i * 10) + 20); copyXPMArea(68, 70, 3, 3, 31, (i * 10) + 22); copyXPMArea(73, 64, 1, 2, 46, (i * 10) + 26); } copyXPMArea(73, 64, 1, 2, 46, 56); copyXPMArea((i + 1) * 6 + 1, 64, 5, 9, 16, (i * 10) + 19); digit = (int)(fanspeed % 10); copyXPMArea((digit * 6) + 1, 64, 5, 9, 53, (i * 10) + 19); digit = (int)((fanspeed % 100) - digit) / 10; copyXPMArea((digit * 6) + 1, 64, 5, 9, 47, (i * 10) + 19); digit = (int)((fanspeed % 1000) - digit) / 100; copyXPMArea((digit * 6) + 1, 64, 5, 9, 41, (i * 10) + 19); digit = (int)(fanspeed - (fanspeed % 1000)) / 1000; copyXPMArea((digit * 6) + 1, 64, 5, 9, 35, (i * 10) + 19); } break; case DISPLAY_VOLT_1: if (changed) { /* Clean unused areas */ copyXPMArea(27, 85, 23, 7, 6, 50); copyXPMArea(27, 85, 23, 7, 35, 50); copyXPMArea(68, 70, 3, 3, 31, 52); /* Show 'VOLT' */ copyXPMArea(19, 75, 23, 7, 6, 6); } /* Get voltages */ for (i = 0; i < 3; i++) { int value; voltage = LM78_VOLT_FROM_DATA(get_data(smbdev, LM78_VOLT(i), interface), i); #ifdef DEBUG printf(" %i :%+8.3fV\n", i, voltage); #endif /* Clean unused areas */ if (changed) { copyXPMArea(27, 85, 23, 7, 6, (i * 10) + 20); copyXPMArea(1, 85, 23, 7, 6, 20); /* Core */ copyXPMArea(1, 85, 23, 7, 6, 30); /* Core */ copyXPMArea(68, 64, 3, 3, 7, 42); /* +3.3 */ copyXPMArea(19, 65, 5, 7, 18, 40); copyXPMArea(19, 65, 5, 7, 24, 40); copyXPMArea(73, 68, 1, 2, 23, 46); copyXPMArea(73, 68, 1, 2, 46, (i * 10) + 26); } if (voltage < 0) copyXPMArea(68, 67, 3, 3, 31, (i * 10) + 22); else copyXPMArea(68, 64, 3, 3, 31, (i * 10) + 22); value = abs((int)(voltage * 100)); digit = (int)(value % 10); /* 1's */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 53, (i * 10) + 19); digit = (int)((value % 100) - digit) / 10; /* 10's */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 47, (i * 10) + 19); digit = (int)((value % 1000) - digit) / 100; /* 100's */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 41, (i * 10) + 19); digit = (int)(value - (value % 1000)) / 1000; /* 1000's */ if (digit) copyXPMArea((digit * 6) + 1, 64, 5, 9, 35, (i * 10) + 19); else copyXPMArea(61, 64, 5, 9, 35, (i * 10) + 19); } break; case DISPLAY_VOLT_2: /* Get voltages */ for (i = 0; i < 4; i++) { int value; voltage = LM78_VOLT_FROM_DATA(get_data(smbdev, LM78_VOLT(i + 3), interface), i + 3); #ifdef DEBUG printf(" %i :%+8.3fV\n", i, voltage); #endif if (changed) { /* Show VOLT */ copyXPMArea(19, 75, 23, 7, 6, 6); /* Show labels */ copyXPMArea(27, 85, 23, 7, 6, (i * 10) + 20); copyXPMArea(68, 64, 3, 3, 7, 22); /* +5.0 */ copyXPMArea(31, 65, 5, 7, 18, 20); copyXPMArea(73, 68, 1, 2, 23, 26); copyXPMArea( 1, 65, 5, 7, 24, 20); copyXPMArea(68, 64, 3, 3, 7, 32); /* +12.0 */ copyXPMArea( 7, 65, 5, 7, 12, 30); copyXPMArea(13, 65, 5, 7, 18, 30); copyXPMArea(73, 68, 1, 2, 23, 36); copyXPMArea( 1, 65, 5, 7, 24, 30); copyXPMArea(68, 67, 3, 3, 7, 42); /* -12.0 */ copyXPMArea( 7, 65, 5, 7, 12, 40); copyXPMArea(13, 65, 5, 7, 18, 40); copyXPMArea(73, 68, 1, 2, 23, 46); copyXPMArea( 1, 65, 5, 7, 24, 40); copyXPMArea(68, 67, 3, 3, 7, 52); /* -5.0 */ copyXPMArea(31, 65, 5, 7, 18, 50); copyXPMArea(73, 68, 1, 2, 23, 56); copyXPMArea( 1, 65, 5, 7, 24, 50); } copyXPMArea(73, 68, 1, 2, 46, (i * 10) + 26); if (voltage < 0) copyXPMArea(68, 67, 3, 3, 31, (i * 10) + 22); else copyXPMArea(68, 64, 3, 3, 31, (i * 10) + 22); value = abs((int)(voltage * 100)); digit = (int)(value % 10); /* 1's */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 53, (i * 10) + 19); digit = (int)((value % 100) - digit) / 10; /* 10's */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 47, (i * 10) + 19); digit = (int)((value % 1000) - digit) / 100; /* 100's */ copyXPMArea((digit * 6) + 1, 64, 5, 9, 41, (i * 10) + 19); digit = (int)(value - (value % 1000)) / 1000; /* 1000's */ if (digit) copyXPMArea((digit * 6) + 1, 64, 5, 9, 35, (i * 10) + 19); else copyXPMArea(61, 64, 5, 9, 35, (i * 10) + 19); } break; } RedrawWindow(); changed = 0; sleep(delay); } return 0; }