/* cd: /usr/local/bin/lirccd# */ /* From /usr/include/bits/signum.h */ #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill, unblockable (POSIX). */ #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* Broken pipe (POSIX). */ #define SIGALRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */ global files = array(), custom = array(), playlist = array(); global args = array(""); global alarms = array(); global alarmnames = array("Playback", "Stop", "Volume raise"); global child = -1, paused = 0, curfile = 0, oldfile; global dieaction = 2, rprev = -1, rnext = -1; global cookie = -1; global bsl = -1, bsr = -1; function say(str) { exec("say \c" + str + "\c &"); } function saysync(str, pause) { var prepaused; prepaused = paused; pause(pause); exec("say \c" + str + "\c"); if(!prepaused) pause(0); } function died(id) { discardchild(id); if(child == id) child = -1; if(dieaction == 1) { if((++curfile) >= (int)playlist) curfile = 0; restart(1); } if(dieaction == 2) restart(1); if(dieaction == 3) { rprev = curfile; rnext = -1; curfile = rand((int)playlist); restart(1); } } function killcur() { if(child >= 0) { if(running(child)) { if(paused) killchild2(child, SIGCONT); killchild(child); } discardchild(child); child = -1; } paused = 0; } function restart(force) { var running; if(child >= 0) { running = running(child); killcur(); } else { running = 0; } if(running || force) { if(curfile < 0) { curfile = ((int)playlist) - 1; saysync("Negative song number", 0); } if(curfile >= (int)playlist) { curfile = 0; saysync("Song number overflow", 0); } ext = strend(playlist[curfile], strrchr(playlist[curfile], ".")); if(strlower(ext) == ".mp3") child = execarray("mpg123", array("mpg123", "-o", "oss", "-q", playlist[curfile])); if(strlower(ext) == ".ogg") child = execarray("sox", array("sox", "-t", ".ogg", playlist[curfile], "-t", "ossdsp", "/dev/dsp")); childnotify(child, "died"); } } function pause(pause) { paused = 0; if(child != -1) { if(running(child)) { if(paused = pause) killchild2(child, SIGSTOP); else killchild2(child, SIGCONT); } else { discardchild(child); child = -1; } } } function globmusic() { files = array(); dirs = expand(file(getenv("HOME") + "/.mp3/dirs"), "\n"); for(i = 0; i < (int)dirs; i++) { tfiles = glob(dirs[i] + "/*.[Mm][Pp]3", 0); tfiles += glob(dirs[i] + "/*.[Oo][Gg][Gg]", 0); sort(tfiles); files += tfiles; } } function init() { globmusic(); playlist = files; } function gualarm(id) { var i, info; for(i = 0; i < (int)alarms; i++) { if(alarms[i][0] == id) { info = alarms[i]; alarms -= i; return(info); } } /* Beware of NULL values */ } function volalarm(id) { gualarm(id); exec("aumix -v100 -w75"); } function playalarm(id) { var song; song = gualarm(id)[3]; if(song >= 0) curfile = song; restart(1); } function stopalarm(id) { gualarm(id); killcur(); } function grargs() { var largs; largs = args; args = array(""); return(largs); } function playsound(file) { exec("sox " + getenv("HOME") + "/sounds/" + file + " -t ossdsp /dev/dsp &"); } bind recursively fallback "[0-9]" { args[(int)args - 1] += button; say(button); } bind recursively "Zoom" args += ""; bind recursively fallback "Vol-" { var largs; largs = grargs(); if(largs[0] == "") exec("aumix -w-5"); else exec("aumix -w" + largs[0]); } bind recursively fallback "Vol\\+" { var largs; largs = grargs(); if(largs[0] == "") exec("aumix -w+5"); else exec("aumix -v" + largs[0]); } bind recursively ".*" { if(!regcmp("[0-9]", button, NULL)) playsound("click02.wav"); else if(button == "Zoom") playsound("click01.wav"); else if((button == "Vol+") || (button == "Vol-")) playsound("click02.wav"); else if(button == "Chan_Last") playsound("click03.wav"); else playsound("click04.wav"); } bind recursively "Chan_Last" grargs(); bind recursively "Info" saysync((string)file(getenv("HOME") + "/phone/lastname"), 1); bind "F_RADIO" subtree { say("MP3 Control"); bind "Play" { var largs; if((child == -1) || !paused) { largs = grargs(); if(largs[0] != "") curfile = (int)(largs[0]); restart(1); } else { pause(0); } } bind "Stop" { if(child == -1) curfile = 0; else killcur(); } bind "Pause" { pause(!paused); } bind "Rewind" { if((dieaction == 3) && (rprev != -1)) { rnext = curfile; curfile = rprev; rprev = -1; } else { if(dieaction == 3) rnext = -1; if((--curfile) < 0) curfile = (int)playlist - 1; } restart(0); } bind "FF" { if((dieaction == 3) && (rnext != -1)) { rprev = curfile; curfile = rnext; rnext = -1; } else { if(dieaction == 3) rprev = -1; if((++curfile) >= (int)playlist) curfile = 0; } restart(0); } bind "Redo" { if((++dieaction) > 3) dieaction = 0; if(dieaction == 0) say("Stop"); if(dieaction == 1) say("Continue"); if(dieaction == 2) say("Repeat"); if(dieaction == 3) say("Random"); rprev = rnext = -1; } bind recursively "Preview" saysync(pipe("date +%H:%M:%S"), 1); bind "Next" { file = strend(playlist[curfile], strrchr(playlist[curfile], "/") + 1); file = strbeg(file, strrchr(file, ".")); say((string)curfile + " -- " + file); } bind "Left" { var largs; largs = grargs(); if((int)largs > 1) { bsl = 0; } if((bsl != -1) && (curfile > bsl)) { bsr = curfile - 1; say((string)(bsr - bsl + 1)); curfile = bsl + ((bsr - bsl) / 2); restart(1); } } bind "Right" { var largs; largs = grargs(); if((int)largs > 1) { bsr = (int)playlist; } if((bsl != -1) && (curfile < bsr)) { bsl = curfile + 1; say((string)(bsr - bsl + 1)); curfile = bsl + ((bsr - bsl) / 2); restart(1); } } bind "Middle" { var i, o, groups, conts, curg, largs; largs = grargs(); if((int)largs > 1) { bsl = 0; bsr = (int)playlist - 1; curfile = bsr / 2; } else { if(dieaction == 3) { rprev = curfile; rnext = -1; } curfile = rand((int)playlist); } /* groups = array(); conts = array(); for(i = 0; i < (int)playlist; i++) { curg = NULL; for(o = 0; (strmid(playlist[i], o, 1) != "") && (strmid(playlist[i], o, 3) != " - "); o++); if(strmid(playlist[i], o, 3) == " - ") { curg = strbeg(playlist[i], o); } else { curg = ""; } for(o = 0; (o < (int)groups) && (groups[o] != curg); o++); if(o == (int)groups) { groups += (string)curg; conts += array(array()); } conts[o] += (int)i; } i = rand((int)conts); o = rand((int)(conts[i])); echo(i); echo((int)(conts[i])); echo(o); curfile = conts[i][o]; */ restart(1); } bind "Menu" subtree { say("Choose sub menu"); bind "1" subtree { say("Scheduling mode"); bind "Play" { var largs, day; largs = grargs(); hour = (int)(largs[0]) / 100; min = (int)(largs[0]) - (hour * 100); day = timearray(time())[2]; time = mktime(-1, -1, day, hour, min, 0); if(time < time()) time = mktime(-1, -1, day + 1, hour, min, 0); if(((int)largs > 1) && (largs[1] != "")) { alarms += (array)array(alarm(time, "playalarm"), 0, time, (int)(largs[1])); file = strend(playlist[(int)(largs[1])], strrchr(playlist[(int)(largs[1])], "/") + 1); file = strbeg(file, strrchr(file, ".")); say("Playback of " + file + " scheduled at " + (string)hour + ":" + (string)min); } else { alarms += (array)array(alarm(time, "playalarm"), 0, time, -1); say("Playback scheduled at " + (string)hour + ":" + (string)min); } } bind "Stop" { var largs, day; largs = grargs(); hour = (int)(largs[0]) / 100; min = (int)(largs[0]) - (hour * 100); day = timearray(time())[2]; time = mktime(-1, -1, day, hour, min, 0); if(time < time()) time = mktime(-1, -1, day + 1, hour, min, 0); alarms += (array)array(alarm(time, "stopalarm"), 1, time); say("Stop scheduled at " + (string)hour + ":" + (string)min); } bind "Vol\\+" { var largs, day; largs = grargs(); hour = (int)(largs[0]) / 100; min = (int)(largs[0]) - (hour * 100); day = timearray(time())[2]; time = mktime(-1, -1, day, hour, min, 0); if(time < time()) time = mktime(-1, -1, day + 1, hour, min, 0); alarms += (array)array(alarm(time, "volalarm"), 2, time); say("Volume raise scheduled at " + (string)hour + ":" + (string)min); } bind "^L$" { var alist, i, ti; alist = "Alarm list: "; for(i = 0; i < (int)alarms; i++) { alist += (string)i + ", "; if((alarms[i][1] == 0) && (alarms[i][3] == -1)) alist += "playback"; if((alarms[i][1] == 0) && (alarms[i][3] != -1)) alist += "sc playback"; if(alarms[i][1] == 1) alist += "stop"; if(alarms[i][1] == 2) alist += "volraise"; ti = timearray(alarms[i][2]); alist += " " + (string)(ti[3]) + ":" + (string)(ti[4]); alist += ": "; } say(alist); } bind "Power" { var largs, a; largs = grargs(); a = (int)(largs[0]); if((a >= (int)alarms) || (calarm(alarms[a][0]))) { say("No such alarm"); } else { alarms -= a; say("Alarm " + (string)a + " cancelled"); } } bind "Undo" { say("Exit scheduling"); endbinding(); } } bind "2" { globmusic(); playlist = files; say("Music files reglobbed"); } bind "3" subtree { { say("Playlist editor"); playlist = files; oldfile = curfile; curfile = 0; } bind "Record" { custom += playlist[curfile++]; restart(0); } bind "Play" { var largs; largs = grargs(); if(largs[0] != "") curfile = (int)(largs[0]); restart(1); } bind "Stop" killcur(); bind "Rewind" { if((--curfile) < 0) curfile = (int)playlist - 1; restart(0); } bind "FF" { if((++curfile) >= (int)playlist) curfile = 0; restart(0); } bind "Redo" { custom = array(); say("Playlist erased"); } bind "Left" { var largs; largs = grargs(); custom = expand(file(getenv("HOME") + "/.mp3/pl" + largs[0]), "\n"); say("Playlist " + largs[0] + " loaded"); } bind "Right" { var largs; var i, data; largs = grargs(); data = ""; for(i = 0; i < (int)custom; i++) data += custom[i] + "\n"; tofile(getenv("HOME") + "/.mp3/pl" + largs[0], data); say("Playlist " + largs[0] + " saved"); } bind "Undo" { say("Exit playlist editor"); curfile = oldfile; if((int)custom > 0) playlist = custom; else playlist = files; endbinding(); } } bind "4" subtree { say("Lock mode"); bind "Vol[+-]" { ; } bind "Middle" { var time; if(child >= 0) { killcur(); exec("aumix -v85 -w40"); time = time() + 400 + rand(300); alarms += (array)array(alarm(time, "playalarm"), 0, time, (int)curfile); alarms += (array)array(alarm(time, "volalarm"), 2, time); say("Snoozing"); } } bind "Undo" { var largs; largs = grargs(); if((cookie < 0) || ((int)(largs[0]) == 0)) { cookie = rand(9999) + 1; say("Magic cookie: " + (string)cookie); } else if((int)(largs[0]) == cookie) { cookie = -1; say("Exit lock mode"); endbinding(); } } } bind "5" { var who, dpy, i; who = expand(pipe("who"), "\n"); for(i = 0; i < (int)who; i++) { if(!regcmp("^fredrik +(:[0-9]+)", who[i], dpy)) exec("/usr/X11R6/bin/xset -display " + dpy[1] + " dpms force off"); } } bind "6" { var who, dpy, i; who = expand(pipe("who"), "\n"); for(i = 0; i < (int)who; i++) { if(!regcmp("^fredrik +(:[0-9]+)", who[i], dpy)) exec("/usr/X11R6/bin/xset -display " + dpy[1] + " dpms force on"); } } bind "Undo" { say("Exit function menu"); endbinding(); } } bind "Undo" { say("Exit MP3 control"); endbinding(); } } bind "F_TV" subtree { say("MPlayer control"); bind "Left" { var largs; largs = grargs(); if(largs[0]) sendstring("mplayer", "seek -" + largs[0]); else sendstring("mplayer", "seek -10"); } bind "Right" { var largs; largs = grargs(); if(largs[0]) sendstring("mplayer", "seek +" + largs[0]); else sendstring("mplayer", "seek +10"); } bind "Pause" sendstring("mplayer", "pause"); bind "Fullscreen" sendstring("mplayer", "vo_fullscreen"); bind "Ch-" sendstring("mplayer", "audio_delay -0.100"); bind "Ch\\+" sendstring("mplayer", "audio_delay 0.100"); bind "Undo" { say("Exit MPlayer control"); endbinding(); } }