/*
* Copyright (c) 1999
* Chris D. Faulhaber <jedgar@fxp.org>. 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 <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <machine/cpufunc.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include <X11/Xlibint.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SMB
#include <machine/smb.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1