Here's some simple C code I wrote to handle setting the
xprop without using xsetroot.  At the moment it just
spawns the same shell scripts I used before, but it may
be useful for those having issues with xsetroot...

If anyone is interested, this is the beginings of a 
libnotify-aware status script :)

Jeremy
// C verison of dwm status script -- no need for xsetroot
// by Jeremy Jay
//
// compile with: gcc -lX11 -s -o dwmstatus dwmstatus.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>

// modify BAT0 here to suit (yes this can be done better, but i'm lazy)
const char *batt_rate_script="sed 's/unknown/1/g' /proc/acpi/battery/BAT0/state |grep rate |tr -d [:alpha:],':',' '";
const char *batt_rem_script="grep remaining /proc/acpi/battery/BAT0/state |tr -d [:alpha:],':',' '";
const char *batt_cap_script="grep full /proc/acpi/battery/BAT0/info |tr -d [:alpha:],':',' '";
const char *batt_stat_script="grep charging /proc/acpi/battery/BAT0/state |cut -b 26-";

// modify wlan0 here to suit
const char *wififunc = "/sbin/iwconfig wlan0 |grep Quality | sed 's/:\\|=/./g' |tr -d [:alpha:],[:space:] |cut -d'.' -f2 |cut -d'/' -f1";

// this is slow to return, but gives a true percent, replace with load if you want
const char *cpufunc = "top -b -d1 -n2 | awk '/^Cpu\\(s\\): / {gsub(\"%us,\",\"\",$2); print $2; }' | tail -n 1";

char text[256];

// runs a shell script and returns the output in text[]
int runScript(const char *script) {
	int pd[2], l=0, r=0, p=0;

	if( pipe(pd) == -1 )
		return 0;

	if( (p=fork())==0 ) {
		close(pd[0]);
		close(2);
		close(0);
		dup2( pd[1], 1 );
		execlp("/bin/sh", "/bin/sh", "-c", script, NULL);
		perror("exec failed");
		exit(1);
	} else if( p==-1 ) {
		return 0;
	}
	close(pd[1]);
	waitpid(p, NULL, 0);
	while( (r=read(pd[0], text+l, 256-l)) > 0 )
		l+=r;
	close(pd[0]);

	text[l] = 0;
	return 1;
}

/////////////////////////////////////
// update with your own status info

void getstatus(char *status) {
	time_t now = time(NULL);
	char datestr[21], bstate[2]={0,0};
	int batt=0, btime=0, cpu=0, wifi=0;

	////////////////////////////////////
	// retrieve all the stats
	////////////////////////////////////

	// battery
	if( runScript(batt_rate_script) ) {
		int rate, rem=0, cap=0;
		
		rate = atoi(text);

		runScript(batt_rem_script);
		rem = atoi(text);

		runScript(batt_cap_script);
		cap = atoi(text);

		runScript(batt_stat_script);
		if( strncmp(text, "charging", 8)==0 ) 
			bstate[0]='+';
		else if( strncmp(text, "discharging", 11)==0 ) 
			bstate[0]='-';
		
		btime=(60*rem) / rate;
		batt=(100*rem) / cap;
		if( batt>100 ) batt=100;
	}

	// wifi
	if( runScript(wififunc) )
		wifi = atoi(text);

	// cpu
	if( runScript(cpufunc) )
		cpu = atoi(text);

	//////////////////////////////////
	// build the string
	//////////////////////////////////
	status[0]=0;

	// dont show cpu unless its high
	if( cpu > 50 ) 
		snprintf(status, 256, "%sc=%d%% | ", status, cpu);

	// dont show wifi unless its weak
	if( wifi < 30 )
		snprintf(status, 256, "%sw=%d%% | ", status, wifi);

	// show battery info only if not full (time rem is handy when not plugged in)
	if( bstate[0]=='-' || batt < 50 ) {
		if( batt <= 15 ) {
			// if you have my colored status patch, this will highlight the battery indicator
			// otherwise put your own popup message/whatever here
			snprintf(status, 256, "%s%cb=%d%%%s [%d:%02d] \x01| ", status, (batt<10?4:3), batt, bstate, btime/60, btime%60);
		} else
			snprintf(status, 256, "%sb=%d%%%s [%d:%02d] | ", status, batt, bstate, btime/60, btime%60);
	}

	// add the date/time to the end
	strftime(status+strlen(status), 256-strlen(status), "%d %b %Y - %I:%M", localtime( &now ) );
}

int main(int argc, char **argv) {
	char stext[256];
	Display *dpy;
	Window root;

	if(!(dpy = XOpenDisplay(0))) {
		fprintf(stderr, "dwmstatus: cannot open display\n");
		return 1;
	}
	root = DefaultRootWindow(dpy);

	while( 1 ) {
		sleep(2);
		getstatus(stext);
		
		XChangeProperty(dpy, root, XA_WM_NAME, XA_STRING,
				8, PropModeReplace, (unsigned char*)stext, strlen(stext));
		XFlush(dpy);
	}

	return 0;
}

Reply via email to