Simple GUI PPP monitor
Some parts of being retired aren't hard to like. I always wanted to learn Motif and the Athena widget set, all that stuff, but there wasn't time when I had to work for a living. I've been playing around with this for a week or so and nobody cares.
This started mainly for practice, because it's not reasonable to expect everyone to like command line stuff, and if I use argv/argc with lots of options even I won't remember them all. I used to write a lot of Borland Delphi stuff when I had to work under Windows, and I haven't seen aything yet that beats Delphi for being able to get something working and out the door in a minimum amount of time. FLTK comes close, but I hate C++ and it doesn't seem to work without it.
So I downloaded the early O'Reily books on Motif and X-Windows (about 70 megs in 9 PDF and DJVU files) and started reading. I found much of what I needed was actually built into OpenBSD already, but I did install the Openmotif port. Most of what I've used is in the Athena widget set (Xaw) that comes in a standard OpenBSD installation set though.
I have to rely on dialup for an internet connection, so I spend hours every day downloading stuff. I run a little LAN, and if I've left some page open on my laptop that's set to refresh itself it can make a big hole in my bandwidth. I can type "show physical" into the window where I dialed up my PPP connection from, but there isn't even command line history, so I have to keep typing it every time I want to check bandwidth.
So I hit on making a hack of xload, which comes standard with xorg, and modifying it to show bandwidth instead. Which reminds me of statements I've made earlier that 90% of the work in writing most GUI programs is just making the GUI work. But it's been a week and finally time to get something on the web about what I've learned. xload uses the Athena widgets, which is why it works without installing Openmotif.
I've got a PDF on the Athena widget set, but there's a lot of stuff on it built into OpenBSD already, just not all in one place and it's sort of buried. If you try "man XtSetArg" and you get something you've probably got what you need, except it is good to have an overview (try man Xaw). There doesn't even seem to be much of a network of "see also" sections between the man pages. There's a lot at http://oreilly.com/openbook/ but not all the books are there. Inside the front covers of some is a list of the complete set and I found most of the rest by Googling for the titles. Volume 6a is in the books section of the OpenBSD ports and I started with that. Some of these books are 1200 pages, over 12 megs.
At the end of the XtSetArg man page there's reference to X Toolkit Intrinsics - C Language Interface and Xlib - C Language X Interface. At the end of man Xaw there's reference to Athena Widget Set - C Language Interface. In the beginning of the Xlib pdf there's mention of another document called X Window System Protocol. There's no guarantee that these links will always work, but Google for the titles if they don't. Since the 2 at xfree86.org come from the "current" directory those are probably good, but the Intrinisics will probably always be for X11R7.5. These aren't meant as tutorials for beginners, but reference documents.
One of the hardest lessons I've learned so far is how to set resources in widgets. See that square dot toward the right side of the screenshot above? It's called a "grip" meaning that you can adjust that line up and down only by dragging that. There's one in xpdf between the table of contents type area at the left side of the page and the main screen also. But how do you turn it off? That took me about 2 days to figure out.
The area at the bottom of the ppp screenshot where the vertical bars are is an Athena StripChart widget, the area at the top where it says "PPP speed" is a label widget, and both are inside a paned widget. I didn't want that grip there and I didn't want that size adjustable. The paned widget has a showGrip attribute/resource that's responsible, which defaults to true.
There's a tool called editres in every OpenBSD installation, linked into the FVWM menu in the Utilities category. I've seen it there for years, but now I finally figured out how to use it. What I'm used to calling attributes are called resources in the Athena/Motif context, so I use the terms interchangeably here.
Start editres and the application you want to modify, then do Commands -> Get Tree, click in the application, then select the object you want to change and do Commands -> Show Resource Box. Click on the attribute and type the new value in the "Enter Resource Value" box at the bottom, then click the "Save and Apply" button. It will prompt for a filename the first time, then append to that later (it's just text). Use the "Popdown Resource Box" button when you're done with that object. Do more if you want.
If you don't know the outer classname, do Tree -> Show Class Names and look at the leftmost/top name. Copy the resources file editres makes to /usr/X11R6/lib/X11/app-defaults/, with a filename that's the outer class name (case sensitive). When you start the application again all the changed attributes should be in place. You can edit this file and restart, but editres knows the right format so emulate the lines it made.
Some things that are hard-coded in the application's source code can't be changed this way. You have to change the values and recompile or change them so they're not hard-coded to be able to use editres on them.
The screenshot of PPP speed at the top of the page is just displaying random numbers fed to the StripChart widget. I've been working for 2 days on getting rid of the grip. I probably won't keep the colors either, I was just playing around in editres.
Well, another day has gone by and I don't have it working. I've been reading O'Reilly's Volume 4: X Toolkit Intrinsics Programming Manual which will probably take me easily a week if I finish it. I have this bad habit, especially with tutorials, of starting to read, then getting sidetracking trying out what I read about and never getting back to the text. Volume 4 happens to start out talking about what I've been trying to figure out anyway.
I found a bunch of neat free widgets at ftp://ftp.x.org/contrib/widgets but of course they're all old and abandoned. I grabbed copies of SciPlot, XEarth, XAbacus and ListTree. ListTree can supposedly do stuff like :
Which looks very useful because I really miss Total Commander. I haven't actually had these working as widgets yet. That's a gif that comes with the widget. Most of these are like 20 years old and trying to get them compiled is a challenge.
And I got the bright idea to use editres on xman just to see what the widget tree in that looks like:
That's a thumbnail to a gif that's 1920x1080 pixels and all of 55 K because it only has 8 colors. My 1920x1080 screen isn't quite big enough though and the tree is cut off on the bottom. And here's editres running on another copy of editres:
The xman widget tree as text looks like this:
Xman xman VendorShellExt shellext Tip tip TopLevelShell topBox VendorShellExt shellext Form form Label topLabel Command helpButton Command quitButton Command manpageButton TransientShell search VendorShellExt shellext Dialog dialog Label label Text value AsciiSink textSink AsciiSrc textSource Command manualPage Command apropos Command cancel TransientShell pleaseStandBy VendorShellExt shellext Label label TransientShell likeToSave VendorShellExt shellext Dialog dialog Label label Command yes Command no TopLevelShell manualBrowser VendorShellExt shellext Paned vertPane Paned horizPane MenuButton options MenuButton sections Label manualTitle Viewport directory Core clip List directory Scrollbar vertical List directory Grip grip ScrollByLine manualPage Grip grip SimpleMenu optionMenu SmeBSB displayDirectory SmeBSB displayManualPage SmeBSB help SmeBSB search SmeBSB showBothScreens SmeBSB removeThisManpage SmeBSB openNewManpage SmeBSB showVersion SmeBSB quit TransientShell search VendorShellExt shellext Dialog dialog Label label Text value AsciiSrc textSource AsciiSink textSink Command manualPage Command apropos Command cancel SimpleMenu sectionMenu SmeBSB section0 SmeBSB section1 SmeBSB section2 SmeBSB section3 SmeBSB section4 SmeBSB section5 SmeBSB section6 SmeBSB section7 SmeBSB section8 TransientShell pleaseStandBy VendorShellExt shellext Label label TransientShell likeToSave VendorShellExt shellext Dialog dialog Label label Command yes Command no
Actually I did get as far as putting in a printf in what seems to be the right place to tap a valid throughput number in /usr/src/usr.sbin/ppp/ppp/throughput.c
It sends a stream of numbers about once a second to the rxvt window where I launched ppp from. Notice the numbers in the right window are close to the "K/s" figure in the wget transfer happening in the left window (bottom line). The file size is wrong on the server or something, which is why the number of remaining bytes is negative. This should have been done about 2 days ago but the file's 125 megs, not 65 like I thought.
Here's a patch for this change, both as a gzip and a copy in this web page:
*** /usr/src/usr.sbin/ppp/ppp/throughput.c.original Mon Jun 18 18:14:33 2012 --- /usr/src/usr.sbin/ppp/ppp/throughput.c Mon Jun 18 22:50:11 2012 *************** *** 163,168 **** --- 163,169 ---- unsigned long long old; int uptime, divisor; unsigned long long octets; + int q; // arc timer_Stop(&t->Timer); *************** *** 172,178 **** old = t->in.SampleOctets[t->nSample]; t->in.SampleOctets[t->nSample] = t->OctetsIn; t->in.OctetsPerSecond = (t->in.SampleOctets[t->nSample] - old) / divisor; ! old = t->out.SampleOctets[t->nSample]; t->out.SampleOctets[t->nSample] = t->OctetsOut; t->out.OctetsPerSecond = (t->out.SampleOctets[t->nSample] - old) / divisor; --- 173,181 ---- old = t->in.SampleOctets[t->nSample]; t->in.SampleOctets[t->nSample] = t->OctetsIn; t->in.OctetsPerSecond = (t->in.SampleOctets[t->nSample] - old) / divisor; ! // this writes about once a second (allowing for buffer flushing, etc.) ! q = (t->in.SampleOctets[t->nSample] - old) / divisor; ! printf("%i\n",q); old = t->out.SampleOctets[t->nSample]; t->out.SampleOctets[t->nSample] = t->OctetsOut; t->out.OctetsPerSecond = (t->out.SampleOctets[t->nSample] - old) / divisor;
Tue Jan 29 12:19:36 EST 2013
It's entirely likely that I'll never get back to the GUI version of this. I like the precision that this version gives me. If I'm downloading with wget and I see 1 K per second coming in, but this shows 3 K per second being passed over the wire, I start looking around. Yahoo mail is one frequent culprit: the pages refresh to get fresh advertising every N seconds, so even if you've got that Firefox tab buried and maybe you're on a different pane of your desktop, that bandwidth is still wasted. I've also got a WiFi access point that I can turn on with a script and if the Kindle Fire's turned on upstairs it's talking to Amazon every chance it gets. I also have to pull the network plug out of my laptop once in a while because maybe some web page in the Firefox in that is doing refreshes. Seeing exact numbers from PPP and wget that I can compare really helps.
I just modified the throughput.c on my laptop by hand from looking at this page. It's only 4 lines. With colder weather I've been downloading at night fairly often on my laptop from upstairs (different modem) lately. I just have to run PPP in an rxvt window that I can keep an eye on. But then it needed its own rxvt window before anyway.
I'm getting sidetracked again. Back to reading vol. 4 More later... (ab1jx, 6/20/2012)
AB1JX / toys/