--- modules/FvwmTaskBar/FvwmTaskBar.c.orig Tue May 6 21:08:20 1997 +++ modules/FvwmTaskBar/FvwmTaskBar.c Tue May 6 21:13:42 1997 @@ -60,6 +60,9 @@ #include "Mallocs.h" #include "Goodies.h" #include "Start.h" +#ifdef APM +#include "apm.h" +#endif #define GRAB_EVENTS (ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|EnterWindowMask|LeaveWindowMask) @@ -796,6 +799,12 @@ if (Tip.type != START_TIP) PopupTipWindow(3, 0, "Click here to start"); Tip.type = START_TIP; } +#ifdef APM + else if (MouseInBattery(x, y)) { + if (Tip.type != BATTERY_TIP) CreateBatteryWindow(); + Tip.type = BATTERY_TIP; + } +#endif /* APM */ else if (MouseInMail(x, y)) { if (Tip.type != MAIL_TIP) CreateMailTipWindow(); Tip.type = MAIL_TIP; @@ -883,6 +892,10 @@ SendFvwmPipe(tmp, ItemID(&windows, 0)); } else if (MouseInMail(Event.xbutton.x, Event.xbutton.y)) { HandleMailClick(Event); +#ifdef APM + } else if (MouseInBattery(Event.xbutton.x, Event.xbutton.y)) { + HandleBatteryClick(Event); +#endif /* APM */ } else { num = WhichButton(&buttons, Event.xbutton.x, Event.xbutton.y); UpdateButton(&buttons, num, NULL, (ButPressed == num) ? --- modules/FvwmTaskBar/Goodies.c.orig Tue May 6 21:08:20 1997 +++ modules/FvwmTaskBar/Goodies.c Tue May 6 21:13:42 1997 @@ -17,6 +17,11 @@ #include #include "Goodies.h" #include "minimail.xbm" +#ifdef APM +#include "apm.h" +#include "minibatt.xbm" +#include "minibatt2.xbm" +#endif /* APM */ extern Display *dpy; extern Window Root, win; @@ -39,7 +44,20 @@ #endif int stwin_width = 100, goodies_width = 0; int anymail, unreadmail, newmail, mailcleared = 0; +#ifdef APM +static int fontheight, clock_width, battery_width = 0; +char ac_str[] = " !*"; +char *acline_str[] = {"AC off-line","AC on-line","On backup power"}; +char *battstat_str[] = {"high", "low", "critical", "charging", "unknown"}; +Pixmap battpix, batt2pix, battrpix, battr2pix; +XSegment *BattSign; +int ShowBatteryStatus = False, ShowBatteryStatusP = False; +char *BattFore = "NavyBlue", *BattFore2 = "Gold"; +unsigned long battc_fore, battc_fore2, battc_red, battc_white; +struct apm_info prev_ap; void CreateBatteryWindow(); +#else int fontheight, clock_width; +#endif /* APM */ char *mailpath = NULL; char *clockfmt = NULL; int BellVolume = DEFAULT_BELL_VOLUME; @@ -65,6 +83,7 @@ /* Parse 'goodies' specific resources */ void GoodiesParseConfig(char *tline, char *Module) { + char *str; if(strncasecmp(tline,CatString3(Module, "BellVolume",""), Clength+10)==0) { BellVolume = atoi(&tline[Clength+11]); @@ -100,6 +119,29 @@ Clength+8)==0) { ShowTips = True; } +#ifdef APM + else if(strncasecmp(tline,CatString3(Module, "ShowBatteryStatus",""), + Clength+17)==0) { + ShowBatteryStatus = True; + if (strncasecmp(&tline[Clength+18], "Sign", 4)!=0) { + ac_str[2]= tline[Clength+18]; + if (strncasecmp(&tline[Clength+18], "Icon", 4)==0) + ShowBatteryStatus = BATT_ICON; + if (strncasecmp(&tline[Clength+22], "P", 1)==0) + ShowBatteryStatusP = True; + } + } if(strncasecmp(tline,CatString3(Module, "BatteryColor",""), + Clength+12)==0) { + str = &tline[Clength+12]; + while(*++str > ' ' && *str != '\t'); + if (isspace((unsigned char)*str)) { + *(str++) = '\n'; + while(isspace((unsigned char)*str)) str++; + if (*str > ' ') CopyString(&BattFore2, str); + } + CopyString(&BattFore, &tline[Clength+12]); + } +#endif /* APM */ } void InitGoodies() { @@ -147,7 +189,14 @@ gcval.font = StatusFont->fid; gcval.graphics_exposures = False; statusgc = XCreateGC(dpy, Root, gcmask, &gcval); - +#ifdef APM + battc_white = GetColor("white"); + battc_red = GetColor("red"); + battc_fore2 = GetColor(BattFore2); + battc_fore = GetColor(BattFore); + BattSign = (XSegment *)safemalloc(sizeof(XSegment) * 3); +#endif + if (!NoMailCheck) { mailpix = XCreatePixmapFromBitmapData(dpy, win, (char *)minimail_bits, minimail_width, minimail_height, @@ -166,8 +215,30 @@ tms = localtime(&timer); strftime(str, 24, clockfmt, tms); clock_width = XTextWidth(StatusFont, str, strlen(str)) + 4; + } else + clock_width = XTextWidth(StatusFont, "XX:XX", 5) + 4; +#ifdef APM + if (ShowBatteryStatus && apm_exists()) { + if (ShowBatteryStatus == BATT_ICON) { + battpix = XCreatePixmapFromBitmapData(dpy, win, (char *)minibatt_bits, + minibatt_width, minibatt_height, + fore, back, d_depth); + batt2pix = XCreatePixmapFromBitmapData(dpy, win, (char *)minibatt2_bits, + minibatt2_width, minibatt2_height, + fore, back, d_depth); + battrpix = XCreatePixmapFromBitmapData(dpy, win, (char *)minibatt_bits, + minibatt_width, minibatt_height, + battc_red, back, d_depth); + battr2pix = XCreatePixmapFromBitmapData(dpy, win, (char *)minibatt2_bits, + minibatt2_width, minibatt2_height, + battc_red, back, d_depth); + battery_width = minibatt_width + 7; + } else { + battery_width = XTextWidth(StatusFont, "--XX%", 5) + 4; + } + goodies_width += battery_width; } - else clock_width = XTextWidth(StatusFont, "XX:XX", 5) + 4; +#endif /* APM */ goodies_width += clock_width; stwin_width = goodies_width; } @@ -188,6 +259,12 @@ static char str[40]; static time_t timer; static int last_mail_check = -1; +#ifdef APM + static struct apm_info ap; + static char battery[10]; + int batt_height, batt_ofs; + int batt_line, i; +#endif /* APM */ time(&timer); tms = localtime(&timer); @@ -199,10 +276,100 @@ } Draw3dBox(win, win_width - stwin_width, 0, stwin_width, RowHeight); - XDrawString(dpy,win,statusgc, - win_width - stwin_width + 4, - ((RowHeight - fontheight) >> 1) +StatusFont->ascent, - str, strlen(str)); +#ifdef APM + if (ShowBatteryStatus && apm_read(ShowBatteryStatusP, &ap)) { + if (ShowBatteryStatus == BATT_ICON) { + /* 5 <= Battery Life < 15 --> 10% */ + batt_line = (int)((ap.ai_batt_life +5) / 10); + batt_height = (RowHeight - minibatt_height) +1; + batt_ofs = win_width - stwin_width + clock_width +10; + if (ap.ai_acline == 1) { + XCopyArea(dpy, (ap.ai_status ? batt2pix:battr2pix), + win, statusgc, 0, 0, + minibatt2_width, minibatt2_height, + win_width - stwin_width + clock_width +3, + (RowHeight - minibatt2_height) >> 1); + XSetForeground(dpy, statusgc, battc_fore2); + XFillRectangle(dpy, win, statusgc, batt_ofs -6, batt_height +2, + 3, 3); /* fill plug */ + } else { + XCopyArea(dpy, + (ap.ai_status ? battpix:battrpix), + win, statusgc, 0, 0, + minibatt_width, minibatt_height, + win_width - stwin_width + clock_width +3, + (RowHeight - minibatt_height) >> 1); + } + if (batt_line) { + if (ap.ai_batt_life <= 40 || ap.ai_batt_stat == APM_STAT_BATT_LOW) + XSetForeground(dpy, statusgc, battc_fore2); + else + XSetForeground(dpy, statusgc, battc_fore); + XFillRectangle(dpy, win, statusgc, + batt_ofs, batt_height +9 - batt_line, 9, batt_line); + } + if (10 - batt_line) { + XSetForeground(dpy, statusgc, battc_white); + XFillRectangle(dpy, win, statusgc, batt_ofs +3, batt_height -4, 3, 2); + XFillRectangle(dpy, win, statusgc, batt_ofs, batt_height -1, + 9, 10 - batt_line); + } + XDrawPoint(dpy, win, statusgc, batt_ofs, batt_height -2); + XDrawPoint(dpy, win, statusgc, batt_ofs +8, batt_height -2); + XSetForeground(dpy, statusgc, (ap.ai_status ? fore:battc_red)); + XDrawPoint(dpy, win, statusgc, batt_ofs, batt_height +8); + XDrawPoint(dpy, win, statusgc, batt_ofs +8, batt_height +8); + XSetForeground(dpy, statusgc, battc_red); + if ((ap.ai_batt_life <= 15 || ap.ai_batt_stat == APM_STAT_BATT_CRITICAL) + && ap.ai_acline == APM_STAT_LINE_OFF) { + XSetLineAttributes(dpy, statusgc, 2, LineSolid, CapButt, JoinMiter); + BattSign[0] = (XSegment){batt_ofs -2, batt_height -3, + batt_ofs +minibatt_width-6, batt_height+9}; + BattSign[1] = (XSegment){batt_ofs+minibatt_width -6, batt_height -3, + batt_ofs -2, batt_height +9}; + XDrawSegments(dpy, win, statusgc, BattSign, 2); /* criss-cross */ + XSetLineAttributes(dpy, statusgc, 1, + LineSolid, CapProjecting, JoinMiter); + } else { + BattSign[0] = (XSegment){batt_ofs +3, batt_height, + batt_ofs +5, batt_height}; + BattSign[1] = (XSegment){batt_ofs +4, batt_height -1, + batt_ofs +4, batt_height +1}; + BattSign[2] = (XSegment){batt_ofs +3, batt_height +7, + batt_ofs +5, batt_height +7}; + XDrawSegments(dpy, win, statusgc, BattSign, 3); /* +- */ + } + XSetForeground(dpy, statusgc, fore); + XDrawString(dpy,win,statusgc, + win_width - stwin_width +4, + ((RowHeight - fontheight) >> 1) +StatusFont->ascent, + str, strlen(str)); + } else { + XDrawString(dpy,win,statusgc, + win_width - stwin_width +4, + ((RowHeight - fontheight) >> 1) +StatusFont->ascent, + str, strlen(str)); + if (ap.ai_batt_life < 10 && ap.ai_acline == 0) { + XSetForeground(dpy, statusgc, battc_red); + } + sprintf(battery, "%d%%%c", + ap.ai_batt_life, ac_str[ap.ai_acline]); + XDrawString(dpy,win,statusgc, + win_width - stwin_width + clock_width +4, + ((RowHeight - fontheight) >> 1) +StatusFont->ascent, + battery, strlen(battery)); + if (ap.ai_batt_life < 10 && ap.ai_acline == 0) { + XSetForeground(dpy, statusgc, fore); + } + } + } else { /* ShowBatteryStatus && apm_read(&ap) */ +#endif /* APM */ + XDrawString(dpy,win,statusgc, win_width - stwin_width + 4, + ((RowHeight - fontheight) >> 1) +StatusFont->ascent, + str, strlen(str)); +#ifdef APM + } +#endif if (NoMailCheck) return; if (timer - last_mail_check >= 10) { @@ -215,22 +382,45 @@ if (!mailcleared && (unreadmail || newmail)) XCopyArea(dpy, wmailpix, win, statusgc, 0, 0, minimail_width, minimail_height, - win_width - stwin_width + clock_width + 3, - ((RowHeight - minimail_height) >> 1)); + win_width - stwin_width + clock_width + 2 +#ifdef APM + + battery_width +#endif + , ((RowHeight - minimail_height) >> 1)); else if (!IgnoreOldMail /*&& !mailcleared*/ && anymail) XCopyArea(dpy, mailpix, win, statusgc, 0, 0, minimail_width, minimail_height, - win_width - stwin_width + clock_width + 3, - ((RowHeight - minimail_height) >> 1)); + win_width - stwin_width + clock_width + 2 +#ifdef APM + + battery_width +#endif + , ((RowHeight - minimail_height) >> 1)); if (Tip.open) { - if (Tip.type == DATE_TIP) + if (Tip.type == DATE_TIP) { if (tms->tm_mday != last_date) /* reflect date change */ CreateDateWindow(); /* This automatically deletes any old window */ + } +#ifdef APM + else if (Tip.type == BATTERY_TIP) { + if (ShowBatteryStatus && apm_read(ShowBatteryStatusP, &ap)) { + /* reflect battery status change */ + if (ap.ai_acline != prev_ap.ai_acline || + prev_ap.ai_batt_stat != ap.ai_batt_stat || + prev_ap.ai_batt_life != ap.ai_batt_life || + prev_ap.ai_status != ap.ai_status) { + CreateBatteryWindow(); + } + } + } + prev_ap.ai_acline = ap.ai_acline; + prev_ap.ai_batt_stat = ap.ai_batt_stat; + prev_ap.ai_batt_life = ap.ai_batt_life; + prev_ap.ai_status = ap.ai_status; +#endif last_date = tms->tm_mday; RedrawTipWindow(); } - } int MouseInClock(int x, int y) { @@ -239,8 +429,20 @@ return (x>=clockl && x1 && y=battl && x1 && y=maill && x1 && y +#include + +#define APM_DEVICE "/dev/apm" +#define BATT_ICON (True+1) + +#define APM_STAT_UNKNOWN 255 +#define APM_STAT_LINE_OFF 0 +#define APM_STAT_LINE_ON 1 + +#define APM_STAT_BATT_HIGH 0 +#define APM_STAT_BATT_LOW 1 +#define APM_STAT_BATT_CRITICAL 2 +#define APM_STAT_BATT_CHARGING 3 +#define APM_STAT_BATT_UNKNOWN 4 + +#define APM_POWERTOGGLE 1 +#define APM_POWERENABLE 0 +#define APM_POWERDISABLE -1 +#define APM_CPUHALT 1 +#define APM_CPUNOTHALT 0 + +extern int apm_exists(void); +extern int apm_read(int percent, apm_info_t i); +extern int apm_power(int enable_apm); +extern int apm_cpuhalt(int haltcpu); --- modules/FvwmTaskBar/apmlib.c.orig Tue May 6 21:13:42 1997 +++ modules/FvwmTaskBar/apmlib.c Tue May 6 21:13:43 1997 @@ -0,0 +1,76 @@ +/* + * apmlib.c -- APM interface for fvwm95 Tips on FreeBSD + * $Id: apmlib.c,v 1.2 1997/05/05 03:00:53 ryo2 Exp ryo2 $ + */ + +#include +#include +#include +#include +#include "apm.h" + +/* returns 0 on failure, 1 on success */ +int apm_exists(void) { + if (open(APM_DEVICE, O_RDWR) == -1) return 0; + return 1; +} + +/* returns 0 on failure, 1 on success */ +int apm_read(int percent, apm_info_t i) { + int fd; + + if (!(fd = open(APM_DEVICE, O_RDWR))) return 0; + if (ioctl(fd, APMIO_GETINFO, i) == -1) return 0; + + if (i->ai_batt_stat > APM_STAT_BATT_UNKNOWN) + i->ai_batt_stat = APM_STAT_BATT_UNKNOWN; + if (i->ai_batt_life == APM_STAT_UNKNOWN) { + if (percent) { + /* for the BIOS that returns batt_life */ + i->ai_batt_life = 0; + } else { + if (i->ai_batt_stat == APM_STAT_BATT_HIGH) { + i->ai_batt_life = 100; + } else if (i->ai_batt_stat == APM_STAT_BATT_LOW) { + i->ai_batt_life = 40; + } else if (i->ai_batt_stat == APM_STAT_BATT_CRITICAL) { + i->ai_batt_life = 10; + } else { + /* expected to be APM_STAT_BATT_CHARGING */ + i->ai_batt_life = 30; + } + } + } + if (i->ai_batt_life > 100) i->ai_batt_life = 100; + close(fd); + return 1; +} + +/* toggle apm and/or halt cpu */ +int apm_power (int enable_apm) { + int fd; + struct apm_info ap; + + if (!(fd = open(APM_DEVICE, O_RDWR))) return 0; + if (enable_apm == APM_POWERTOGGLE) { + if (ioctl(fd, APMIO_GETINFO, &ap) == -1) return 0; + } else { + ap.ai_status = enable_apm; + } + if (ioctl(fd, (ap.ai_status ? APMIO_DISABLE:APMIO_ENABLE), NULL) == -1) + return 0; + return 1; +} + +#ifdef CPUHALT +/* halt or nohalt cpu */ +int apm_cpuhalt (int haltcpu) { + int fd; + struct apm_info ap; + + if (!(fd = open(APM_DEVICE, O_RDWR))) return 0; + if (ioctl(fd, (haltcpu ? APMIO_HALTCPU:APMIO_NOTHALTCPU), NULL) == -1) + return 0; + return 1; +} +#endif /* CPUHALT */ --- modules/FvwmTaskBar/minibatt.xbm.orig Tue May 6 21:13:43 1997 +++ modules/FvwmTaskBar/minibatt.xbm Tue May 6 21:13:43 1997 @@ -0,0 +1,7 @@ +#define minibatt_width 17 +#define minibatt_height 15 +static unsigned char minibatt_bits[] = { + 0x00, 0x3c, 0x00, 0x80, 0xe3, 0x00, 0xc0, 0xa2, 0x01, 0x40, 0x7f, 0x01, + 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, + 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, + 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x80, 0xff, 0x00, }; --- modules/FvwmTaskBar/minibatt2.xbm.orig Tue May 6 21:13:43 1997 +++ modules/FvwmTaskBar/minibatt2.xbm Tue May 6 21:13:43 1997 @@ -0,0 +1,7 @@ +#define minibatt2_width 17 +#define minibatt2_height 15 +static unsigned char minibatt2_bits[] = { + 0x00, 0x3c, 0x00, 0x80, 0xe3, 0x00, 0xc0, 0xa2, 0x01, 0x40, 0x7f, 0x01, + 0x4a, 0x00, 0x01, 0x4a, 0x00, 0x01, 0x5f, 0x00, 0x01, 0x51, 0x00, 0x01, + 0x51, 0x00, 0x01, 0x51, 0x00, 0x01, 0x4e, 0x00, 0x01, 0x44, 0x00, 0x01, + 0x44, 0x00, 0x01, 0x47, 0x00, 0x01, 0x80, 0xff, 0x00, }; --- modules/FvwmTaskBar/Goodies.h.orig Tue May 6 21:08:21 1997 +++ modules/FvwmTaskBar/Goodies.h Tue May 6 21:13:44 1997 @@ -10,6 +10,9 @@ #define DATE_TIP (-2) #define MAIL_TIP (-3) #define START_TIP (-4) +#ifdef APM +#define BATTERY_TIP (-5) +#endif typedef struct { int x, y, w, h, tw, th, open, type; --- modules/FvwmTaskBar/FvwmTaskBar.man.orig Wed Dec 11 03:09:59 1996 +++ modules/FvwmTaskBar/FvwmTaskBar.man Tue May 6 21:13:44 1997 @@ -156,7 +156,7 @@ .IP "*FvwmTaskBarMailBox \fIpath\fP" This option intructs the module to look for mail at the specified place It is a full pathname to the user's mailbox. -By default it is \fI/var/spool/mail/$USER_LOGIN\fP. +By default it is \fI/var/mail/$USER_LOGIN\fP. A value of 'None' instructs the module not to have a mail indicator. .IP "*FvwmTaskBarMailCommand \fIcommand\fP" @@ -165,6 +165,17 @@ .IP "*FvwmTaskBarIgnoreOldMail" If set, draw no bitmap if there is no new mail. + +.IP "*FvwmTaskBarShowBatteryStatus \fItype\fP" +Specifies the type of battery status as to be 'Icon' or 'Sign'. +The latter will show digital characters instead of the battery icon. +Double-clicking the icon is the toggle switch to enable or +disable the advanced power management. + +.IP "*FvwmTaskBarBatteryColor \fIcolor1\fP \fIcolor2\fP" +Specifies the battery icon colors. Color2 is the color if the +remaining battery life is less than fourty percents, or color1 will be +used. By default "NavyBlue Gold". .SH "" The following options deal with the Start button at the left of the taskbar: --- modules/FvwmTaskBar/Makefile.in.orig Tue May 6 21:08:21 1997 +++ modules/FvwmTaskBar/Makefile.in Tue May 6 21:13:45 1997 @@ -36,8 +36,8 @@ PROG=FvwmTaskBar -SRCS=FvwmTaskBar.c List.c ButtonArray.c Mallocs.c Colors.c Goodies.c Start.c -OBJS=FvwmTaskBar.o List.o ButtonArray.o Mallocs.o Colors.o Goodies.o Start.o +SRCS=FvwmTaskBar.c List.c ButtonArray.c Mallocs.c Colors.c Goodies.c Start.c apmlib.c +OBJS=FvwmTaskBar.o List.o ButtonArray.o Mallocs.o Colors.o Goodies.o Start.o apmlib.o all: ${PROG} --- configure.in.orig Tue May 6 21:08:28 1997 +++ configure.in Tue May 6 21:13:45 1997 @@ -174,7 +174,7 @@ if test "x$x_includes" != x ; then x_includes="-I$x_includes" fi -local_defines="-DI18N" +local_defines="-DI18N -DAPM" #------------------------------------------------------------------- # --- configure.orig Tue May 6 21:08:28 1997 +++ configure Tue May 6 21:45:12 1997 @@ -2131,7 +2131,7 @@ if test "x$x_includes" != x ; then x_includes="-I$x_includes" fi -local_defines="-DI18N" +local_defines="-DI18N -DAPM" #------------------------------------------------------------------- #