simple icon tray

Window managers, icon programs, widgets, etc.
Message
Author
User avatar
LazY Puppy
Posts: 1934
Joined: Fri 21 Nov 2014, 18:14
Location: Germany

#121 Post by LazY Puppy »

Here is how to use gettext for tool-tips in C code (learned this from 01micko)

Define:

Code: Select all

#define _(STRING)    gettext(STRING)
Function:

Code: Select all

gtk_status_icon_set_tooltip(tray_icon, _("Refresh the Desktop"));
RSH

"you only wanted to work your Puppies in German", "you are a separatist in that you want Germany to secede from Europe" (musher0) :lol:

No, but I gave my old drum kit away for free to a music store collecting instruments for refugees! :wink:

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

Re: sdesk Ubuntu

#122 Post by technosaurus »

torios wrote:What is this licensed and who do I license it to?
right now (place holder info)
GPL3
Not only no, but hell no! All of my code here is released to the Public Domain (or equivalent CC0 or WTFPL or 0 clause BSD license)... with no warrantees of course. Feel free to relicense it however you want, but I would appreciate avoiding the GPL3+ if you can so that it may be used in low cost ROM based systems (the GPL3 "tivoization clause" prevents this legitimate use).
The latest version (sdesk) is all my original code and is basically just SIT with the addition of being able to set the background.
If you go through this thread, I have provided the basis for various example applets. Its not really hard considering about half of tray applets are just a static icon with some click actions like glipper and wpa_gui or a few that rarely change: volume control, battery, sven
I don't know C, but only C++ so maybe now is a good time to learn C as well so I can make even lighter programs.
Thanks so much!!
Aside from memory management, casting and pointers, C is much easier. Usually the C compiler tells you almost exactly what/where you screwed up, whereas a C++ compile just says you F'd up somewhere. I put C++ and perl in a category I call "write-only languages"... it is much easier to read and follow other people's C code.

Edit:

Code: Select all

<svg height="48" width="48" viewBox="0 0 100 100">
  <circle cx="0" cy="100" r="100" stroke="black" stroke-width="2" fill="blue" fill-opacity="0.3" />
  <circle cx="0" cy="100" r="75" stroke="black" stroke-width="3" fill="blue" fill-opacity="0.3" />
  <circle cx="0" cy="100" r="50" stroke="black" stroke-width="4" fill="blue" fill-opacity="0.3" />
  <circle cx="0" cy="100" r="25" stroke="black" stroke-width="5" fill="blue" fill-opacity="0.3" />
  <path d="M97,0L70,27L75,10L78,14,93,0" fill="blue" stroke="black" stroke-width="1" />
  <path d="M73,28L99,2L95,20L91,15,75,30" fill="blue" stroke="black" stroke-width="1" />
</svg> 
this svg image can be easily adapted to replace wifi applets by using /proc/net/dev for receive and transmit arrows (the path elements) and /proc/net/wireless to show the signal level (the circle elements)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

license

#123 Post by torios »

Hi technosaurus,
would MIT be appropriate, then? Basically I want you to simply choose whatever license you want and tell me :)
I used GPL3 because it is a standard GNU license... don't be offended :)
I license a lot of stuff as MIT since it seems to be very free and permissive.

We are so fortunate to have legal protections for freedom of code :)

I have been parsing the thread lately. So I will probably go over this a few times to get the full gist of everything, but suffice it to say, I am very excited about this program. I think this will be a huge help in making a lightweight version of Ubuntu (which is not known for being lightweight). I am confident that this will allow us to make a plethora of 'applets' available for the tray. Plus SVGs are amazing. Thanks for your work!

I will crack open the ' C a reference Manual ' on my shelf sometime soon

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#124 Post by technosaurus »

MIT is fine.

Here is some rather rudimentary low level C that avoids using printf, scanf and even malloc so the static binary is under 8kb.
Basically it monitors /proc/acpi/battery and generates an svg and tooltip text.

Code: Select all

/*
 * proc2imgd.c
 * 
 * Copyright 2014 Brad Conroy - released to public domain
 * 
 */
#include <fcntl.h> //open
#include <unistd.h> //read,write
#include <string.h> //strstr, strlen
#include <stdlib.h> //getenv
#include <sys/stat.h> //mkdir

#define strcpyALL(buf, l, ...) do{ \
	char *bp=(char*)(buf); \
	const char *s, *a[] = { __VA_ARGS__,NULL}, **ss=a; \
	while((s=*ss++)) \
		while((*s)&&((--l) >0)) \
			*bp++=*s++; \
	*bp=0; \
}while(0)

static inline int ispad(int X){return (X)==' '||(unsigned)(X)-'\t'<5;}
#define isnum(X)	((unsigned)(X)-'0' < 10)

int stod(const char *s){ //like atoi but no negatives and only for small numbers
	int r=0;
	while (ispad(*s++));
	while (isnum(*s)) r = 10*r + (*s++ - '0');
	return r;
}


static void dtos(int d, char *buf){ //like itoa, but you pass the buffer
	int p=0;
	if (0>d) {
		buf[p++]='-';
		d=-d;
	}
	if (0==d){
		buf[p++]='0';
		buf[p]=0;
		return;
	}
	int i=1000000000;
	while (i > d) i/=10;
	while (0<i){
		buf[p++]=('0'+(d/i));
		if (i<=d) d=d%i;
		i/=10;
	}
	buf[p]=0;
	return;
}



//GLOBALs

static char //default colors TODO read from config file
	*ln_c="#000", //lines, outlines, strokes, etc...
	*fg_c="#AAA", //foreground items ... usually the actual image
	*bg_c="#444", //background color ... todo match with theme
	*txt_c="#FFF", //use a text color that will work with both the bg and fg
	*chg_c="#0F0", //usually green indicates a preferred status
	*dchg_c="#F00", //usually red denotes less preferred status
	*width="22px", //set for standard tray size
	*height="22px";

static const char *HOME,
	hdr[]="<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" \tviewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" ",
	ftr[]="</svg>\n",
	w[]=" width=\"",
	h[]=" height=\"",
	x[]=" x=\"",
	y[]=" y=\"",
	q[]="\" ",
	tagend[]=">\n",
	tagclose[]="/>\n",
	rect[]="\t<rect ",
	fill[]=" fill=\"",
	txt[]="\t<text ",
	center[]=" text-anchor=\"middle\"",
	rotate[]=" transform=\"rotate(90 50,50)\"",
	fontsz[]=" font-size=\"",
	txtend[]="</text>\n";	

#if 0 //TODO
void do_wifi(){
const char upload[]="M71,29L99,2L99,27L92,18,75,34",
	download[] = "M98,0L70,27L70,5L77,12,90,0",
	  updown[] = "<path d=\"%s\" fill=\"%s\" stroke=\"%s\"/>\n",
	 sigqual[] = "<circle cx=\"0\" cy=\"100\" r=\"%d\" stroke=\"%s\" stroke-width=\"%d\" fill=\"%s\" fill-opacity=\"0.5\" />\n";

	static int lastrcv=0, lastxmt=0;
	int rcv,xmt,quality;

	FILE *wireless = fopen("/proc/net/wireless", "r");
	char dev[8], status[8], link[8], level[8], noise[8];
	fgets(dummy, 99, wireless);
	fgets(dummy, 99, wireless);
	while (fscanf(fp, "%s %s %s %s %s %s\n", ip, hw, flags, mac, mask, dev) != EOF)
		if (!strcmp(argv[1],ip))
			printf("%s\n",dev);
	return 0;
	
}
#endif

void do_bat(char *batt){
	const char BAT[]="/proc/acpi/battery/BAT";
	char buf[4096]={0}, *bp=(char *)buf, fname[32], dy[8], ht[8], ftsz[8],
		text[]="BAT0";
	static int dcap=0, rcap=-1, percent=-1;
	int i, fd, len=sizeof(buf), chg=0, cap=0;
	if (!isnum(*batt)) *batt='0';
	else text[3] = *batt;
	i=sizeof(fname);
	strcpyALL(fname, i, BAT, batt, "/info");
	if (( fd = open(fname,O_RDONLY))<0) return;
	len = read(fd,buf,len);
	close(fd);
	if (len < 0) return;
	buf[len]=0; //for strstr
	if (!dcap){ //only do once
		bp = strstr(buf,"design capacity:");
		if (!bp) return;
		dcap = stod(&bp[25]);
	}

	if ((bp = strstr(buf,"last ful"))) cap = stod(&bp[25]);
	else cap = dcap;
	i=sizeof(fname);
	strcpyALL(fname,i,BAT,(batt)?batt:"0","/state");
	if (( fd = open(fname,O_RDONLY))<0) return;
	i = read(fd,&(buf[len]),sizeof(buf)-len);
	close(fd);
	if (i < 0) return;
	else buf[(len+=i)]=0;

	if ((bp = strstr(buf,"remain")) && (i = stod(&bp[25])) == rcap) return;
	else rcap = i;
	if ((bp = strstr(buf,"charging st"))) chg=bp[25]-'c';
	i=sizeof(fname);
	strcpyALL(fname,i,HOME,"/.sit/b", batt, ".tt");
	if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC))<0) return;
	len=write(fd,buf,len);
	close(fd);
	i=(rcap>cap)?(100*rcap)/cap:(100*rcap)/dcap;
	if (i==percent) return;
	else percent = i;
	i=sizeof(fname);
	strcpyALL(fname,i,HOME,"/.sit/b", batt, ".svg");
	if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC))<0) return;
	dtos(100-percent,dy);
	dtos(percent,ht);
	dtos(100/(strlen(text)-1),ftsz);
	len=sizeof(buf);
	strcpyALL(buf, len, hdr, w, width, q, h, height, q, tagend,
		rect, x, "20%\"", w, "60%\"", h, "100%\"", fill, bg_c, q, tagclose,
		rect, x, "20%\"", w, "60%\"", y, dy, q, h, ht, q, fill, (chg)?dchg_c:chg_c, q, tagclose,
		//txt, x, "50\"", y, "50\"", fill, txt_c, q, fontsz, ftsz, q, center, rotate, tagend,	"\t\t", text, "\n", txtend,
		ftr
	);
	write(fd,buf,sizeof(buf)-len);
}

int main(int argc, char **argv){
	char buf[64];
	int len=sizeof(buf);
	HOME=getenv("HOME");
	strcpyALL(buf,len,HOME,"/.sit");
	mkdir(buf,0644);
	while(!sleep(1)){
		do_bat("0");
	}
	return 0;
}

Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#125 Post by torios »

https://launchpad.net/sdesk

Here is the Launchpad page.

I licensed it Public Domain, because I finally found that licensing on the launchpad page.... I did that because you originally indicated that...
I also made an SVG version of your logo, so let me know if you want it.
I did that so I could scale it correctly for the Launchpad logos... it is very picky about sizes, and I needed to make sure it looked clean. :)[/url]

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#126 Post by torios »

I am having trouble determining how to build that program using cmake...
I tried putting it in with the other program and building it with the previous flags, this however did not work.
I also tried removing -Os as this worked from geany once I removed that flag...
I am using pbuilder since I am debianizing this
here are the errors

Code: Select all

make[3]: Entering directory `/tmp/buildd/sdesk-plugins-1.0.22/obj-x86_64-linux-gnu'
/usr/bin/cmake -E cmake_progress_report /tmp/buildd/sdesk-plugins-1.0.22/obj-x86_64-linux-gnu/CMakeFiles 1
[100%] Building C object CMakeFiles/proc2imgd.dir/plugins/proc2imgd.c.o
/usr/bin/gcc   -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security  -O3 -DNDEBUG   -o CMakeFiles/proc2imgd.dir/plugins/proc2imgd.c.o   -c /tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c
/tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c: In function 'do_bat':
/tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c:164:9: warning: ignoring return value of 'write', declared with attribute warn_unused_result [-Wunused-result]
In file included from /usr/include/fcntl.h:252:0,
                 from /tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c:7:
In function 'open',
    inlined from 'do_bat.constprop.0' at /tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c:145:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
In function 'open',
    inlined from 'do_bat.constprop.0' at /tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c:153:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
In function 'open',
    inlined from 'do_bat' at /tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c:145:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
In function 'open',
    inlined from 'do_bat' at /tmp/buildd/sdesk-plugins-1.0.22/plugins/proc2imgd.c:153:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
make[3]: *** [CMakeFiles/proc2imgd.dir/plugins/proc2imgd.c.o] Error 1
make[3]: Leaving directory `/tmp/buildd/sdesk-plugins-1.0.22/obj-x86_64-linux-gnu'
make[2]: *** [CMakeFiles/proc2imgd.dir/all] Error 2
make[2]: Leaving directory `/tmp/buildd/sdesk-plugins-1.0.22/obj-x86_64-linux-gnu'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/tmp/buildd/sdesk-plugins-1.0.22/obj-x86_64-linux-gnu'
dh_auto_build: make -j1 returned exit code 2
make: *** [build] Error 2
dpkg-buildpackage: error: debian/rules build gave error exit status 2
E: Failed autobuilding of package
I am packaging it as sdesk plugins, where I will heap all the plugins together so they can be easily installed.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#127 Post by technosaurus »

torios wrote:I did that so I could scale it correctly for the Launchpad logos... it is very picky about sizes, and I needed to make sure it looked clean. :)
That's funny, Launchpad has got to be the most unclean interface ever developed ... almost as bizarre as Bazaar.

I had to drop plans for the application part of sdesk because the gtk devs won't add 10 lines of code for passing a simple string with gtkbuilder UIs. As it stands you have to have a C function for every single thing passed or do a bunch of hacks to add a special hidden label. Just another reason why gtk sucks
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#128 Post by technosaurus »

torios wrote:I am having trouble determining how to build that program using cmake...
I tried putting it in with the other program and building it with the previous flags, this however did not work.
I also tried removing -Os as this worked from geany once I removed that flag...
I am using pbuilder since I am debianizing this
here are the errors
...
I am packaging it as sdesk plugins, where I will heap all the plugins together so they can be easily installed.
If you are talking about https://github.com/technosaurus/sdesk That was just an initial idea I was putting down from memory of the gtk API that I wrote using the touchscreen of my smartphone on the github web interface without ever doing an interim compiles. The tarball posted in this thread is the version that is based on the reality that redhat doesn't give a shit if gtk works for anything but their own cross platform applications. But please let me know if you or anyone else is successful in convincing them that the gtkbuilder UIs should be able to handle simple strings instead of every single thing needing to be an object. Not that it matters though as of the most recent gtk3 release, the gtkstatusicon (the core of SIT and the tray part of sdesk) is deprecated with no replacement.
What we need is an actual community fork of gtk2 so we can let gtk3 rot.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#129 Post by torios »

Haha... no..
I meant the proc2imgd file. I figured out how to build the sdesk program. I have packaged it and tested it... it is pretty sweet! I am making a man page for it, and I will test it out more. Though... there are some things that I will have to modify a little to work as a Debian package...

I also need to read up on 'alltray' and see how this works... I am quite interested in the possibilities of sdesk.

I used the code from this thread.... I just used the image from the github page

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#130 Post by technosaurus »

Here is the updated version: (compile with gcc -Os -o proc2imgd proc2imgd.c -s)

Code: Select all

/*
 * proc2imgd.c
 * 
 * Copyright 2014 Brad Conroy - released to public domain
 * 
 */
#include <fcntl.h> //open
#include <unistd.h> //read,write
#include <string.h> //strstr, strlen
#include <stdlib.h> //getenv
#include <sys/stat.h> //mkdir
#include <sys/statfs.h> //for statfs
#include <stdint.h> //for *int*_t
#include <libgen.h> //basename

#define strcpyALL(buf, l, ...) do{ \
	char *bp=(char*)(buf); \
	const char *s, *a[] = { __VA_ARGS__,NULL}, **ss=a; \
	while((s=*ss++)) \
		while((*s)&&((--l) >0)) \
			*bp++=*s++; \
	*bp=0; \
}while(0)

static inline int ispad(int X){return (X)==' '||(unsigned)(X)-'\t'<5;}
#define isnum(X)	((unsigned)(X)-'0' < 10)

int stod(const char *s){ //like atoi but no negatives and only for small numbers
	int r=0;
	while (ispad(*s))s++;
	while (isnum(*s)) r = 10*r + (*s++ - '0');
	return r;
}


static void dtos(int64_t d, char *buf){ //like itoa, but you pass the buffer
	int p=0;
	if (0>d) {
		buf[p++]='-';
		d=-d;
	}
	if (0==d){
		buf[p++]='0';
		buf[p]=0;
		return;
	}
	int64_t i=1000000000000000000;
	while (i > d) i/=10;
	while (0<i){
		buf[p++]=('0'+(d/i));
		if (i<=d) d=d%i;
		i/=10;
	}
	buf[p]=0;
	return;
}


//GLOBALs

static char //default colors TODO read from config file
	*ln_c="#000", //lines, outlines, strokes, etc...
	*fg_c="#AAA", //foreground items ... usually the actual image
	*bg_c="#444", //background color ... todo match with theme
	*txt_c="#FFF", //use a text color that will work with both the bg and fg
	*chg_c="#0F0", //usually green indicates a preferred status
	*dchg_c="#F00", //usually red denotes less preferred status
	*width="22px", //set for standard tray size
	*height="22px",
	buf[4096]={0},
	HOME[64];

static const char
	hdr[]="<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" \tviewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" ",
	ftr[]="</svg>\n",
	w[]=" width=\"",
	h[]=" height=\"",
	x[]=" x=\"",
	y[]=" y=\"",
	q[]="\" ",
	tagend[]=">\n",
	tagclose[]="/>\n",
	rect[]="\t<rect ",
	fill[]=" fill=\"",
	txt[]="\t<text ",
	center[]=" text-anchor=\"middle\"",
	rotate[]=" transform=\"rotate(90 50,50)\"",
	fontsz[]=" font-size=\"",
	txtend[]="</text>\n";	

#if 0
static inline void do_wifi(const char *wlan){
const char upload[]="M71,29L99,2L99,27L92,18,75,34",
	download[] = "M98,0L70,27L70,5L77,12,90,0",
	  updown[] = "<path d=\"%s\" fill=\"%s\" stroke=\"%s\"/>\n",
	 sigqual[] = "<circle cx=\"0\" cy=\"100\" r=\"%d\" stroke=\"%s\" stroke-width=\"%d\" fill=\"%s\" fill-opacity=\"0.5\" />\n";

	static int lastrcv=0, lastxmt=0;
	int rcv,xmt,quality;

	FILE *wireless = fopen("/proc/net/wireless", "r");
	char dev[8], status[8], link[8], level[8], noise[8];
	fgets(dummy, 99, wireless);
	fgets(dummy, 99, wireless);
	while (fscanf(fp, "%s %s %s %s %s %s\n", ip, hw, flags, mac, mask, dev) != EOF)
		if (!strcmp(argv[1],ip))
			printf("%s\n",dev);
	return 0;
	
}
#endif

static inline void do_fs(char *fname, int *lastsz){
	char extensions[]=" kMGTE", sz[8], *bp, outfile[64];
	size_t ext=0, len=sizeof(outfile);
	int fd;
	if (!fname) return;
	struct statfs st;
	if ((statfs(fname, &st))<0) return;
	uint64_t left = st.f_bfree * st.f_bsize;
	while(left>1024){
		left>>=10; //same as /=1024
		++ext;
	}
	if ((int)left == *lastsz) return; //try not to trigger unnecessary redraw
	else *lastsz=left;
	dtos(left,sz);
	bp=sz+strlen(sz);
	if (ext) *bp++=extensions[ext];
	*bp++='b';*bp++='\n';*bp++=0;
	strcpyALL(outfile, len,HOME,(const char *)basename(fname),".svg");
	if (( fd = open(outfile,O_WRONLY|O_CREAT|O_TRUNC))<0) return;
	len=sizeof(buf);
	strcpyALL(buf, len,
		hdr, w, width, q, h, height, q, tagend,
			rect, w, "100%\"", h, "100%\"", fill, bg_c, q, tagclose,
			txt, x, "50\"", y, "50\"", fill, txt_c, q, fontsz, "30", q, center, tagend,	"\t\t",
				sz, "\n",
			txtend,
		ftr
	);	
	write(fd,buf,strlen(buf));
	close(fd);
	return;
}


static inline void do_bat(char *batt, int *percent){
	const char BAT[]="/proc/acpi/battery/";
	char *bp=(char *)buf, fname[32], dy[24], ht[24];
	int i, fd, len=sizeof(buf), chg=0, cap=-1, dcap=-1, rcap=-1;

/* We _could_ just do this block once, but last full capacity may change */
	i=sizeof(fname);
	strcpyALL(fname, i, BAT, batt, "/info");
	if (( fd = open(fname,O_RDONLY))<0) return;
	len = read(fd,buf,len);
	close(fd);
	if (len < 0) return;
	buf[len]=0; //for strstr
	if (!(bp = strstr(buf,"design capacity:"))) return;
	else dcap = stod(&bp[25]);
	if ((bp = strstr(buf,"last ful"))) cap = stod(&bp[25]);
	else cap = dcap;

	i=sizeof(fname);
	strcpyALL(fname,i,BAT,batt,"/state");
	if (( fd = open(fname,O_RDONLY))<0) return;
	i = read(fd,&(buf[len]),sizeof(buf)-len);
	close(fd);
	if (i < 0) return;
	else buf[(len+=i)]=0;

	if ((bp = strstr(buf,"remain")) && (i = stod(&bp[25])) == rcap) return;
	else rcap = i;
	if ((bp = strstr(buf,"charging st"))) chg=bp[25]-'c';
	i=sizeof(fname);
	i=(100*rcap)/((rcap>cap)?dcap:cap);
	if (*percent==((chg)?-i:i)) return; //try not to trigger unnecessary redraw
	else *percent = i;
	strcpyALL(fname,i,HOME, batt, ".tt");
	if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC))<0) return;
	len=write(fd,buf,len);
	close(fd);
	i=sizeof(fname);
	strcpyALL(fname,i,HOME, batt, ".svg");
	if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC))<0) return;
	dtos(100-*percent,dy);
	dtos(*percent,ht);
	if (chg) *percent=-*percent;
	len=sizeof(buf);
	strcpyALL(buf, len, hdr, w, width, q, h, height, q, tagend,
		rect, x, "20%\"", w, "60%\"", h, "100%\"", fill, bg_c, q, tagclose,
		rect, x, "20%\"", w, "60%\"", y, dy, q, h, ht, q, fill, (chg)?dchg_c:chg_c, q, tagclose,
		txt, x, "50\"", y, "50\"", fill, txt_c, q, fontsz, "30", q, center, rotate, tagend,	"\t\t", batt, "\n", txtend,
		ftr
	);
	write(fd,buf,sizeof(buf)-len);
}

int main(int argc, char **argv){
	int len=sizeof(HOME),
		state[argc/2];
	strcpyALL(HOME,len,getenv("HOME"),"/.sit/");
	mkdir(HOME,0422);
	do{
		do_fs("/mnt/save",&state[0]);
		do_bat("BAT0",&state[1]);
		//do_wifi("wlan0",&state[2]); //todo
	}while(!sleep(1));
	return 0;
}

Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#131 Post by torios »

Hi again,
I am still getting the same type of error.
I have never used GTK in my programs so I will have to look into it, I am a bit wary of it since GTK has been in a blender for the past few years. I usually write things using FLTK because it is very fast and light. And FLUID makes it very simple to make interfaces look the way you want them to.

Anyhow here is the error... it keeps looking for 3 args.

Code: Select all

/usr/bin/gcc   -Os -o -O3 -DNDEBUG   -o CMakeFiles/proc2imgd.dir/plugins/proc2imgd.c.o   -c /tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c
/tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c: In function 'do_fs':
/tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c:142:9: warning: ignoring return value of 'write', declared with attribute warn_unused_result [-Wunused-result]
/tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c: In function 'do_bat':
/tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c:198:9: warning: ignoring return value of 'write', declared with attribute warn_unused_result [-Wunused-result]
In file included from /usr/include/fcntl.h:252:0,
                 from /tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c:7:
In function 'open',
    inlined from 'do_fs.constprop.1' at /tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c:132:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
In function 'open',
    inlined from 'do_bat.constprop.0' at /tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c:182:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
In function 'open',
    inlined from 'do_bat.constprop.0' at /tmp/buildd/sdesk-plugins-1.0.23/plugins/proc2imgd.c:187:7:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:51:24: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments
I think pbuilder automatically adds in -O3 -DNDEBUG
as I have

Code: Select all

set(CMAKE_C_FLAGS "-Os -o")
in my CMakeLists.txt
Thanks for helping me with this!

On a side note I made a nice locate dialog using gxmessage and zenity. It is very neat to have a search tool available right in my panel.
I am looking forward to adding more features soon (like this monitoring program you have made... if it will only compile in pbuilder)

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#132 Post by technosaurus »

Stop using cmake and just compile with the command posted at the top of my last post. if you are going to use cmake the "-o" is not a flag, it denotes the next argument is the name of the output binary.
To make a standalone binary, just:
gcc -Os -o proc2imgd proc2imgd.c -s
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#133 Post by torios »

Hi, sorry I have been a bit under the weather.
-o is definitely not a C flag... please ignore that...
I want to use cmake because I want to package this for debian.

open can take 3 arguments, so I think I will just add the third argument (mode) and see what happens... that seems to be the main complaint from the compiler/pbuilder.

I don't know that cmake is as big of a problem here as the pbuilder building system... they use extremely strict rules to govern what code will work, and what code will not build. When I get some time I will test this out and let you know...

There may be something else I could do... what about using a flag to denote what standard of C is being used... I know there is such a thing in C++ i.e.
-std=c++0x
I have had to use this in order to get certain programs to compile correctly for similar issues.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#134 Post by technosaurus »

oops, the ones with O_CREAT should have a mode afterward.... just add ,0644

my static build with musl just uses defaults and it is smaller than the shared glibc build (mostly because I don't use any printf or scanf functions)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#135 Post by torios »

Thanks technosaurus! I really appreciate this. Should I use this format:
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
to be in line with the previous argument?
Or is the numerical permission better?

I know this is kind of a minor stylistic question, but this is your code so I like to always ask people before I modify their code, especially since I have contact with you directly. I feel like this promotes the openness we appreciate about libre software.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#136 Post by technosaurus »

honestly, _I_ think 0644 is easier to read, since the octal numbers represent USER,GROUP,ALL and for each one, the binary bits represent READ, WRITE, EXEC permissions... so 0644 is user read/write and world read permission. Most Unix/Linux guys that write C would probably be the same.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#137 Post by torios »

Hi,
I was also looking through your code to try to get my mind around the genius of what you have done. There are a few things I don't fully understand based on the variable names. I'd like to ask you about them, but I feel like it would clutter the thread can I contact you outside of the forum to ask about this? If not I will continue through the code and ask here when I absolutely am stumped. Thanks for working with me on this, I really appreciate all your tireless efforts! I think your programs have incredible value and will bring some of the Puppy goodness I am so fond of to Ubuntu.

Part of the reason why I want to understand this is the move to
/sys/class/power_supply/BAT0
and the different files used. I want to be able to handle both (eventually).

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#138 Post by technosaurus »

May as well ask it here. I know some other people wanted some C examples. Hopefully I can translate my naming system back to human. I've been meaning to learn doxygen style inline comments anyhow.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
torios
Posts: 28
Joined: Fri 05 Dec 2014, 23:21

#139 Post by torios »

Well, I'll just paste the code here to show you what I did to make things easier for me to figure out things. I am still trying to figure it all out.
Basically I haven't figured out the ones that don't have long names...
there are a few things I didn't translate into a longer name yet that I already know... but certain things like:
bp
fd
i
chg (is this charged?)
d
p
s
ss
r
sz... I understand this is the size, but it is not immediately clear which size.

Just some minor things. I tried to name things here in the normal c naming convention...

Code: Select all

/*
 * proc2imgd.c
 *
 * Copyright 2014 Brad Conroy - released to public domain
 *
 */
#include <fcntl.h> //open
#include <unistd.h> //read,write
#include <string.h> //strstr, strlen
#include <stdlib.h> //getenv
#include <sys/stat.h> //mkdir
#include <sys/statfs.h> //for statfs
#include <stdint.h> //for *int*_t
#include <libgen.h> //basename

#define strcpyALL(buf, l, ...) do{ \
   char *bp=(char*)(buf); \
   const char *s, *a[] = { __VA_ARGS__,NULL}, **ss=a; \
   while((s=*ss++)) \
      while((*s)&&((--l) >0)) \
         *bp++=*s++; \
   *bp=0; \
}while(0)

static inline int ispad(int X){return (X)==' '||(unsigned)(X)-'\t'<5;}
#define isnum(X)   ((unsigned)(X)-'0' < 10)

int stod(const char *s){ //like atoi but no negatives and only for small numbers
   int r=0;
   while (ispad(*s))s++;
   while (isnum(*s)) r = 10*r + (*s++ - '0');
   return r;
}


static void dtos(int64_t d, char *buf){ //like itoa, but you pass the buffer
   int p=0;
   if (0>d) {
      buf[p++]='-';
      d=-d;
   }
   if (0==d){
      buf[p++]='0';
      buf[p]=0;
      return;
   }
   int64_t i=1000000000000000000;
   while (i > d) i/=10;
   while (0<i){
      buf[p++]=('0'+(d/i));
      if (i<=d) d=d%i;
      i/=10;
   }
   buf[p]=0;
   return;
}


//GLOBALs

static char //default colors TODO read from config file
   *line_color="#000", //lines, outlines, strokes, etc...
   *foreground_color="#AAA", //foreground items ... usually the actual image
   *background_color="#444", //background color ... todo match with theme
   *text_color="#FFF", //use a text color that will work with both the bg and fg
   *charge_color="#0F0", //usually green indicates a preferred status
   *discharge_color="#F00", //usually red denotes less preferred status
   *icon_width="22px", //set for standard tray size
   *icon_height="22px",
   buf[4096]={0},
   HOME[64];

static const char
   svg_header[]="<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" \tviewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" ",
   svg_footer[]="</svg>\n",
   svg_width[]=" width=\"",
   svg_height[]=" height=\"",
   svg_x[]=" x=\"",
   svg_y[]=" y=\"",
   svg_quote[]="\" ",
   svg_tag_end[]=">\n",
   svg_tag_close[]="/>\n",
   svg_rect[]="\t<rect ",
   svg_fill[]=" fill=\"",
   svg_text[]="\t<text ",
   center[]=" text-anchor=\"middle\"",
   rotate[]=" transform=\"rotate(90 50,50)\"",
   svg_font_size[]=" font-size=\"",
   svg_text_close[]="</text>\n";   

#if 0
static inline void do_wifi(const char *wlan){
const char upload[]="M71,29L99,2L99,27L92,18,75,34",
   download[] = "M98,0L70,27L70,5L77,12,90,0",
     updown[] = "<path d=\"%s\" fill=\"%s\" stroke=\"%s\"/>\n",
    sigqual[] = "<circle cx=\"0\" cy=\"100\" r=\"%d\" stroke=\"%s\" stroke-width=\"%d\" fill=\"%s\" fill-opacity=\"0.5\" />\n";

   static int lastrcv=0, lastxmt=0;
   int rcv,xmt,quality;

   FILE *wireless = fopen("/proc/net/wireless", "r");
   char dev[8], status[8], link[8], level[8], noise[8];
   fgets(dummy, 99, wireless);
   fgets(dummy, 99, wireless);
   while (fscanf(fp, "%s %s %s %s %s %s\n", ip, hw, flags, mac, mask, dev) != EOF)
      if (!strcmp(argv[1],ip))
         printf("%s\n",dev);
   return 0;
   
}
#endif

static inline void do_fs(char *fname, int *lastsz){
   char extensions[]=" kMGTE", sz[8], *bp, outfile[64];
   size_t ext=0, len=sizeof(outfile);
   int fd;
   if (!fname) return;
   struct statfs st;
   if ((statfs(fname, &st))<0) return;
   uint64_t left = st.f_bfree * st.f_bsize;
   while(left>1024){
      left>>=10; //same as /=1024
      ++ext;
   }
   if ((int)left == *lastsz) return; //try not to trigger unnecessary redraw
   else *lastsz=left;
   dtos(left,sz);
   bp=sz+strlen(sz);
   if (ext) *bp++=extensions[ext];
   *bp++='b';*bp++='\n';*bp++=0;
   strcpyALL(outfile, len,HOME,(const char *)basename(fname),".svg");
   if (( fd = open(outfile,O_WRONLY|O_CREAT|O_TRUNC,0644 ))<0) return;
   len=sizeof(buf);

   strcpyALL(buf, len,
	svg_header,
	svg_width,
	icon_width,
	svg_quote, svg_height,icon_height, svg_quote, svg_tag_end,

	svg_rect, svg_width, "100%\"", svg_height, "100%\"",
	svg_fill, background_color, svg_quote,
	svg_tag_close,

	svg_text, svg_x, "50\"", svg_y, "50\"",
	svg_fill, text_color, svg_quote, svg_font_size, "30",
	svg_quote, center, svg_tag_end,   "\t\t",
	sz, "\n",
	svg_text_close,
	svg_footer
   );   
   write(fd,buf,strlen(buf));
   close(fd);
   return;
}


static inline void do_bat(char *batt, int *percent){
   const char BAT[]="/proc/acpi/battery/";
   char *bp=(char *)buf, fname[32], dy[24], ht[24];
   int i, fd, len=sizeof(buf), chg=0, full_capacity=-1, discharging_capacity=-1, remaining_capacity=-1;

/* We _could_ just do this block once, but last full capacity may change */
   i=sizeof(fname);
   strcpyALL(fname, i, BAT, batt, "/info");
   if (( fd = open(fname,O_RDONLY,0644 ))<0) return;
   len = read(fd,buf,len);
   close(fd);
   if (len < 0) return;
   buf[len]=0; //for strstr
   if (!(bp = strstr(buf,"design capacity:"))) return;
   else discharging_capacity = stod(&bp[25]);
   if ((bp = strstr(buf,"last ful"))) full_capacity = stod(&bp[25]);
   else full_capacity = discharging_capacity;

   i=sizeof(fname);
   strcpyALL(fname,i,BAT,batt,"/state");
   if (( fd = open(fname,O_RDONLY,0644 ))<0) return;
   i = read(fd,&(buf[len]),sizeof(buf)-len);
   close(fd);
   if (i < 0) return;
   else buf[(len+=i)]=0;

   if ((bp = strstr(buf,"remain")) && (i = stod(&bp[25])) == remaining_capacity) return;
   else remaining_capacity = i;
   if ((bp = strstr(buf,"charging st"))) chg=bp[25]-'c';
   i=sizeof(fname);
   i=(100*remaining_capacity)/((remaining_capacity>full_capacity)?discharging_capacity:full_capacity);
   if (*percent==((chg)?-i:i)) return; //try not to trigger unnecessary redraw
   else *percent = i;
   strcpyALL(fname,i,HOME, batt, ".tt");
   if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644 ))<0) return;
   len=write(fd,buf,len);
   close(fd);
   i=sizeof(fname);
   strcpyALL(fname,i,HOME, batt, ".svg");
   if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644))<0) return;
   dtos(100-*percent,dy);
   dtos(*percent,ht);
   if (chg) *percent=-*percent;
   len=sizeof(buf);

   strcpyALL(buf, len,
	svg_header, svg_width, icon_width, svg_quote,
	svg_height, icon_height, svg_quote, svg_tag_end,

	svg_rect, svg_x, "20%\"",
	svg_width, "60%\"",
	svg_height, "100%\"",
	svg_fill, background_color, svg_quote, svg_tag_close,

	svg_rect, svg_x, "20%\"",
	svg_width, "60%\"",
	svg_y, dy, svg_quote,
	svg_height, ht, svg_quote,
	svg_fill, (chg)?discharge_color:charge_color, svg_quote, svg_tag_close,

	svg_text, svg_x, "50\"",
	svg_y, "50\"",
	svg_fill, text_color, svg_quote,
	svg_font_size, "30", svg_quote,
	center, rotate, svg_tag_end,   "\t\t", batt, "\n",
	svg_text_close,
	svg_footer
   );
   write(fd,buf,sizeof(buf)-len);
}

int main(int argc, char **argv){
   int len=sizeof(HOME),
      state[argc/2];
   strcpyALL(HOME,len,getenv("HOME"),"/.sit/");
   mkdir(HOME,0422);
   do{
      do_fs("/mnt/save",&state[0]);
      do_bat("BAT0",&state[1]);
      //do_wifi("wlan0",&state[2]); //todo
   }while(!sleep(1));
   return 0;
} 

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#140 Post by technosaurus »

torios wrote:

Code: Select all

bp ... things that end in p are typically pointers, in this case to buf
fd ... file descriptor (typically anything that ends with fd)
i ... just an integer for temporary use
chg (is this charged?) ... actually I should have renamed it dchg
      (it is a 1 when discharging or a 0 when charged or charging)
       I used the fact that their ascii values are sequential
d    I didn't want a full itoa function so used the printf format specifiers and called it dtos (int to string)
p    used inside [] for position (I wrote it before I really understood pointers)
s    string
ss   2d array of strings or pointer to array of strings
r     the return value
sz... follow the loop that fills it (it converts integer to string with b,K,M,G,...)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Post Reply