diff --git a/Makefile.in b/Makefile.in index 3751322..5e323c6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -171,6 +171,9 @@ Filesystem : filesystem.o $(LIBAMI) Keyboard : kbdmodule.o kbdlexer.o $(LIBAMI) $(CC) -o Keyboard kbdmodule.o kbdlexer.o $(LIBS) +Battery : battery_module.o $(LIBAMI) + $(CC) -o Battery battery_module.o $(LIBS) + Launcher : launchermodule.o $(LIBAMI) $(CC) -o Launcher launchermodule.o $(LIBS) @@ -181,7 +184,7 @@ localetest : localetest.o $(LIBAMI) $(CC) -o localetest localetest.o $(LIBS) clean : lib_clean - $(RM) core $(PROGS) $(LIBAMI) Keyboard Launcher *.o + $(RM) core $(PROGS) $(LIBAMI) Keyboard Battery Launcher *.o $(RM) lex.yy.c lex.c y.tab.c y.tab.h gram.h gram.c $(RM) kbdlexer.c kbdmodule.h kbdmodule.c $(RM) config.log diff --git a/battery_module.c b/battery_module.c new file mode 100644 index 0000000..272b4a6 --- /dev/null +++ b/battery_module.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include + +#include + +#define APM_DEV "/dev/apm" + +#include "libami.h" + +/* + * Test battery module for FreeBSD, using APM. + */ + +void docmd(XEvent *e, void *callback) +{ + ((void (*)(Window))callback)(e->xany.window); +} + +static char *progname; +static int apm_fd = -1; + +static bool +get_apm_info(void) +{ + int ret; + struct apm_info info; + + ret = ioctl(apm_fd, APMIO_GETINFO, &info); + if (ret < 0) { + warn("ioctl (APMIO_GETINFO)"); + return false; + } + + printf("Battery life: %d\n", info.ai_batt_life); + printf("Battery time: %d\n", info.ai_batt_time); + printf("Battery AC: %d\n", info.ai_acline); + + md_update_battery(info.ai_batt_life, info.ai_batt_time, + info.ai_acline); + + return true; +} + +int main(int argc, char *argv[]) +{ + char *arg=md_init(argc, argv); + + progname=argv[0]; + + apm_fd = open(APM_DEV, O_RDONLY); + if (apm_fd < 0) { + err(127, "open"); + } + + /* + * XXX TODO: how do I actually get this to run once + * a second in the main loop? + */ + get_apm_info(); + + md_main_loop(); + + close(apm_fd); + return 0; +} diff --git a/libami/Makefile.in b/libami/Makefile.in index c53816f..dc27c58 100644 --- a/libami/Makefile.in +++ b/libami/Makefile.in @@ -19,12 +19,12 @@ LN_S = @LN_S@ RM = -rm -f OBJS = drawinfo.o module.o broker.o eventdispatcher.o mdscreen.o \ - mdicon.o mdwindow.o kbdsupport.o hotkey.o \ + mdicon.o mdwindow.o kbdsupport.o hotkey.o mdbattery.o \ lists.o readargs.o iconlib.o iconutil.o error.o strutil.o \ iffparse.o gadget_button.o gadget_textbox.o gadget_textinput.o SRCS = drawinfo.c module.c broker.c eventdispatcher.c mdscreen.c \ - mdicon.c mdwindow.c kbdsupport.c hotkey.c \ + mdicon.c mdwindow.c kbdsupport.c hotkey.c mdbattery.c \ lists.c readargs.c iconlib.c iconutil.c error.c strutil.c \ iffparse.c gadget_button.c gadget_textbox.c gadget_textinput.c diff --git a/libami/libami.h b/libami/libami.h index 160dbea..5e9e662 100644 --- a/libami/libami.h +++ b/libami/libami.h @@ -389,6 +389,9 @@ extern Pixmap md_image_to_pixmap(Window, unsigned long, struct Image *, int, int, struct ColorStore *); extern char *get_current_icondir(void); +/* mdbattery.c */ +extern void md_update_battery(int pct, int time, int ac); + /* mdwindow.c */ extern int md_set_appwindow(Window); diff --git a/libami/mdbattery.c b/libami/mdbattery.c new file mode 100644 index 0000000..24bab6a --- /dev/null +++ b/libami/mdbattery.c @@ -0,0 +1,85 @@ +#include +#include + +#include "libami.h" +#include "module.h" +#include "alloc.h" + +void +md_update_battery(int pct, int time, int ac) +{ + struct mcmd_update_battery batt = { 0 }; + int res; + + batt.battery_time = time; + batt.battery_pct = pct; + batt.battery_ac = ac; + + res = md_command0(None, MCMD_UPDATE_BATTERY, &batt, sizeof(batt)); + (void) res; +} + +Window md_create_appicon(Window p, int x, int y, char *name, + Pixmap pm1, Pixmap pm2, Pixmap pmm) +{ + char *data; + Window w; + int res, l=strlen(name); +#ifdef HAVE_ALLOCA + struct NewAppIcon *nai=alloca(sizeof(struct NewAppIcon)+l); +#else + struct NewAppIcon *nai=malloc(sizeof(struct NewAppIcon)+l); + if(nai==NULL) return None; +#endif + nai->x=x; nai->y=y; + nai->pm1=pm1; nai->pm2=pm2; nai->pmm=pmm; + strcpy(nai->name, name); + res=md_command(p, MCMD_CREATEAPPICON, nai, sizeof(struct NewAppIcon)+l, + &data); + if(res=0 && p) + return p; + if(p) free(p); + return NULL; +} + diff --git a/menu.c b/menu.c index eba1e1f..0ec80de 100644 --- a/menu.c +++ b/menu.c @@ -485,9 +485,16 @@ void createmenubar() } } +/* + * Redraw the menu bar and its components. + * + * This takes in the target window, which may be the basic menubar, + * a clicked-on menu, or the depth widget. + */ void redrawmenubar(Window w) { static const char defaultTimeFormat[] = "%c"; + int widget_rhs; struct Menu *m; struct Item *item; @@ -495,6 +502,7 @@ void redrawmenubar(Window w) if(!w) return; if(w==scr->menubar) { + /* Menubar itself */ XSetForeground(dpy, scr->menubargc, scr->dri.dri_Pens[BARDETAILPEN]); XSetBackground(dpy, scr->menubargc, scr->dri.dri_Pens[BARBLOCKPEN]); #ifdef USE_FONTSETS @@ -507,6 +515,13 @@ void redrawmenubar(Window w) #endif XSetForeground(dpy, scr->menubargc, scr->dri.dri_Pens[BARTRIMPEN]); XDrawLine(dpy, w, scr->menubargc, 0, scr->bh-1, scr->width-1, scr->bh-1); + + /* Widgets start here and move to the left */ + widget_rhs = (scr->width - 30); + /* + * Update the title bar clock if it's enabled. + */ + if( prefs.titlebarclock ) { char clockbuf[512]; @@ -519,15 +534,38 @@ void redrawmenubar(Window w) #ifdef USE_FONTSETS l = XmbTextEscapement(scr->dri.dri_FontSet, clockbuf, strlen(clockbuf)); XmbDrawImageString(dpy, w, scr->dri.dri_FontSet, scr->menubargc, - (scr->width-30-l), 1+scr->dri.dri_Ascent, + widget_rhs - l, 1+scr->dri.dri_Ascent, clockbuf, strlen(clockbuf)); #else l = XTextWidth(scr->dri.dri_Font, clockbuf, strlen(clockbuf)); - XDrawImageString( dpy, w, scr->menubargc,(scr->width-30-l), + XDrawImageString( dpy, w, scr->menubargc, widget_rhs - l, 1+scr->dri.dri_Ascent, clockbuf, strlen(clockbuf)); #endif - } + widget_rhs = widget_rhs - l - 8; // 8 = padding + } + + /* + * Update the battery indicator if it's enabled. + */ + if (1) { + char battery_buf[512]; + int l; + + sprintf(battery_buf, "| Battery |"); +#ifdef USE_FONTSETS + l = XmbTextEscapement(scr->dri.dri_FontSet, battery_buf, strlen(battery_buf)); + XmbDrawImageString(dpy, w, scr->dri.dri_FontSet, scr->menubargc, + widget_rhs - l, 1+scr->dri.dri_Ascent, + battery_buf, strlen(battery_buf)); +#else + l = XTextWidth(scr->dri.dri_Font, battery_buf, strlen(battery_buf)); + XDrawImageString( dpy, w, scr->menubargc, widget_rhs - l, + 1+scr->dri.dri_Ascent, battery_buf, strlen(battery_buf)); +#endif + widget_rhs = widget_rhs - l - 8; // 8 = padding + } } else if(w==scr->menubardepth) { + /* Menubar depth widget */ if(!mbdclick) { XSetForeground(dpy, scr->menubargc, scr->dri.dri_Pens[SHADOWPEN]); XDrawRectangle(dpy, w, scr->menubargc, 4, scr->h2, 10, scr->h6-scr->h2); @@ -545,6 +583,7 @@ void redrawmenubar(Window w) XDrawLine(dpy, w, scr->menubargc, 0, scr->bh-1, 22, scr->bh-1); XDrawLine(dpy, w, scr->menubargc, 22, 0, 22, scr->bh-1); } else { + /* One of the menus is being displayed */ for(m=scr->firstmenu; m; m=m->next) if(m->win==w) redraw_menu(m, w); diff --git a/module.c b/module.c index 3b1bb7b..955e2f6 100644 --- a/module.c +++ b/module.c @@ -490,6 +490,27 @@ static void handle_module_cmd(struct module *m, char *data, int data_len) } else reply_module(m, NULL, -1); break; + case MCMD_UPDATE_BATTERY: + { + struct mcmd_update_battery *batt; + if (data_len != sizeof(struct mcmd_update_battery)) { + reply_module(m, NULL, -1); + break; + } + batt = (void *) data; + + fprintf(stderr, "%s: called, BATTERY, pct=%d, time=%d, ac=%d\n", + __func__, + batt->battery_pct, + batt->battery_time, + batt->battery_ac); + + /* XXX TODO: update the battery menu thingy here */ + + reply_module(m, NULL, 0); + break; + } + break; default: reply_module(m, NULL, -1); } diff --git a/module.h b/module.h index 9c891f1..4d227dd 100644 --- a/module.h +++ b/module.h @@ -16,6 +16,7 @@ #define MCMD_MANAGEMENU 18 #define MCMD_ROTATE_WINDOW_RAISE 19 #define MCMD_ROTATE_WINDOW_LOWER 20 +#define MCMD_UPDATE_BATTERY 21 struct mcmd_header { XID id; @@ -42,6 +43,14 @@ struct NewAppIcon { char name[1]; }; +struct mcmd_update_battery { + int battery_time; + int battery_pct; + int battery_cap; + int battery_ac; + int battery_charging; +}; + extern struct module { struct module *next; int in_fd, out_fd;