Tiny Core Extensions > TCE Tips & Tricks
nifty volume control for jwm
softwaregurl:
I was following this topic but just recently had the time to do my own version.
I hacked watcher again (thanks Curaga) so it reads /tmp/watcher2msg and displays the contents of that file instead if its not empty. any app should be able to take advantage of this. I also renamed to watcher2 and put it in /usr/local/bin.
--- Code: ---echo "testing" >/tmp/watcher2msg
--- End code ---
displays "testing" instead of the normal watcher stuff
--- Code: ---echo "" >/tmp/watcher2msg
--- End code ---
clears that and goes back to the normal watcher stuff.
Watch out for the bug in this, if /tmp/watcher2msg does not exist there will be many error messages to stderr.
--- Code: ---// Copyright 2008 Curaga
// A small app to be swallowed into JWM tray, to show cpu,mem,swap usage
// What do you know, mixing C with fltk C++ works just fine
// Licensed under the GPLv2, as scanf did not work for me, so
// I benefited from Open Source and copied the fgets block from
// wmbluemem :)
// Thank You Mihai Dr\ufffdghicioiu
// Changes from Softwaregurl:
// Moved letters after the values with percentages
// Gigabytes for swap and mem
// May 2009
// Reads a file and displays instead if not empty
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/filename.H>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char version[4]="1.5";
float timeout=1.5,mem=0,swap=0,cpu=0,used=0,oldused=0,cputotal=0,oldcputotal=0;
int arg_i=0, fontsize=10, mib=0;
char memind[2]="m",swapind[2]="m",newmsg[25];
FILE *meminfo,*cpuinfo,*msg;
void checkup(){
unsigned long memtotal,memfree,buffers,cache,swaptotal,swapfree;
unsigned long user,nice,sys,idle,iowait,irq,softirq,virt,virt2;
char buf[60],buf2[190];
char *p;
int i;
if((meminfo=fopen("/proc/meminfo","r"))==NULL){
fprintf(stderr,"Error opening meminfo");
exit(1);
}
if((cpuinfo=fopen("/proc/stat","r"))==NULL){
fprintf(stderr,"Error opening stat");
exit(1);
}
if((msg=fopen("/tmp/watcher2msg","r"))==NULL){
fprintf(stderr,"Error opening msg");
} else {
fgets(newmsg, 25, msg);
fclose(msg);
}
fgets(buf, 60, meminfo); strtok(buf, " "); p = strtok(NULL, " ");
memtotal = strtol(p, NULL, 10);
fgets(buf, 60, meminfo); strtok(buf, " "); p = strtok(NULL, " ");
memfree = strtol(p, NULL, 10);
fgets(buf, 60, meminfo); strtok(buf, " "); p = strtok(NULL, " ");
buffers = strtol(p, NULL, 10);
fgets(buf, 60, meminfo); strtok(buf, " "); p = strtok(NULL, " ");
cache = strtol(p, NULL, 10);
for(i = 1; i < 11; i++){
fgets(buf, 60, meminfo);
p=strtok(buf, " ");
if(strcmp("SwapTotal:",p)==0) break;
}
p = strtok(NULL, " ");
swaptotal = strtol(p, NULL, 10);
fgets(buf, 60, meminfo); strtok(buf, " "); p = strtok(NULL, " ");
swapfree = strtol(p, NULL, 10);
fclose(meminfo);
fgets(buf2,190,cpuinfo); strtok(buf2, " ");
p=strtok(NULL, " "); user=strtol(p, NULL, 10);
p=strtok(NULL, " "); nice=strtol(p, NULL, 10);
p=strtok(NULL, " "); sys=strtol(p, NULL, 10);
p=strtok(NULL, " "); idle=strtol(p, NULL, 10);
p=strtok(NULL, " "); iowait=strtol(p, NULL, 10);
p=strtok(NULL, " "); irq=strtol(p, NULL, 10);
p=strtok(NULL, " "); softirq=strtol(p, NULL,10);
p=strtok(NULL, " "); virt=strtol(p, NULL, 10);
p=strtok(NULL, " "); virt2=strtol(p, NULL, 10);
fclose(cpuinfo);
used=(float)(user+nice+sys+irq+softirq+virt+virt2);
cputotal=used+(float)idle+(float)iowait;
cpu=((used-oldused)/(cputotal-oldcputotal))*(float)100;
if(mib==1){
mem=(float)(memtotal-(memfree+buffers+cache))/(float)1024;
swap=(float)(swaptotal-swapfree)/(float)1024;
}
if(mib==2){
mem=(float)(memfree+buffers+cache)/(float)1024;
swap=(float)swapfree/(float)1024;
}
if(mib==0){
mem=((float)(memtotal-(memfree+buffers+cache))/ (float) memtotal)*(float)100;
swap=((float)(swaptotal-swapfree)/(float)swaptotal)*(float)100;
}
oldused=used;
oldcputotal=cputotal;
if(mem>999.9){
mem=mem/1024;
strcpy(memind,"g");
}
if(swap>999.9){
swap=swap/1024;
strcpy(swapind,"g");
}
if(swaptotal==0){
swap=0;
}
}
void tick(void* v){
checkup();
Fl_Box* box=(Fl_Box*)v;
char yeah[25]="";
if(mib) sprintf(yeah,"C%.1f%% M%.1f%s S%.1f%s",cpu,mem,memind,swap,swapind);
else sprintf(yeah,"%.1f%%C %.1f%%M %.1f%%S",cpu,mem,swap);
if ( strlen (newmsg) > 1) box->copy_label(newmsg);
else box->copy_label(yeah);
Fl::repeat_timeout(timeout,tick,box);
}
int parser(int argc, char **argv, int &z){
if(strcmp(argv[z], "-h")==0){
printf("Watcher %s\n" \
"(C) Curaga 2008\n" \
"Fixes from softwaregurl\n\n" \
"Switches: \n" \
"\t-bg <color> background color \n" \
"\t-fg <color> text color\n" \
"\t-m show used MiB instead of percent on mem/swap\n" \
"\t-r show remaining MiB instead of percent on mem/swap\n" \
"\t-s <float> check every s secs, default %.2f\n" \
"\t-f <size> use font size f (default %d)\n" \
"The color can be either named (green) or rgb ('#00ff00')\n",version,
timeout,fontsize);
exit(0);
}
if(strcmp(argv[z], "-s")==0){
timeout=strtof(argv[(z+1)],NULL);
z+=2;
return 1;
}
if(strcmp(argv[z], "-f")==0){
fontsize=atoi(argv[(z+1)]);
z+=2;
return 1;
}
if(strcmp(argv[z], "-m")==0){
mib=1;
z++;
return 1;
}
if(strcmp(argv[z], "-r")==0){
mib=2;
z++;
return 1;
}
return 0;
}
int main(int argc, char **argv) {
// Graphic stuff
Fl_Window *window = new Fl_Window(124,18);
Fl::args(argc,argv,arg_i,&parser);
Fl_Box *box = new Fl_Box(FL_NO_BOX,0,0,124,18,"Starting...");
box->labelsize(fontsize);
window->end();
window->show(argc, argv);
Fl::add_timeout(timeout,tick,box);
return Fl::run();
}
--- End code ---
then this is what I wrote
--- Code: ---#!/usr/bin/perl
# adjvolume.pl adjusts volume by reading from a fifo
# Copyright 2009 Softwaregurl
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#### set volume up-down commands $$$$
# ????? (yes, five question marks) indicates where to insert the channel name/number.
$cmds{'vup'}="amixer set ????? 2%+";
$cmds{'vdn'}="amixer set ????? 2%-";
#### set controls display & names/numbers $$$$
# list of control names to display
@cnmd = ('Master',
'PCM',
'Line In'
);
# list of control names/numbers corresponding to above
@ctnn = ('Master',
'PCM',
'Line'
);
print "commands\n";
sub adjvolume {
$syscmd="$cmds{$cmd} >/dev/null";
$syscmd=~ s|\?\?\?\?\?|$ctnn[$ctlnn]|g;
$err = system ("$syscmd >/tmp/adjvolumedata");
if ($err) { print "$err bad volume command $syscmd\n";}
undef ($err);
&rdadjvolumedata;
&printout;
}
sub rdadjvolumedata {
open (vol1, "/tmp/adjvolumedata") || &error0recover;
@adjvolumedata0=<vol1>;
close (vol1);
$adjvolumedata1=@adjvolumedata0;
$adjvolumedata1--;
$adjvolumedata2="$adjvolumedata0[$adjvolumedata1]";
chomp ($adjvolumedata2);
$adjvolumedata2 =~ s/[^0-9]+/ /g;
chop ($adjvolumedata2);
$adjvolumedata2 = "$adjvolumedata2\%";
$adjvolumedata1--;
$adjvolumedata3="$adjvolumedata0[$adjvolumedata1]";
chomp ($adjvolumedata3);
$adjvolumedata3 =~ s/[^0-9]+/ /g;
$adjvolumedata3 = "$adjvolumedata2";
$adjvolumedata2="$adjvolumedata2 $adjvolumedata3";
}
sub changec {
$ctlnn++;
if ($ctlnn >= $ncnmd) { $ctlnn=0;}
&printout;
}
sub proccmd {
if ($cmd eq "vup" || $cmd eq "vdn") { &adjvolume;}
if ($cmd eq "cdn") { &changec;}
}
sub printout {
print "$cnmd[$ctlnn], $adjvolumedata2\n";
$tmp0="echo \"$cnmd[$ctlnn], $adjvolumedata2\" >/tmp/watcher2msg";
system ($tmp0);
}
sub error0recover {
exit;
}
sub rddata {
for ($j=0;$j<9;$j=1) {
$cmd=<vol0>;
chomp ($cmd);
&proccmd;
if ($cmd eq "" ) {
sleep 2;
$nulltime++;
if ($nulltime > 4) {
$tmp0="echo \"\" >/tmp/watcher2msg";
system ($tmp0);
$nulltime=0;
}
}
}
}
$ncnmd=@cnmd;
open (vol0, "/tmp/adjvolumefifo") || &error0recover;
&rddata;
print "exiting\n";
exit;
--- End code ---
it reads commands from /tmp/adjvolumefifo and sends output to /tmp/watcher2msg then clears it about 10 seconds later as well as writing to the terminal. anything can send commands to it via the fifo.
and this is my .jwmrc-tray
--- Code: ---<JWM>
<!-- Additional tray attributes: autohide, width, border, layer, layout -->
<Tray x="0" y="0" height="20">
<!-- Additional TaskList attribute: maxwidth -->
<TaskList/>
<!-- Additional TrayButton attribute: label -->
<TrayButton label="_">showdesktop</TrayButton>
<TrayButton label="^">exec:echo "vup" >>/tmp/adjvolumefifo </TrayButton>
<TrayButton label="v">exec:echo "vdn" >>/tmp/adjvolumefifo </TrayButton>
<TrayButton label="C">exec:echo "cdn" >>/tmp/adjvolumefifo </TrayButton>
<TrayButton label="S">exec:echo "sel" >>/tmp/adjvolumefifo </TrayButton>
<!-- Additional Pager attributes; width, height -->
<Pager/>
<!-- Additional Swallow attribute: height -->
<Swallow name="watcher2" width="0"> watcher2 </Swallow>
<Clock format="%a %d %b %k:%M"></Clock>
<Dock/>
<TrayButton label="X">exec:exittc</TrayButton>
</Tray>
</JWM>
--- End code ---
the "S" is for future use. it needs a fifo named /tmp/adjvolumefifo
--- Code: ---mkfifo /tmp/adjvolumefifo
--- End code ---
I was backgrounding it in a terminal so I could see which control i'm on. now I just do
--- Code: ---/usr/local/mediaswg/bin/adjvolume.pl >/dev/null &
--- End code ---
to use it, C changes channel and the ^ and v adjust the level. Set the first four variables for your card. Output works with alsa and fits in watcher.
this requires perl5 and
--- Code: ---[ -e /usr/bin/perl ] || sudo ln -s /usr/local/bin/perl /usr/bin/perl
--- End code ---
still a few bugs to work out and more features I want but so far it works.
tobiaus:
hehe, it uses a daemon? that's fun.
jls:
In tc 1.4.1 I use the ossxmix from oss package of tc 2.0RC1
tobiaus:
--- Quote from: jls_legalize on May 05, 2009, 04:43:31 PM ---In tc 1.4.1 I use the ossxmix from oss package of tc 2.0RC1
--- End quote ---
it's very good. i wish i could use it in ubuntu. i'm using wmix, which is good enough, but it will not dock in jwm, and whenever you close the window it says "kill this window? it may cause data to be lost!" which is a ridiculous message, not to mention annoying. killall wmix (so that it doesn't ask) too many times and x may close!
i use the same v ^ buttons in jwm that i made for tc, but ^ opens the stupid volume control, and v issues "killall -2 wmix." for whatever reason i should know, killall -2 is safer.
when testing 2.x (can't upgrade to it yet) i like to use ossxmix unless i have my buttons installed. i like how the buttons are "always open" even though they're not running anything. i also like the idea of assigning keys, like mikshaw would.
jls:
I was sying I'm using ossxmix in 1.4.1
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version