/* * This is a simple X11 program that displays the battery percentage * on NetBSD. * * It should be compiled with the following flags: * * CFLAGS = -I/usr/X11R7/include -I/usr/pkg/include * LDFLAGS = -lXm -L/usr/X11R7/lib -L/usr/pkg/lib * LDFLAGS += -Wl,-R/usr/X11R7/lib -Wl,-R/usr/pkg/lib * * It requires x11/motif to be installed. * * The program uses the following resources: * * xbattext*fontList = normal font * xbattext*foreground = normal text color * xbattext*alertFontList = font when battery is low * xbattext*alertForeground = text color when battery is low * * Set their values in ~/.Xdefaults to customize xbattext. * * xbattext is written by John Ankarstr\xf6m and * is released into the public domain; do whatever you want with it. */ #include #include #include #include #include #include #include /* interval in seconds */ #define INTERVAL 15 /* low battery level */ #define ALERT 30 void update(XtPointer, XtIntervalId *); /* resources */ struct _res { XmFontList font_list; XmFontList alert_font_list; Pixel foreground; Pixel alert_foreground; } res; static XtResource res_opts[] = { {"fontList", "FontList", XmRFontList, sizeof(XmFontList), XtOffset(struct _res*, font_list), XtRImmediate, (caddr_t)NULL}, {"foreground", "foreground", XmRPixel, sizeof(Pixel), XtOffset(struct _res*, foreground), XtRImmediate, (caddr_t)NULL}, {"alertFontList", "AlertFontList", XmRFontList, sizeof(XmFontList), XtOffset(struct _res*, alert_font_list), XtRImmediate, (caddr_t)NULL}, {"alertForeground", "AlertForeground", XmRPixel, sizeof(Pixel), XtOffset(struct _res*, alert_foreground), XtRImmediate, (caddr_t)NULL}, }; /* application state */ Arg wargs[10]; char *s; int apmfd, alert; struct apm_power_info info; Widget toplevel, label; XmFontList font_list; XmString str; XtAppContext app_context; XtIntervalId timer = 0; int main(int argc, char* argv[]) { toplevel = XtVaAppInitialize( &app_context, "XBat", NULL, 0, &argc, argv, NULL, NULL); if ((apmfd = open("/dev/apm", O_RDONLY, 0755)) == -1) err(1, "open"); if ((s = malloc(5*sizeof(char))) == NULL) err(1, "malloc"); XtSetLanguageProc(NULL, NULL, NULL); /* load application resources */ XtGetApplicationResources(toplevel, &res, res_opts, XtNumber(res_opts), NULL, 0); /* create motif label */ label = XtVaCreateManagedWidget("text", xmLabelWidgetClass, toplevel, XmNlabel, "", NULL); alert = 0; update(NULL, &timer); XtRealizeWidget(toplevel); XtAppMainLoop(app_context); } /* update battery status and (re-)add timer */ void update(XtPointer client_data, XtIntervalId *t) { int i; /* remove current timer */ if (t == NULL && timer) { XtRemoveTimeOut(timer); timer = 0; } /* get battery info */ memset(&info, 0, sizeof(info)); if (ioctl(apmfd, APM_IOC_GETPOWER, &info) == -1) { fprintf(stderr, "ioctl APM_IOC_GETPOWER failed\n"); sprintf(s, "?"); goto end; } /* put battery status into label */ sprintf(s, "%d%%", info.battery_life); str = XmStringCreate(s, XmFONTLIST_DEFAULT_TAG); i = 0; #ifdef ALERT if (!alert && info.battery_life < ALERT) { alert = 1; XtSetArg(wargs[i], XmNlabelString, str); i++; if (res.alert_foreground != -1) { XtSetArg(wargs[i], XtNforeground, res.alert_foreground); i++; } if (res.alert_font_list != NULL) { XtSetArg(wargs[i], XmNfontList, res.alert_font_list); i++; } XtSetValues(label, wargs, i); } else if (alert && info.battery_life >= ALERT) { alert = 1; XtSetArg(wargs[i], XmNlabelString, str); i++; if (res.foreground != -1) { XtSetArg(wargs[i], XtNforeground, res.foreground); i++; } if (res.font_list != NULL) { XtSetArg(wargs[i], XmNfontList, res.font_list); i++; } XtSetValues(label, wargs, i); } else #endif XtVaSetValues(label, XmNlabelString, str, NULL); XmStringFree(str); /* add new timer */ end: timer = XtAppAddTimeOut(app_context, INTERVAL * 1000, update, toplevel); }