mirror of
https://github.com/amiwm/amiwm.git
synced 2026-03-24 01:24:15 +00:00
[amiwm] MVP for initial battery stuff
Totally not ready for prod, but at least I'm making progress figuring out how to add extra bits to this thing. * add a second widget to the menu bar, next to the title bar * add a new module command to update the battery information * add a freebsd specific Battery module, not linked into the build right now. * amiwm will print out whenever we get battery information from the module. Right now I'm trying to figure out how to get some kind of periodic background event into the module main loop. Launcher does it using cx_broker(), but I dunno if I can adapt that pattern here.
This commit is contained 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
|
||||
|
||||
69
battery_module.c
Normal file
69
battery_module.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <machine/apm_bios.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
85
libami/mdbattery.c
Normal file
85
libami/mdbattery.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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<sizeof(w)) {
|
||||
if(data) free(data);
|
||||
#ifndef HAVE_ALLOCA
|
||||
free(nai);
|
||||
#endif
|
||||
return None;
|
||||
}
|
||||
memcpy(&w, data, sizeof(w));
|
||||
free(data);
|
||||
#ifndef HAVE_ALLOCA
|
||||
free(nai);
|
||||
#endif
|
||||
return w;
|
||||
}
|
||||
|
||||
Pixmap md_image_to_pixmap(Window w, unsigned long bgcolor, struct Image *i,
|
||||
int width, int height, struct ColorStore *cs)
|
||||
{
|
||||
Display *dpy = md_display();
|
||||
static GC gc = None;
|
||||
Pixmap pm;
|
||||
static int iconcolormask;
|
||||
static unsigned long *iconcolor = NULL;
|
||||
if(gc == None && w != None)
|
||||
gc = XCreateGC(dpy, w, 0, NULL);
|
||||
if(iconcolor == NULL) {
|
||||
char *p;
|
||||
int res = md_command(w, MCMD_GETICONPALETTE, NULL, 0, &p);
|
||||
if(res<0)
|
||||
return None;
|
||||
iconcolor = (unsigned long *)(void *)p;
|
||||
iconcolormask = (res/sizeof(unsigned long))-1;
|
||||
}
|
||||
pm = image_to_pixmap(md_display(), w, gc, bgcolor, iconcolor, iconcolormask,
|
||||
i, width, height, cs);
|
||||
return pm;
|
||||
}
|
||||
|
||||
char *get_current_icondir()
|
||||
{
|
||||
char *p;
|
||||
if(md_command(None, MCMD_GETICONDIR, NULL, 0, &p)>=0 && p)
|
||||
return p;
|
||||
if(p) free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
45
menu.c
45
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);
|
||||
|
||||
21
module.c
21
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);
|
||||
}
|
||||
|
||||
9
module.h
9
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;
|
||||
|
||||
Reference in New Issue
Block a user