diff --git a/rc/bin/juke b/rc/bin/juke deleted file mode 100755 index 6a523d847..000000000 --- a/rc/bin/juke +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/rc -rfork e -wide=`{echo $vgasize | sed 's/(.*)x.*x.*/\1 > 240/' | hoc} -debug=0 -tflag='' -wflag='' -host='' -flags=() -sname=$user -if (! ~ $wide 1) { - flags=($flags -t) -} -while(! ~ $#* 0) { - switch ($1) { - case -d - debug=$2 - shift - case -t - tflag='-t' - case -h - host=$2 - shift - case -w - wflags='-w' - case -s - sname=$2 - shift - case -* - echo usage: juke [-d level] [-tw] [-s srv] [-h srvhost] >[1=2] - exit usage - } - shift -} -if (! test -f /mnt/playlist) { - if (! ~ $debug '0') echo mounting playlistfs - if (! test -e /srv/playlist.$sname && ! ~ $host ''){ - import -a $host /srv /srv - } - if (! mount -b /srv/playlist.$sname /mnt >/dev/null >[2]/dev/null){ - rm -f /srv/playlist.$sname - if (! ~ $debug '0') echo starting playlistfs - games/playlistfs -s $sname -d $debug - } -} -if (~ `{ls /mnt/juke >[2]/dev/null | sed '1q'} '') { - if (! test -e /srv/jukefs.$sname && ! ~ $host ''){ - import -a $host /srv /srv - } - if (! mount -b /srv/jukefs.$sname /mnt >/dev/null >[2]/dev/null){ - if (! ~ $debug '0') echo games/jukefs - games/jukefs -s $sname - } -} -if (~ $wflags '-w') { - exec games/jukebox -w -d $debug $tflag & -} -exec games/jukebox -d $debug $tflag diff --git a/sys/man/7/juke b/sys/man/7/juke deleted file mode 100644 index 1e49f43f5..000000000 --- a/sys/man/7/juke +++ /dev/null @@ -1,368 +0,0 @@ -.TH JUKE 7 -.SH NAME -juke \- music jukebox -.SH SYNOPSIS -.B juke -[ -.B \-t -] -[ -.B \-w -] -[ -.B \-h -.I srvhost -] -[ -.B \-s -.I srvname -] -.ift .sp 0.5 -.ifn .sp -.B games/jukebox -[ -.B \-t -] -[ -.B \-w -] -.ift .sp 0.5 -.ifn .sp -.B games/jukefs -[ -.B \-m -.I mountpoint -] -[ -.B \-s -.I srvname -] -[ -.I mapfile -] -.SH DESCRIPTION -.I Jukebox -controls a playlist server -(see -.IR playlistfs (7)) -through a graphical user interface. It connects to a music database server which reads a set of -.I map -files that describe recordings and their location. Currently, there is -one set of maps, mostly for classical music, with some jazz and other stuff -thrown in. These are served by -.BR jukefs , -which presents a file system conventionally mounted at -.BR /mnt/juke . -The playlist, explained below, is managed by a file system implemented by -.IR playlistfs (7) -and normally mounted on -.BR /mnt . -.PP -.I Jukebox -is most easily started through the -.I juke -shell script. -.PP -.I Jukebox -has four windows, which can be selected by clicking the appropriate tab -at the top of the window. -.PP -Above the tab are nine buttons and a volume slider. The -.ift buttons, shown below, -.ifn buttons -are named, from left to right, -.IR Exit , -.IR Pause , -.IR Play , -.IR Halt , -.IR Back , -.IR Forward , -.IR Root , -.IR Delete , -and -.IR Help . -The buttons are -.I active -when they are displayed in dark green (or red). When they are pale blue -they are -.IR inactive . -The Exit button is always active; it exits the program (but leaves the playlist and music database -servers running). -.PP -The -.I browse -window is for browsing through the music and selecting music to play. -Browsing down in the music hierarchy is done by clicking button one on -an item. Clicking button three goes back up. -Clicking button two recursively adds all files below the selected item to -the -.IR "play list" . -.PP -The selected music is displayed in the -.I playlist -window. -The track currently playing is shown in the -.I playing -window. -.PP -The -.I Root -button browses back to the root. -.PP -The -.I Delete -button empties the playlist. -.PP -The -.I Help -displays a minimal on-line manual. -.PP -.I Play -starts playing at the beginning of the play list, or at the selected track in -the play list. -.PP -During play, -.IR Pause , -.IR Stop , -.IR Back , -and -.I Forward -are active. -.I Back -and -.I Forward -go back or forward a track at a time. The other buttons do the obvious thing. -.PP -The -.B \-t -flag chooses a tiny font, useful for handhelds. -.PP -The -.B \-w -flag creates the jukebox in a new window. Normally, the jukebox takes over -the window in which it is invoked. -.PP -The -.B \-s -flag specifies the name under which the file descriptors of the playlist and databse servers are posted -in /srv. This allows two or more play list servers to exist on one platform, e.g., when -there are several audio devices. The default value of the flag is -.B $\f2user\fP -for a playlist server at -.B /srv/playlistfs.$\f2user\fP -and a database server at -.BR /srv/jukefs.$\f2user\fP . -.sp -.LP -.B Jukefs -reads a set of -.I maps -describing the music data, builds an in-memory database, and provides -lookup service to -.IR jukebox . -The default map is -.BR /sys/lib/music/map . -It consists of a hierarchical set of -.IR objects . -Each object has a type, a value, zero or more attribute-value -pairs and zero or more subobjects. An object consists of the -type, followed by its contents between curly brackets. -Attribute value pairs consist -of a single line containing an attribute name, an equals sign, and -a value. -The value of an object is any text not containing curly brackets or equals -signs. Here is an example: -.EX -.ps -2 -.vs -2p -.sp -category { - composer = mahler - - Gustav Mahler - (1860 — 1911) - - work { - path {classic/mahler} - class = symphonic - orchestra = rfo - conductor = Waart,~Edo~de - - Symphony Nº 5 in c♯ (RFO, Vienna) - performance{ - Radio Filharmonisch Orkest Holland - Edo de Waart, conductor - - recorded: Musikverein, Vienna, May 6, 1996 - } - command {number} - track { - Trauermarsch (In gemessenem Schritt. Streng. Wie ein Kondukt) - time {13:55} - file {034.pac} - } - track { - Stürmisch bewegt, mit größter Vehemenz - time {15:34} - file {035.pac} - } - track { - Scherzo (Kräftig, nicht zu schnell) - time {18:54} - file {036.pac} - } - track { - Adagietto (Sehr Langsam) - time {10:01} - file {037.pac} - } - track { - Rondo–Finale (Allegro) - time {15:44} - file {038.pac} - } - } -} -.EE -.LP -This example shows a -.I category -object for the composer Gustav Mahler (the value consists of the two -lines `Gustav Mahler' and `(1860 — 1911)') with one subobject, a -.I work -object whose value is `Symphony Nº 5 in c♯ (RFO, Vienna)'. The work object -contains six subobjects: one -.I performance -object and five -.I track -objects. -.PP -.I Category -objects must contain exactly one attribute-value pair. The attribute -names a subobject of the root under which this category object will -be placed. Gustav Mahler, thus, will be placed in -Root→composer. -.IR Work , -.IR Recording , -.IR Part , -and -.IR Track , -objects all describe named containers for subunits. -A -.IR Lyrics , -.IR Performance , -or -.IR Soloists -object adds information to a -.IR Work , -.IR Recording , -.IR Part , -or -.IR Track , -object. It should only contain text. -The same is true for a -.I Time -object; however, it should only be used adjacent to -.I File -objects and it should contain the running time of that file (this -is for future use). -.PP -A -.I File -object specifies a file to be played. When the -.I Select -button is pressed, all file objects contained hierarchically in the -selected object are added to the playlist. -.PP -There are a number of pseudo objects: -.I Command -may contain either -.I sort -or -.IR number . -The -.I sort -command sorts the subobjects of the object it appears in by -.I key -or textual content. -The -.I number -commands prepends numbers to the texts of its subobjects -(e.g., for the parts in a symphony) -.PP -An -.I Include -object is replaced by the contents of the named file. -.PP -A -.I Key -object specifies a key for sorting subobjects. -.PP -Finally, a -.I Path -object specifies a path to be prepended to the files named in -hierarchically contained -.I File -objects. -.PP -The attribute-value value pairs arrange for entries to be made of the -current object in a -.I Category -object named by the attribute directly under the root. -.sp -.LP -The interface to the browsing database is through a file system -implemented by -.BR jukefs . -The file system synthesises a directory per object. Each directory contains a set of files -describing the object's attributes: -.TP -.B children -contains a new-line separated list of subobject names. For each name, -.I x -the directory -.BI /mnt/juke/ x -describes the subobject. -.TP -.B digest -contains a one-line summary of the object -.TP -.B files -is a new-line separated list of file objects contained in this object. -Each line consists of object name and file name. -.TP -.B fulltext -is the fulltextual value of the object. -.TP -.B key -contains the key by which objects are sorted -.TP -.B miniparentage -is a one-line summary of the objects and the path leading to it from the root. -This is the line displayed in the playlist and bottom browse windows of -.BR games/jukebox . -.TP -.B parent -is the object reference to the parent of this object. -.TP -.B parentage -is a full description of the path leading to this object and the object itself. -This is the string displayed in the top of the Browse and Playing windows -of -.BR games/jukebox . -.TP -.B text -is the text field of the object. -.TP -.B type -is the type of the object -.LP -.SH FILES -.BR /sys/lib/music/map : -Default map file -.BR /mnt/juke : -Default mount point for the music database. -.SH SOURCE -.B /sys/src/games/music -.SH SEE ALSO -.IR playlistfs (7). diff --git a/sys/man/7/playlistfs b/sys/man/7/playlistfs deleted file mode 100644 index a38327be2..000000000 --- a/sys/man/7/playlistfs +++ /dev/null @@ -1,147 +0,0 @@ -.TH PLAYLISTFS 7 -.SH NAME -playlistfs \- playlist file system -.SH SYNOPSIS -.B games/playlistfs -[ -.B \-s -.I postname -] -[ -.B \-m -.I mountpoint -] -[ -.B \-a -] -.SH DESCRIPTION -.B Playlistfs -implements an audio player which plays files from a built-in play list. -The player is controlled through three files, usually mounted at -.BR /mnt . -The files are -.B /playctl -for controlling play: start, stop, pause, skip, etc.; -.B /playvol -for controlling the playout volume; and -.B /playlist -for controlling the play list itself. -.PP -All three files can be written to control the player and read to obtain player -status information. -.PP -When read, the files report the current status of the player, volume and playlist, -respectively. End of file is indicated by a read that returns zero bytes, as usual. -However, in all three files, subsequent read operations will block until the status -of the file changes and then report the changed state. When the changed state has -been read, another end-of-file indication is given, after which another read -can be issued to wait for state changes. -.PP -The -.B /playctl -file returns strings of the form `\f2cmd n\fP' -where -.I cmd -is one of -.IR stop , -.IR pause , -or -.I play -and -.I n -is an index (or offset) into the playlist; indices start at zero. -.PP -The commands that can be written to -.B /playctl -take the same form; however, the index is an optional argument. If the -index is omitted, the current value is used. The commands are -.IR play , -.IR stop , -.IR pause , -.IR resume , -and -.IR skip . -.I Play -starts playing at the index. -.I Stop -stops playing. If an index is given, the current index is set to it and -can be used in future commands. -.I Pause -and -.I Resume -interrupt and continue play, respectively. The index argument is always ignored and -the whole command is ignored if the state in which they occur does not -make sense. -.I Skip -adds the argument to the current index (adds one if no argument is given) -and starts play at that index, stopping current play, if necessary. -.PP -Reads of -.B /playvol -return strings of the form -.BR "`volume \f2n\fP'" , -where -.I n -is a number or, if there is more than one channel, a quoted set of numbers, between 0 -(minimum) and 100 (maximum). -Writes to -.B /playvol -take the same form. -.PP -The -.B /playlist -file is an append-only file which accepts lines with one or two fields -per line (parsed using -.BR tokenize ). -The first, compulsory, field is a file name, the optional second argument -may contain a reference to, or a description of, the item, for instance in a graphical -user interface. -.B /playlist -is append-only, individual lines cannot be removed. However, the playlist -can be cleared by opening the file with the -.B OTRUNC -flag. A process that has -.B /playlist -open while the file is truncated will receive an error on the next read with -.B errstr -set to -.IR "reading past eof" . -When this error occurs, clients can seek to the beginning of the file and reread its contents. -.PP -After starting up, -.B Playlistfs -puts itself in the background. When called with the -.B \-s -flag, it posts a mountable file descriptor in -.BR /srv/playlist.\f2postname\fP . -The -.B \-m -flag can be used to specify a mount point other than -.BR /mnt . -.PP -.B Playlistfs -uses the -.IR audio (1) -decoders by running -.IR play (1) -for format detection and conversion to pcm. -.SH FILES -.BR /srv/playlistfs.\f2user\fP : -default -.B playlistfs -mountable file descriptor used by juke(7). -.br -.BR /mnt/playctl : -Control file -.br -.BR /mnt/playlist : -Playlist file -.br -.BR /mnt/playvol : -Volume control file -.SH SOURCE -.B /sys/src/games/music/playlistfs -.SH SEE ALSO -.IR play (1), -.IR audio (1), -.IR juke (7). diff --git a/sys/src/games/mkfile b/sys/src/games/mkfile index 48f720677..89477b88f 100644 --- a/sys/src/games/mkfile +++ b/sys/src/games/mkfile @@ -40,7 +40,6 @@ DIRS=\ mahjongg\ mines\ mix\ - music\ md\ nes\ opl3\ diff --git a/sys/src/games/music/Readme b/sys/src/games/music/Readme deleted file mode 100644 index 59762e77f..000000000 --- a/sys/src/games/music/Readme +++ /dev/null @@ -1,12 +0,0 @@ -The Plan 9 Jukebox consists of three applications: a play-list server, a browse server -and a GUI: - playlist server: playlistfs - browse server: jukefs - GUI: jukebox -The juke.rc script (installed, by default, in /rc/bin/juke) starts them all up. - -To configure, adjust the DEFAULTMAP and ICONPATH in the central mkfile. -The default map is used by jukefs as the root of the descriptive database. -The iconpath is used by jukebox to find the icons. - -Report problems to sape@plan9.bell-labs.com diff --git a/sys/src/games/music/debug.h b/sys/src/games/music/debug.h deleted file mode 100644 index 5015ad872..000000000 --- a/sys/src/games/music/debug.h +++ /dev/null @@ -1,13 +0,0 @@ -extern int debug; - -enum { - DBGSERVER = 0x01, - DBGCONTROL = 0x02, - DBGCTLGRP = 0x04, - DBGPICKLE = 0x08, - DBGSTATE = 0x10, - DBGPLAY = 0x20, - DBGPUMP = 0x40, - DBGTHREAD = 0x80, - DBGFILEDUMP = 0x100, -}; diff --git a/sys/src/games/music/icon/next.bit b/sys/src/games/music/icon/next.bit deleted file mode 100644 index 3464b6eba..000000000 Binary files a/sys/src/games/music/icon/next.bit and /dev/null differ diff --git a/sys/src/games/music/icon/pause.bit b/sys/src/games/music/icon/pause.bit deleted file mode 100644 index b6a0d8d1b..000000000 Binary files a/sys/src/games/music/icon/pause.bit and /dev/null differ diff --git a/sys/src/games/music/icon/play.bit b/sys/src/games/music/icon/play.bit deleted file mode 100644 index 3d2ec8500..000000000 Binary files a/sys/src/games/music/icon/play.bit and /dev/null differ diff --git a/sys/src/games/music/icon/prev.bit b/sys/src/games/music/icon/prev.bit deleted file mode 100644 index d20cf27da..000000000 Binary files a/sys/src/games/music/icon/prev.bit and /dev/null differ diff --git a/sys/src/games/music/icon/question.bit b/sys/src/games/music/icon/question.bit deleted file mode 100644 index 59275d9e0..000000000 Binary files a/sys/src/games/music/icon/question.bit and /dev/null differ diff --git a/sys/src/games/music/icon/root.bit b/sys/src/games/music/icon/root.bit deleted file mode 100644 index 7da3f90d8..000000000 Binary files a/sys/src/games/music/icon/root.bit and /dev/null differ diff --git a/sys/src/games/music/icon/skull.bit b/sys/src/games/music/icon/skull.bit deleted file mode 100644 index c3dd74b78..000000000 Binary files a/sys/src/games/music/icon/skull.bit and /dev/null differ diff --git a/sys/src/games/music/icon/stop.bit b/sys/src/games/music/icon/stop.bit deleted file mode 100644 index 50dd7eae1..000000000 Binary files a/sys/src/games/music/icon/stop.bit and /dev/null differ diff --git a/sys/src/games/music/icon/trash.bit b/sys/src/games/music/icon/trash.bit deleted file mode 100644 index 22af1601f..000000000 Binary files a/sys/src/games/music/icon/trash.bit and /dev/null differ diff --git a/sys/src/games/music/juke.rc b/sys/src/games/music/juke.rc deleted file mode 100755 index a661c7f79..000000000 --- a/sys/src/games/music/juke.rc +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/rc -rfork e -wide=`{echo $vgasize | sed 's/(.*)x.*x.*/\1 > 240/' | hoc} -debug=0 -tflag='' -wflag='' -host='' -flags=() -sname=$user -if (! ~ $wide 1) { - flags=($flags -t) -} -while(! ~ $#* 0) { - switch ($1) { - case -d - debug=$2 - shift - case -t - tflag='-t' - case -h - host=$2 - shift - case -w - wflags='-w' - case -s - sname=$2 - shift - case -* - echo Usage: classical [-d level] [-t] [-h srvhost] - exit usage - } - shift -} -if (! test -f /mnt/playlist) { - if (! ~ $debug '0') echo mounting playlistfs - if (! test -e /srv/playlist.$sname && ! ~ $host ''){ - import -a $host /srv /srv - } - if (! mount -b /srv/playlist.$sname /mnt >/dev/null >[2]/dev/null){ - rm -f /srv/playlist.$sname - if (! ~ $debug '0') echo starting playlistfs - games/playlistfs -s $sname -d $debug - } -} -if (~ `{ls /mnt/juke >[2]/dev/null | sed '1q'} '') { - if (! test -e /srv/jukefs.$sname && ! ~ $host ''){ - import -a $host /srv /srv - } - if (! mount -b /srv/jukefs.$sname /mnt >/dev/null >[2]/dev/null){ - if (! ~ $debug '0') echo games/jukefs - games/jukefs -s $sname - } -} -if (~ $wflags '-w') { - exec games/jukebox -w -d $debug $tflag & -} -exec games/jukebox -d $debug $tflag diff --git a/sys/src/games/music/jukebox/client.c b/sys/src/games/music/jukebox/client.c deleted file mode 100644 index 80022965b..000000000 --- a/sys/src/games/music/jukebox/client.c +++ /dev/null @@ -1,157 +0,0 @@ -#include -#include -#include -#include -#include "client.h" -#include "playlist.h" -#include "../debug.h" - -char *srvmount = "/mnt/juke"; - -char* -getroot(void) -{ - return "root"; -} - -void -fillbrowsebot(char *onum) -{ - char *name, *p, *q; - Biobuf *b, *d; - int c; - - name = smprint("%s/%s/children", srvmount, onum); - b = Bopen(name, OREAD); - if(b == nil) - sysfatal("getchildren: %s: %r", name); - free(name); - while(p = Brdline(b, '\n')){ - c = strtol(p, &q, 0); - assert(*q == '\n'); - *q = 0; - name = smprint("%s/%d/type", srvmount, c); - d = Bopen(name, OREAD); - if(d == nil) - sysfatal("getchildren: %s: %r", name); - free(name); - q = Brdstr(d, '\n', 1); - if(q == nil){ - abort(); - } - Bterm(d); - if(strcmp(q, "performance") == 0) - continue; - name = smprint("%s/%d/digest", srvmount, c); - d = Bopen(name, OREAD); - if(d == nil) - sysfatal("getchildren: %s: %r", name); - free(name); - q = Brdstr(d, '\n', 1); - if(q == nil){ - Bterm(d); - continue; - } - addchild(strdup(p), q); - Bterm(d); - } - Bterm(b); -} - -void -doplay(char *onum){ - char *name, *p, *q; - Biobuf *b; - int m; - - name = smprint("%s/%s/files", srvmount, onum); - b = Bopen(name, OREAD); - if(b == nil) -abort();// sysfatal("doplay: %s: %r", name); - while(p = Brdline(b, '\n')){ - m = Blinelen(b); - assert(p[m-1] == '\n'); - p[m-1] = '\0'; - q = strchr(p, ' '); - if(q == nil) - sysfatal("doplay: %s: format", name); - *q++ = '\0'; - sendplaylist(strdup(q), strdup(p)); - } - free(name); - Bterm(b); -} - -void -fillbrowsetop(char *onum) -{ - char *name, *p; - Biobuf *b; - int m; - - name = smprint("%s/%s/parentage", srvmount, onum); - b = Bopen(name, OREAD); - if(b == nil) -abort();// sysfatal("gettopwin: %s: %r", name); - free(name); - while(p = Brdline(b, '\n')){ - m = Blinelen(b); - assert(p[m-1] == '\n'); - p[m-1] = '\0'; - addparent(p); - } - Bterm(b); -} - -void -fillplaytext(char *onum) -{ - char *name, *p; - Biobuf *b; - int m; - - name = smprint("%s/%s/parentage", srvmount, onum); - b = Bopen(name, OREAD); - if(b == nil) - sysfatal("fillplaytext: %s: %r", name); - free(name); - while(p = Brdline(b, '\n')){ - m = Blinelen(b); - assert(p[m-1] == '\n'); - p[m-1] = '\0'; - addplaytext(p); - } - Bterm(b); -} - -char * -getoneliner(char *onum) -{ - char *name, *p; - Biobuf *b; - - name = smprint("%s/%s/miniparentage", srvmount, onum); - b = Bopen(name, OREAD); - if(b == nil) - sysfatal("gettopwin: %s: %r", name); - free(name); - p = Brdstr(b, '\n', 1); - Bterm(b); - return p; -} - -char * -getparent(char *onum) -{ - char *name, *p; - Biobuf *b; - - name = smprint("%s/%s/parent", srvmount, onum); - b = Bopen(name, OREAD); - if(b == nil) -abort();// sysfatal("gettopwin: %s: %r", name); - free(name); - p = Brdstr(b, '\n', 1); - Bterm(b); - return p; -} diff --git a/sys/src/games/music/jukebox/client.h b/sys/src/games/music/jukebox/client.h deleted file mode 100644 index b0a6e828d..000000000 --- a/sys/src/games/music/jukebox/client.h +++ /dev/null @@ -1,10 +0,0 @@ -char* getroot(void); -void doplay(char*); -void fillbrowsebot(char*); -void fillbrowsetop(char*); -void fillplaytext(char*); -void addchild(char*, char*); -void addparent(char*); -char *getoneliner(char*); -char *getparent(char*); -void addplaytext(char*); diff --git a/sys/src/games/music/jukebox/colors.c b/sys/src/games/music/jukebox/colors.c deleted file mode 100644 index 8ab8dc7b6..000000000 --- a/sys/src/games/music/jukebox/colors.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "colors.h" - -Font *boldfont; -Font *romanfont; - -Image *background; -Image *bordercolor; -Image *black; -Image *blue; -Image *darkblue; -Image *darkgrey; -Image *darkgreen; -Image *darkmagenta; -Image *green; -Image *grey; -Image *high; -Image *land; -Image *lightblue; -Image *lightgreen; -Image *lightgrey; -Image *lightmagenta; -Image *low; -Image *magenta; -Image *oceanblue; -Image *pale; -Image *paleblue; -Image *paleyellow; -Image *red; -Image *sea; -Image *white; -Image *yellow; - -static ulong -rgba(ulong rgba) -{ - uchar r, g, b, a; - - a = rgba & 0xff; - b = (rgba >>= 8) & 0xff; - g = (rgba >>= 8) & 0xff; - r = (rgba >> 8) & 0xff; - rgba = ((r * a / 0xff) & 0xff); - rgba = ((g * a / 0xff) & 0xff) | (rgba << 8); - rgba = ((b * a / 0xff) & 0xff) | (rgba << 8); - rgba = (a & 0xff) | (rgba << 8); - return rgba; -} - -void -colorinit(char *roman, char *bold) -{ - Rectangle r = Rect(0, 0, 1, 1); - - white = display->white; - black = display->black; - blue = allocimage(display, r, screen->chan, 1, rgba(0x0000ffff)); - darkblue = allocimage(display, r, screen->chan, 1, rgba(0x0000ccff)); - darkgrey = allocimage(display, r, screen->chan, 1, rgba(0x444444ff)); - darkgreen = allocimage(display, r, screen->chan, 1, rgba(0x008800ff)); - darkmagenta = allocimage(display, r, screen->chan, 1, rgba(0x770077ff)); - green = allocimage(display, r, screen->chan, 1, rgba(0x00ff00ff)); - grey = allocimage(display, r, screen->chan, 1, rgba(0x888888ff)); - high = allocimage(display, r, screen->chan, 1, rgba(0x00ccccff)); - land = allocimage(display, r, screen->chan, 1, rgba(0xe0ffe0ff)); - lightblue = allocimage(display, r, screen->chan, 1, rgba(0x88ccccff)); - lightgreen = allocimage(display, r, screen->chan, 1, rgba(0xaaffaaff)); - lightgrey = allocimage(display, r, screen->chan, 1, rgba(0xddddddff)); - lightmagenta = allocimage(display, r, screen->chan, 1, rgba(0xff88ffff)); - low = allocimage(display, r, screen->chan, 1, rgba(0xddddddff)); - magenta = allocimage(display, r, screen->chan, 1, rgba(0xbb00bbff)); - oceanblue = allocimage(display, r, screen->chan, 1, rgba(0x93ddddff)); - pale = allocimage(display, r, screen->chan, 1, rgba(0xffffaaff)); - paleblue = allocimage(display, r, screen->chan, 1, rgba(0xddffffff)); - paleyellow = allocimage(display, r, screen->chan, 1, rgba(0xeeee9eff)); - red = allocimage(display, r, screen->chan, 1, rgba(0xff0000ff)); - sea = allocimage(display, r, screen->chan, 1, rgba(0xe0e0ffff)); - yellow = allocimage(display, r, screen->chan, 1, rgba(0xffff00ff)); - background = sea; - bordercolor = darkgreen; - - namectlimage(background, "background"); - namectlimage(bordercolor, "border"); - namectlimage(black, "black"); - namectlimage(blue, "blue"); - namectlimage(darkblue, "darkblue"); - namectlimage(darkgreen, "darkgreen"); - namectlimage(darkmagenta, "darkmagenta"); - namectlimage(green, "green"); - namectlimage(grey, "grey"); - namectlimage(high, "high"); - namectlimage(land, "land"); - namectlimage(lightblue, "lightblue"); - namectlimage(lightgreen, "lightgreen"); - namectlimage(lightgrey, "lightgrey"); - namectlimage(lightmagenta, "lightmagenta"); - namectlimage(low, "low"); - namectlimage(magenta, "magenta"); - namectlimage(oceanblue, "oceanblue"); - namectlimage(pale, "pale"); - namectlimage(paleblue, "paleblue"); - namectlimage(paleyellow, "paleyellow"); - namectlimage(red, "red"); - namectlimage(sea, "sea"); - namectlimage(white, "white"); - namectlimage(yellow, "yellow"); - - if ((romanfont = openfont(display, roman)) == nil) - sysfatal("openfont %s: %r", roman); - namectlfont(romanfont, "romanfont"); - if ((boldfont = openfont(display, bold)) == nil) - sysfatal("openfont %s: %r", bold); - namectlfont(boldfont, "boldfont"); -} diff --git a/sys/src/games/music/jukebox/colors.h b/sys/src/games/music/jukebox/colors.h deleted file mode 100644 index 933a981fc..000000000 --- a/sys/src/games/music/jukebox/colors.h +++ /dev/null @@ -1,30 +0,0 @@ -extern Image *background; -extern Image *bordercolor; -extern Image *black; -extern Image *blue; -extern Image *darkblue; -extern Image *darkgrey; -extern Image *darkgreen; -extern Image *darkmagenta; -extern Image *green; -extern Image *grey; -extern Image *high; -extern Image *land; -extern Image *lightblue; -extern Image *lightgreen; -extern Image *lightgrey; -extern Image *lightmagenta; -extern Image *low; -extern Image *magenta; -extern Image *oceanblue; -extern Image *pale; -extern Image *paleblue; -extern Image *paleyellow; -extern Image *red; -extern Image *sea; -extern Image *white; -extern Image *yellow; - -extern Font *romanfont, *boldfont; - -void colorinit(char*, char*); diff --git a/sys/src/games/music/jukebox/mk.dep b/sys/src/games/music/jukebox/mk.dep deleted file mode 100644 index a9036dba1..000000000 --- a/sys/src/games/music/jukebox/mk.dep +++ /dev/null @@ -1,4 +0,0 @@ -client.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/bio.h client.h playlist.h -colors.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/draw.h /sys/include/keyboard.h /sys/include/mouse.h /sys/include/control.h colors.h -music.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/draw.h /sys/include/keyboard.h /sys/include/mouse.h /sys/include/control.h colors.h client.h playlist.h -playlist.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/draw.h /sys/include/keyboard.h /sys/include/mouse.h /sys/include/control.h playlist.h diff --git a/sys/src/games/music/jukebox/mkfile b/sys/src/games/music/jukebox/mkfile deleted file mode 100644 index 36e868620..000000000 --- a/sys/src/games/music/jukebox/mkfile +++ /dev/null @@ -1,16 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include "colors.h" -#include "client.h" -#include "playlist.h" -#include "../debug.h" - -int debug = 0; //DBGSERVER|DBGPUMP|DBGSTATE|DBGPICKLE|DBGPLAY; - -char usage[] = "Usage: %s [-d mask] [-t] [-w]\n"; - -typedef struct But { - char *name; - Control *ctl; -} But; - -typedef struct Simpleitem { - char *address; - char *data; -} Simpleitem; - -typedef struct Multiitem { - char *address; - int ndata; - char **data; -} Multiitem; - -enum { - WinBrowse, - WinPlay, - WinPlaylist, - WinError, - Topselect = 0x7fffffff, - - Browsedepth = 63, -}; - -typedef enum { - PlayIdle, - PlayStart, - Playing, - PlayPause, -} Playstate; - -typedef enum { - User, - Troot, - Rroot, - Tchildren, - Rchildren, - Tparent, - Rparent, - Tinfo, - Rinfo, - Tparentage, - Rparentage, - Tplay, - Rplay, -} Srvstate; - -enum { - Exitbutton, - Pausebutton, - Playbutton, - Stopbutton, - Prevbutton, - Nextbutton, - Rootbutton, - Deletebutton, - Helpbutton, - Volume, - Browsetopwin, - Browsebotwin, - Browsebotscr, - Playevent, - Playlistwin, - Nalt, -}; - -But buts[] = { - [Exitbutton] = {"skull", nil}, - [Pausebutton] = {"pause", nil}, - [Playbutton] = {"play", nil}, - [Stopbutton] = {"stop", nil}, - [Prevbutton] = {"prev", nil}, - [Nextbutton] = {"next", nil}, - [Rootbutton] = {"root", nil}, - [Deletebutton] = {"trash", nil}, - [Helpbutton] = {"question", nil}, -}; - -struct tab { - char *tabname; - char *winname; - Control *tab; - Control *win; -} tabs[4] = { - [WinBrowse] = {"Browse", "browsewin", nil, nil}, - [WinPlay] = {"Playing", "playwin", nil, nil}, - [WinPlaylist] = {"Playlist", "listwin", nil, nil}, - [WinError] = {"Errors", "errorwin", nil, nil}, -}; - -char *helptext[] = { - "Buttons, left to right:", - " Exit: exit jukebox", - " Pause: pause/resume playback", - " Play: play selection in Playlist", - " Stop: stop playback", - " Prev: play previous item in Playlist", - " Next: play next item in Playlist", - " Root: browse to root of database tree", - " Delete: empty Playlist, reread database", - " Help: show this window", - "", - "Browse window: (click tab to bring forward)", - " Top window displays current item", - " Bottom window displays selectable subitems", - " Mouse commands:", - " Left: selected subitem becomes current", - " Right: parent of current item becomes current", - " Middle: add item or subitem to Playlist", - "", - "Playing window", - " Displays item currently playing", - "", - "Playlist window", - " Displays contents of Playlist", - " Mouse commands:", - " Left: select item", - " (then click the play button)", - "", - "Error window", - " Displays error messages received from player", - " (e.g., can't open file)", - nil, -}; - -struct Browsestack { - char *onum; - int scrollpos; -} browsestack[Browsedepth]; -int browsesp; /* browse stack pointer */ -int browseline; /* current browse position */ - -Control *vol; -Control *browsetopwin; -Control *browsebotwin; -Control *playlistwin; -Control *errortext; -Control *browsetopscr; -Control *browsebotscr; - -Playstate playstate; - -ulong playingbuts = 1<name); - if((fd = open(file, OREAD)) < 0) - sysfatal("open: %s: %r", file); - mask = readimage(display, fd, 0); - close(fd); - butwid = Dx(mask->r); - butht = Dy(mask->r); - b->ctl = createbutton(cs, b->name); - chanprint(cs->ctl, "%q align center", b->name); - chanprint(cs->ctl, "%q border 0", b->name); - - img = allocimage(display, mask->r, screen->chan, 0, 0xe0e0ffff); - draw(img, img->r, darkgreen, mask, mask->r.min); - sprint(str, "%s.active", b->name); - namectlimage(img, str); - - img = allocimage(display, mask->r, screen->chan, 0, 0xe0e0ffff); - draw(img, img->r, lightblue, mask, mask->r.min); - sprint(str, "%s.passive", b->name); - namectlimage(img, str); - - chanprint(cs->ctl, "%q image %q", b->name, str); - sprint(str, "%s.mask", b->name); - namectlimage(mask, str); - chanprint(cs->ctl, "%q mask %q", b->name, str); - chanprint(cs->ctl, "%q light red", b->name); - chanprint(cs->ctl, "%q size %d %d %d %d", b->name, butwid, butht, butwid, butht); - } -} - -void -activatebuttons(ulong mask) -{ // mask bit i corresponds to buts[i]; - ulong bit; - But *b; - static char str[40]; - int i; - - for(i = 0; i < nelem(buts); i++){ - b = &buts[i]; - bit = 1 << i; - if((mask & bit) && (activebuts & bit) == 0){ - // button was `deactive' - activate(b->ctl); - activebuts |= bit; - sprint(str, "%s.active", b->name); - chanprint(cs->ctl, "%q image %q", b->name, str); - chanprint(cs->ctl, "%q show", b->name); - } - } -} - -void -deactivatebuttons(ulong mask) -{ // mask bit i corresponds with buts[i]; - ulong bit; - But *b; - static char str[40]; - int i; - - for(i = 0; i < nelem(buts); i++){ - b = &buts[i]; - bit = 1 << i; - if((mask & bit) && (activebuts & bit)){ - // button was active - deactivate(b->ctl); - activebuts &= ~bit; - sprint(str, "%s.passive", b->name); - chanprint(cs->ctl, "%q image %q", b->name, str); - chanprint(cs->ctl, "%q show", b->name); - } - } -} - -void -resizecontrolset(Controlset *){ - static Point pol[3]; - char *p; - - if(getwindow(display, Refbackup) < 0) - sysfatal("getwindow"); - draw(screen, screen->r, bordercolor, nil, screen->r.min); - if(!resizeready) - return; -#ifndef REPLACESEMANTICS - if(vol1img) - chanprint(cs->ctl, "volume image darkgreen"); - if(vol2img) - chanprint(cs->ctl, "volume indicatorcolor red"); - chanprint(cs->ctl, "wholewin size"); - chanprint(cs->ctl, "wholewin rect %R", screen->r); - - chanprint(cs->ctl, "sync"); - p = recvp(cs->data); - if(strcmp(p, "sync")) - sysfatal("huh?"); - free(p); - - if(vol1img){ - freectlimage("volume.img"); - freeimage(vol1img); - } - if(vol2img){ - freectlimage("indicator.img"); - freeimage(vol2img); - } - vol1img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); - vol2img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); - pol[0] = Pt(vol->rect.min.x, vol->rect.max.y); - pol[1] = Pt(vol->rect.max.x, vol->rect.min.y); - pol[2] = vol->rect.max; - fillpoly(vol1img, pol, 3, 0, darkgreen, ZP); - fillpoly(vol2img, pol, 3, 0, red, ZP); - namectlimage(vol1img, "volume.img"); - namectlimage(vol2img, "indicator.img"); - chanprint(cs->ctl, "volume image volume.img"); - chanprint(cs->ctl, "volume indicatorcolor indicator.img"); -#else - chanprint(cs->ctl, "wholewin size"); - chanprint(cs->ctl, "wholewin rect %R", screen->r); - - chanprint(cs->ctl, "sync"); - p = recvp(cs->data); - if(strcmp(p, "sync")) - sysfatal("huh?"); - free(p); - - new1img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); - new2img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); - pol[0] = Pt(vol->rect.min.x, vol->rect.max.y); - pol[1] = Pt(vol->rect.max.x, vol->rect.min.y); - pol[2] = vol->rect.max; - fillpoly(new1img, pol, 3, 0, darkgreen, ZP); - fillpoly(new2img, pol, 3, 0, red, ZP); - namectlimage(new1img, "volume.img"); - namectlimage(new2img, "indicator.img"); - if(vol1img) - freeimage(vol1img); - else - chanprint(cs->ctl, "volume image volume.img"); - if(vol2img) - freeimage(vol2img); - else - chanprint(cs->ctl, "volume indicatorcolor indicator.img"); - vol1img = new1img; - vol2img = new2img; -#endif - chanprint(cs->ctl, "browsetopscr vis '%d'", - Dy(controlcalled("browsetopscr")->rect)/romanfont->height); - chanprint(cs->ctl, "browsebotscr vis '%d'", - Dy(controlcalled("browsebotscr")->rect)/romanfont->height); - chanprint(cs->ctl, "playscr vis '%d'", - Dy(controlcalled("playscr")->rect)/romanfont->height); - chanprint(cs->ctl, "playlistscr vis '%d'", - Dy(controlcalled("playlistscr")->rect)/romanfont->height); - chanprint(cs->ctl, "wholewin show"); -} - -void -maketab(void) -{ - int i; - - tabht = boldfont->height + 1 + borderwidth; - - createtab(cs, "tabs"); - - for(i = 0; i < nelem(tabs); i++){ - tabs[i].tab = createtextbutton(cs, tabs[i].tabname); - chanprint(cs->ctl, "%q size %d %d %d %d", tabs[i].tab->name, - stringwidth(boldfont, tabs[i].tabname), tabht, 1024, tabht); - chanprint(cs->ctl, "%q align uppercenter", tabs[i].tab->name); - chanprint(cs->ctl, "%q font boldfont", tabs[i].tab->name); - chanprint(cs->ctl, "%q image background", tabs[i].tab->name); - chanprint(cs->ctl, "%q light background", tabs[i].tab->name); - chanprint(cs->ctl, "%q pressedtextcolor red", tabs[i].tab->name); - chanprint(cs->ctl, "%q textcolor darkgreen", tabs[i].tab->name); - chanprint(cs->ctl, "%q mask transparent", tabs[i].tab->name); - chanprint(cs->ctl, "%q text %q", tabs[i].tab->name, tabs[i].tabname); - - chanprint(cs->ctl, "tabs add %s %s", tabs[i].tabname, tabs[i].winname); - } - - chanprint(cs->ctl, "tabs separation %d", 2); - chanprint(cs->ctl, "tabs image background"); - chanprint(cs->ctl, "tabs value 0"); -} - -void -makeplaycontrols(void) -{ - int w; - Control *playscr; - - w = stringwidth(romanfont, "Roll over Beethoven"); - playscr = createslider(cs, "playscr"); - chanprint(cs->ctl, "playscr size 12, 24, 12, 1024"); - createtext(cs, "playtext"); - chanprint(cs->ctl, "playtext size %d %d %d %d", - w, 5*romanfont->height, 2048, 1024); - - chanprint(cs->ctl, "playscr format '%%s: playtext topline %%d'"); - controlwire(playscr, "event", cs->ctl); - - tabs[WinPlay].win = createrow(cs, tabs[WinPlay].winname); - chanprint(cs->ctl, "%q add playscr playtext", tabs[WinPlay].win->name); -} - -void -makebrowsecontrols(void) -{ - int w; - - w = stringwidth(romanfont, "Roll over Beethoven"); - browsetopscr = createslider(cs, "browsetopscr"); - chanprint(cs->ctl, "browsetopscr size 12, 24, 12, %d", 12*romanfont->height); - browsetopwin = createtext(cs, "browsetopwin"); - chanprint(cs->ctl, "browsetopwin size %d %d %d %d", - w, 3*romanfont->height, 2048, 12*romanfont->height); - createrow(cs, "browsetop"); - chanprint(cs->ctl, "browsetop add browsetopscr browsetopwin"); - - browsebotscr = createslider(cs, "browsebotscr"); - chanprint(cs->ctl, "browsebotscr size 12, 24, 12, 1024"); - browsebotwin = createtext(cs, "browsebotwin"); - chanprint(cs->ctl, "browsebotwin size %d %d %d %d", - w, 3*romanfont->height, 2048, 1024); - createrow(cs, "browsebot"); - chanprint(cs->ctl, "browsebot add browsebotscr browsebotwin"); - - chanprint(cs->ctl, "browsetopscr format '%%s: browsetopwin topline %%d'"); - controlwire(browsetopscr, "event", cs->ctl); -// chanprint(cs->ctl, "browsebotscr format '%%s: browsebotwin topline %%d'"); -// controlwire(browsebotscr, "event", cs->ctl); - - tabs[WinBrowse].win = createcolumn(cs, tabs[WinBrowse].winname); - chanprint(cs->ctl, "%q add browsetop browsebot", tabs[WinBrowse].win->name); -} - -void -makeplaylistcontrols(void) -{ - int w; - Control *playlistscr; - - w = stringwidth(romanfont, "Roll over Beethoven"); - playlistscr = createslider(cs, "playlistscr"); - chanprint(cs->ctl, "playlistscr size 12, 24, 12, 1024"); - playlistwin = createtext(cs, "playlistwin"); - chanprint(cs->ctl, "playlistwin size %d %d %d %d", - w, 5*romanfont->height, 2048, 1024); -// chanprint(cs->ctl, "playlistwin selectmode multi"); - - chanprint(cs->ctl, "playlistscr format '%%s: playlistwin topline %%d'"); - controlwire(playlistscr, "event", cs->ctl); - - tabs[WinPlaylist].win = createrow(cs, tabs[WinPlaylist].winname); - chanprint(cs->ctl, "%q add playlistscr playlistwin", tabs[WinPlaylist].win->name); -} - -void -makeerrorcontrols(void) -{ - int w; - Control *errorscr; - - w = stringwidth(romanfont, "Roll over Beethoven"); - errorscr = createslider(cs, "errorscr"); - chanprint(cs->ctl, "errorscr size 12, 24, 12, 1024"); - errortext = createtext(cs, "errortext"); - chanprint(cs->ctl, "errortext size %d %d %d %d", - w, 5*romanfont->height, 2048, 1024); - chanprint(cs->ctl, "errortext selectmode multi"); - - chanprint(cs->ctl, "errorscr format '%%s: errortext topline %%d'"); - controlwire(errorscr, "event", cs->ctl); - - tabs[WinError].win = createrow(cs, tabs[WinError].winname); - chanprint(cs->ctl, "%q add errorscr errortext", tabs[WinError].win->name); -} - -void -makecontrols(void) -{ - int i; - - cs = newcontrolset(screen, nil, nil, nil); - - // make shared buttons - readbuts(); - - vol = createslider(cs, "volume"); - chanprint(cs->ctl, "volume size %d %d %d %d", 2*butwid, butht, 2048, butht); - chanprint(cs->ctl, "volume absolute 1"); - chanprint(cs->ctl, "volume indicatorcolor red"); - chanprint(cs->ctl, "volume max 100"); - chanprint(cs->ctl, "volume orient hor"); - chanprint(cs->ctl, "volume clamp low 1"); - chanprint(cs->ctl, "volume clamp high 0"); - chanprint(cs->ctl, "volume format '%%s volume %%d'"); - - createrow(cs, "buttonrow"); - for(i = 0; i < nelem(buts); i++) - chanprint(cs->ctl, "buttonrow add %s", buts[i].name); - chanprint(cs->ctl, "buttonrow add volume"); - chanprint(cs->ctl, "buttonrow separation %d", borderwidth); - chanprint(cs->ctl, "buttonrow image darkgreen"); - - makebrowsecontrols(); - makeplaycontrols(); - makeplaylistcontrols(); - makeerrorcontrols(); - - maketab(); - - chanprint(cs->ctl, "%q image background", "text slider"); - chanprint(cs->ctl, "text font romanfont"); - chanprint(cs->ctl, "slider indicatorcolor darkgreen"); - chanprint(cs->ctl, "row separation %d", borderwidth); - chanprint(cs->ctl, "row image darkgreen"); - chanprint(cs->ctl, "column separation %d", 2); - chanprint(cs->ctl, "column image darkgreen"); - - createcolumn(cs, "wholewin"); - chanprint(cs->ctl, "wholewin separation %d", borderwidth); - chanprint(cs->ctl, "wholewin add buttonrow tabs"); - chanprint(cs->ctl, "wholewin image darkgreen"); - chanprint(cs->ctl, "%q image darkgreen", "column row"); -} - -void -makewindow(int dx, int dy, int wflag){ - int mountfd, fd, n; - static char aname[128]; - static char rio[128] = "/mnt/term"; - char *args[6]; - - if(wflag){ - /* find out screen size */ - fd = open("/mnt/wsys/screen", OREAD); - if(fd >= 0 && read(fd, aname, 60) == 60){ - aname[60] = '\0'; - n = tokenize(aname, args, nelem(args)); - if(n != 5) - fprint(2, "Not an image: /mnt/wsys/screen\n"); - else{ - n = atoi(args[3]) - atoi(args[1]); - if(n <= 0 || n > 2048) - fprint(2, "/mnt/wsys/screen very wide: %d\n", n); - else - if(n < dx) dx = n-1; - n = atoi(args[4]) - atoi(args[2]); - if(n <= 0 || n > 2048) - fprint(2, "/mnt/wsys/screen very high: %d\n", n); - else - if(n < dy) dy = n-1; - } - close(fd); - } - n = 0; - if((fd = open("/env/wsys", OREAD)) < 0){ - n = strlen(rio); - fd = open("/mnt/term/env/wsys", OREAD); - if(fd < 0) - sysfatal("/env/wsys"); - } - if(read(fd, rio+n, sizeof(rio)-n-1) <= 0) - sysfatal("/env/wsys"); - mountfd = open(rio, ORDWR); - if(mountfd < 0) - sysfatal("open %s: %r", rio); - snprint(aname, sizeof aname, "new -dx %d -dy %d", dx, dy); - rfork(RFNAMEG); - if(mount(mountfd, -1, "/mnt/wsys", MREPL, aname) < 0) - sysfatal("mount: %r"); - if(bind("/mnt/wsys", "/dev", MBEFORE) < 0) - sysfatal("mount: %r"); - } - - if(initdraw(nil, nil, "music") < 0) - sysfatal("initdraw: %r"); - - initcontrols(); - if(dx <= 320) - colorinit("/lib/font/bit/lucidasans/unicode.6.font", - "/lib/font/bit/lucidasans/boldunicode.8.font"); - else - colorinit("/lib/font/bit/lucidasans/unicode.8.font", - "/lib/font/bit/lucidasans/boldunicode.10.font"); - makecontrols(); - resizeready = 1; - - resizecontrolset(cs); - if(debug & DBGCONTROL) - fprint(2, "resize done\n"); -} - -void -setparent(char *addr) -{ - int i; - - if(parent.address) - free(parent.address); - parent.address = strdup(addr); - for(i = 0; i < parent.ndata; i++) - if(parent.data[i]) - free(parent.data[i]); - parent.ndata = 0; - if(parent.data){ - free(parent.data); - parent.data = nil; - } - chanprint(cs->ctl, "browsetopwin clear"); - chanprint(cs->ctl, "browsetopscr max 0"); - chanprint(cs->ctl, "browsetopscr value 0"); -} - -void -addparent(char *str) -{ - parent.data = realloc(parent.data, (parent.ndata+1)*sizeof(char*)); - parent.data[parent.ndata] = strdup(str); - parent.ndata++; - chanprint(cs->ctl, "browsetopwin accumulate %q", str); - chanprint(cs->ctl, "browsetopscr max %d", parent.ndata); -} - -void -clearchildren(void) -{ - int i; - - for(i = 0; i < nchildren; i++){ - if(children[i].address) - free(children[i].address); - if(children[i].data) - free(children[i].data); - } - nchildren= 0; - chanprint(cs->ctl, "browsebotwin clear"); - chanprint(cs->ctl, "browsebotwin topline 0"); - chanprint(cs->ctl, "browsebotscr max 0"); - chanprint(cs->ctl, "browsebotscr value 0"); - selected = -1; -} - -void -addchild(char *addr, char *data) -{ - children[nchildren].address = addr; - children[nchildren].data = data; - nchildren++; - chanprint(cs->ctl, "browsebotwin accumulate %q", data); - chanprint(cs->ctl, "browsebotscr max %d", nchildren); -} - -static void -playlistselect(int n) -{ - if(playlist.selected >= 0 && playlist.selected < playlist.nentries){ - chanprint(cs->ctl, "playlistwin select %d 0", playlist.selected); - deactivatebuttons(1<= playlist.nentries) - return; - activatebuttons(1<ctl, "playlistwin select %d 1", n); - if(n >= 0 && n <= playlist.nentries - Dy(playlistwin->rect)/romanfont->height) - n--; - else - n = playlist.nentries - Dy(playlistwin->rect)/romanfont->height + 1; - if(n < 0) n = 0; - if(n < playlist.nentries){ - chanprint(cs->ctl, "playlistwin topline %d", n); - chanprint(cs->ctl, "playlistscr value %d", n); - } - chanprint(cs->ctl, "playlist show"); -} - -void -updateplaylist(int trunc) -{ - char *s; - int fd; - - while(cs->ctl->s - cs->ctl->n < cs->ctl->s/4) - sleep(100); - if(trunc){ - playlistselect(-1); - chanprint(cs->ctl, "playlistwin clear"); - chanprint(cs->ctl, "playlistwin topline 0"); - chanprint(cs->ctl, "playlistscr max 0"); - chanprint(cs->ctl, "playlistscr value 0"); - deactivatebuttons(1<ctl, "playlistwin show"); - chanprint(cs->ctl, "playlistscr show"); - s = smprint("%s/ctl", srvmount); - if((fd = open(s, OWRITE)) >= 0){ - fprint(fd, "reread"); - close(fd); - } - free(s); - return; - } - if(playlist.entry[playlist.nentries].onum){ - s = getoneliner(playlist.entry[playlist.nentries].onum); - chanprint(cs->ctl, "playlistwin accumulate %q", s); - free(s); - }else - chanprint(cs->ctl, "playlistwin accumulate %q", playlist.entry[playlist.nentries].file); - playlist.nentries++; - chanprint(cs->ctl, "playlistscr max %d", playlist.nentries); - if(playlist.selected == playlist.nentries - 1) - playlistselect(playlist.selected); - activatebuttons(1<ctl, "playlistscr show"); - chanprint(cs->ctl, "playlistwin show"); -} - -void -browseto(char *onum, int line) -{ - onum = strdup(onum); - setparent(onum); - clearchildren(); - fillbrowsetop(onum); - chanprint(cs->ctl, "browsetop show"); - fillbrowsebot(onum); - if(line){ - chanprint(cs->ctl, "browsebotscr value %d", line); - chanprint(cs->ctl, "browsebotwin topline %d", line); - } - chanprint(cs->ctl, "browsebot show"); - free(onum); -} - -void -browsedown(char *onum) -{ - if(browsesp == 0){ - /* Make room for an entry by deleting the last */ - free(browsestack[Browsedepth-1].onum); - memmove(browsestack + 1, browsestack, (Browsedepth-1) * sizeof(browsestack[0])); - browsesp++; - } - /* Store current position in current stack frame */ - assert(browsesp > 0 && browsesp < Browsedepth); - browsestack[browsesp].onum = strdup(parent.address); - browsestack[browsesp].scrollpos = browseline; - browsesp--; - browseline = 0; - if(browsestack[browsesp].onum && strcmp(browsestack[browsesp].onum, onum) == 0) - browseline = browsestack[browsesp].scrollpos; - browseto(onum, browseline); -} - -void -browseup(char *onum) -{ - if(browsesp == Browsedepth){ - /* Make room for an entry by deleting the first */ - free(browsestack[0].onum); - memmove(browsestack, browsestack + 1, browsesp * sizeof(browsestack[0])); - browsesp--; - } - /* Store current position in current stack frame */ - assert(browsesp >= 0 && browsesp < Browsedepth); - browsestack[browsesp].onum = strdup(parent.address); - browsestack[browsesp].scrollpos = browseline; - browsesp++; - browseline = 0; - if(browsestack[browsesp].onum && strcmp(browsestack[browsesp].onum, onum) == 0) - browseline = browsestack[browsesp].scrollpos; - browseto(onum, browseline); -} - -void -addplaytext(char *s) -{ - chanprint(cs->ctl, "playtext accumulate %q", s); -} - -void -work(void) -{ - static char *eventstr, *args[64], *s; - static char buf[4096]; - int a, n, i; - Alt alts[] = { - [Exitbutton] = {buts[Exitbutton].ctl->event, &eventstr, CHANRCV}, - [Pausebutton] = {buts[Pausebutton].ctl->event, &eventstr, CHANRCV}, - [Playbutton] = {buts[Playbutton].ctl->event, &eventstr, CHANRCV}, - [Stopbutton] = {buts[Stopbutton].ctl->event, &eventstr, CHANRCV}, - [Prevbutton] = {buts[Prevbutton].ctl->event, &eventstr, CHANRCV}, - [Nextbutton] = {buts[Nextbutton].ctl->event, &eventstr, CHANRCV}, - [Rootbutton] = {buts[Rootbutton].ctl->event, &eventstr, CHANRCV}, - [Deletebutton] = {buts[Deletebutton].ctl->event, &eventstr, CHANRCV}, - [Helpbutton] = {buts[Helpbutton].ctl->event, &eventstr, CHANRCV}, - [Volume] = {vol->event, &eventstr, CHANRCV}, - [Browsetopwin] = {browsetopwin->event, &eventstr, CHANRCV}, - [Browsebotwin] = {browsebotwin->event, &eventstr, CHANRCV}, - [Browsebotscr] = {browsebotscr->event, &eventstr, CHANRCV}, - [Playevent] = {playevent, &eventstr, CHANRCV}, - [Playlistwin] = {playlistwin->event, &eventstr, CHANRCV}, - [Nalt] = {nil, nil, CHANEND} - }; - - activate(vol); - activate(controlcalled("tabs")); - activatebuttons(1 << Exitbutton | 1 << Rootbutton | 1 << Helpbutton); - - root = getroot(); - setparent(root); - clearchildren(); - addparent("Root"); - chanprint(cs->ctl, "browsetop show"); - fillbrowsebot(root); - chanprint(cs->ctl, "browsebot show"); - - eventstr = nil; - selected = -1; - - for(;;){ - a = alt(alts); - if(debug & DBGCONTROL) - fprint(2, "Event: %s\n", eventstr); - n = tokenize(eventstr, args, nelem(args)); - switch(a){ - default: - sysfatal("Illegal event %d in work", a); - case Volume: - if(n != 3 || strcmp(args[0], "volume") || strcmp(args[1], "volume")) - sysfatal("Bad Volume event[%d]: %s %s", n, args[0], args[1]); - setvolume(args[2]); - break; - case Exitbutton: - return; - case Pausebutton: - if(n != 3 || strcmp(args[0], "pause:") || strcmp(args[1], "value")) - sysfatal("Bad Pausebutton event[%d]: %s %s", n, args[0], args[1]); - if(strcmp(args[2], "0") == 0) - fprint(playctlfd, "resume"); - else - fprint(playctlfd, "pause"); - break; - case Playbutton: - if(n != 3 || strcmp(args[0], "play:") || strcmp(args[1], "value")) - sysfatal("Bad Playbutton event[%d]: %s %s", n, args[0], args[1]); - if(playlist.selected >= 0){ - fprint(playctlfd, "play %d", playlist.selected); - }else - fprint(playctlfd, "play"); - break; - case Stopbutton: - if(n != 3 || strcmp(args[0], "stop:") || strcmp(args[1], "value")) - sysfatal("Bad Stopbutton event[%d]: %s %s", n, args[0], args[1]); - if(strcmp(args[2], "0") == 0) - chanprint(cs->ctl, "%q value 1", buts[Stopbutton].ctl->name); - fprint(playctlfd, "stop"); - break; - case Prevbutton: - if(n != 3 || strcmp(args[0], "prev:") || strcmp(args[1], "value")) - sysfatal("Bad Prevbutton event[%d]: %s %s", n, args[0], args[1]); - if(strcmp(args[2], "0") == 0) - break; - chanprint(cs->ctl, "%q value 0", buts[Prevbutton].ctl->name); - fprint(playctlfd, "skip -1"); - break; - case Nextbutton: - if(n != 3 || strcmp(args[0], "next:") || strcmp(args[1], "value")) - sysfatal("Bad Nextbutton event[%d]: %s %s", n, args[0], args[1]); - if(strcmp(args[2], "0") == 0) - break; - chanprint(cs->ctl, "%q value 0", buts[Nextbutton].ctl->name); - fprint(playctlfd, "skip 1"); - break; - case Playlistwin: - if(debug & (DBGCONTROL|DBGPLAY)) - fprint(2, "Playlistevent: %s %s\n", args[0], args[1]); - if(n != 4 || strcmp(args[0], "playlistwin:") || strcmp(args[1], "select")) - sysfatal("Bad Playlistwin event[%d]: %s %s", n, args[0], args[1]); - n = atoi(args[2]); - if(n < 0 || n >= playlist.nentries) - sysfatal("Selecting line %d of %d", n, playlist.nentries); - if(playlist.selected >= 0 && playlist.selected < playlist.nentries){ - chanprint(cs->ctl, "playlistwin select %d 0", playlist.selected); - chanprint(cs->ctl, "playlistwin show"); - } - playlist.selected = -1; - deactivatebuttons(1<ctl, "%q value 0", buts[Rootbutton].ctl->name); - setparent(root); - clearchildren(); - addparent("Root"); - chanprint(cs->ctl, "browsetop show"); - fillbrowsebot(root); - chanprint(cs->ctl, "browsebot show"); - break; - case Deletebutton: - if(n != 3 || strcmp(args[0], "trash:") || strcmp(args[1], "value")) - sysfatal("Bad Deletebutton event[%d]: %s %s", n, args[0], args[1]); - if(strcmp(args[2], "0") == 0) - break; - chanprint(cs->ctl, "%q value 0", buts[Deletebutton].ctl->name); - sendplaylist(nil, nil); - break; - case Helpbutton: - chanprint(cs->ctl, "%q value 0", buts[Helpbutton].ctl->name); - if(errorlines > 0){ - chanprint(cs->ctl, "errortext clear"); - chanprint(cs->ctl, "errortext topline 0"); - chanprint(cs->ctl, "errorscr max 0"); - chanprint(cs->ctl, "errorscr value 0"); - } - if(errorlines >= 0){ - for(i = 0; helptext[i]; i++) - chanprint(cs->ctl, "errortext accumulate %q", helptext[i]); - chanprint(cs->ctl, "errorscr max %d", i); - } - chanprint(cs->ctl, "errortext topline 0"); - chanprint(cs->ctl, "errorscr value 0"); - errorlines = -1; - chanprint(cs->ctl, "tabs value %d", WinError); - break; - case Browsetopwin: - if(n != 4 || strcmp(args[0], "browsetopwin:") || strcmp(args[1], "select")) - sysfatal("Bad Browsetopwin event[%d]: %s %s", n, args[0], args[1]); - if(strcmp(args[3], "0") == 0) - break; - chanprint(cs->ctl, "browsetopwin select %s 0", args[2]); - selected = -1; - if(strcmp(args[3], "2") == 0) - doplay(parent.address); - else if(strcmp(args[3], "4") == 0){ - s = getparent(parent.address); - browsedown(s); - } - break; - case Browsebotwin: - if(n != 4 || strcmp(args[0], "browsebotwin:") || strcmp(args[1], "select")) - sysfatal("Bad Browsebotwin event[%d]: %s %s", n, args[0], args[1]); - n = atoi(args[2]); - if(n < 0 || n >= nchildren) - sysfatal("Selection out of range: %d [%d]", n, nchildren); - if(strcmp(args[3], "0") == 0){ - selected = -1; - break; - } - if(n < 0) - break; - chanprint(cs->ctl, "browsebotwin select %d 0", n); - selected = n; - if(selected >= nchildren) - sysfatal("Select out of range: %d [0⋯%d)", selected, nchildren); - if(strcmp(args[3], "1") == 0){ - browseup(children[selected].address); - }else if(strcmp(args[3], "2") == 0) - doplay(children[selected].address); - else if(strcmp(args[3], "4") == 0) - browsedown(getparent(parent.address)); - break; - case Browsebotscr: - browseline = atoi(args[2]); - chanprint(cs->ctl, "browsebotwin topline %d", browseline); - break; - case Playevent: - if(n < 3 || strcmp(args[0], "playctlproc:")) - sysfatal("Bad Playevent event[%d]: %s", n, args[0]); - if(debug & (DBGCONTROL|DBGPLAY)) - fprint(2, "Playevent: %s %s\n", args[1], args[2]); - if(strcmp(args[1], "error") ==0){ - if(n != 4){ - fprint(2, "Playevent: %s: arg count: %d\n", args[1], n); - break; - } - if(errorlines < 0){ - chanprint(cs->ctl, "errortext clear"); - chanprint(cs->ctl, "errortext topline 0"); - chanprint(cs->ctl, "errorscr max 0"); - chanprint(cs->ctl, "errorscr value 0"); - errorlines = 0; - } - n = errorlines; - chanprint(cs->ctl, "errortext accumulate %q", args[3]); - chanprint(cs->ctl, "errorscr max %d", ++errorlines); - if(n >= 0 && n <= errorlines - Dy(errortext->rect)/romanfont->height) - n--; - else - n = errorlines - Dy(errortext->rect)/romanfont->height + 1; - if(n < 0) n = 0; - if(n < errorlines){ - chanprint(cs->ctl, "errortext topline %d", n); - chanprint(cs->ctl, "errorscr value %d", n); - } - chanprint(cs->ctl, "tabs value %d", WinError); - }else if(strcmp(args[1], "play") ==0){ - chanprint(cs->ctl, "%q value 1", buts[Playbutton].ctl->name); - chanprint(cs->ctl, "%q value 0", buts[Stopbutton].ctl->name); - chanprint(cs->ctl, "%q value 0", buts[Pausebutton].ctl->name); - playlistselect(strtoul(args[2], nil, 0)); - chanprint(cs->ctl, "playtext clear"); - chanprint(cs->ctl, "playtext topline 0"); - chanprint(cs->ctl, "playscr max 0"); - chanprint(cs->ctl, "playscr value 0"); - playstate = Playing; - activatebuttons(playingbuts); - qlock(&playlist); - if(playlist.selected < playlist.nentries){ - fillplaytext(playlist.entry[playlist.selected].onum); - chanprint(cs->ctl, "playscr max %d", n); - } - qunlock(&playlist); - chanprint(cs->ctl, "playwin show"); - }else if(strcmp(args[1], "stop") ==0){ - chanprint(cs->ctl, "%q value 0", buts[Playbutton].ctl->name); - chanprint(cs->ctl, "%q value 1", buts[Stopbutton].ctl->name); - chanprint(cs->ctl, "%q value 0", buts[Pausebutton].ctl->name); - playlistselect(strtoul(args[2], nil, 0)); - chanprint(cs->ctl, "%q show", tabs[WinPlaylist].winname); - playstate = PlayIdle; - deactivatebuttons(playingbuts); - }else if(strcmp(args[1], "pause") ==0){ - activatebuttons(playingbuts); - chanprint(cs->ctl, "%q value 1", buts[Playbutton].ctl->name); - chanprint(cs->ctl, "%q value 0", buts[Stopbutton].ctl->name); - if(playstate == PlayPause){ - chanprint(cs->ctl, "%q value 0", buts[Pausebutton].ctl->name); - playstate = Playing; - }else{ - chanprint(cs->ctl, "%q value 1", buts[Pausebutton].ctl->name); - playstate = PlayPause; - } - }else if(strcmp(args[1], "exits") ==0){ - threadexits("exitevent"); - }else{ - fprint(2, "Unknown play event:"); - for(i=0; ictl, 8192); - - work(); - - closecontrolset(cs); - threadexitsall(nil); -} diff --git a/sys/src/games/music/jukebox/playlist.c b/sys/src/games/music/jukebox/playlist.c deleted file mode 100644 index a7a536025..000000000 --- a/sys/src/games/music/jukebox/playlist.c +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "playlist.h" -#include "../debug.h" - -char *playlistfile = "/mnt/playlist"; -char *playctlfile = "/mnt/playctl"; -char *playvolfile = "/mnt/playvol"; -char *volumefile = "/dev/audioctl"; - -Playlist playlist; -int playctlfd; - -void -playlistproc(void*) -{ - int fd, m, n, nf; - static char buf[8192+1]; - char *p, *q, *fields[4]; - - threadsetname("playlistproc"); - fd = open(playlistfile, OREAD); - if(fd < 0) - sysfatal("%s: %r", playlistfile); - p = buf; - n = 0; - if(debug & DBGPLAY) - fprint(2, "playlistproc: starting\n"); - for(;;){ - m = read(fd, buf+n, sizeof buf - 1 - n); - if(m == 0){ - if(debug & DBGPLAY) - fprint(2, "playlistproc: empty read\n"); - continue; - } - if(m < 0){ - rerrstr(buf, sizeof(buf)); - if(strcmp(buf, "reading past eof")) - sysfatal("%s: %r", playlistfile); - for(n = 0; n < playlist.nentries; n++){ - free(playlist.entry[n].file); - free(playlist.entry[n].onum); - } - if(debug & DBGPLAY) - fprint(2, "playlistproc: trunc\n"); - playlist.nentries = 0; - free(playlist.entry); - playlist.entry = nil; - updateplaylist(1); - seek(fd, 0, 0); - p = buf; - n = 0; - continue; - } - if(debug & DBGPLAY) - fprint(2, "playlistproc: read %d bytes\n", m); - n += m; - p[n] = '\0'; - while(q = strchr(p, '\n')){ - *q = 0; - nf = tokenize(p, fields, nelem(fields)); - if(nf){ - playlist.entry = realloc(playlist.entry, (playlist.nentries+1)*sizeof playlist.entry[0]); - if(playlist.entry == nil) - sysfatal("realloc %r"); - playlist.entry[playlist.nentries].file = strdup(fields[0]); - if(nf > 1){ - playlist.entry[playlist.nentries].onum = strdup(fields[1]); - if(debug & DBGPLAY) - fprint(2, "playlistproc: [%d]: %q %q\n", playlist.nentries, - playlist.entry[playlist.nentries].file, - playlist.entry[playlist.nentries].onum); - }else{ - playlist.entry[playlist.nentries].onum = nil; - if(debug & DBGPLAY) - fprint(2, "playlistproc: [%d]: %q nil\n", playlist.nentries, - playlist.entry[playlist.nentries].file); - } - updateplaylist(0); // this will also update nentries - } - q++; - n -= q-p; - p = q; - } - if(n) - memmove(buf, p, n); - p = buf; - } -} - -void -sendplaylist(char *file, char *onum) -{ - static int fd = -1; - char *b; - - if(file == nil){ - if(fd >= 0) - close(fd); - fd = open(playlistfile, OWRITE|OTRUNC); - if(fd < 0) - sysfatal("%s: truncate: %r", playlistfile); - return; - } - if(fd < 0){ - fd = open(playlistfile, OWRITE); - if(fd < 0) - sysfatal("%s: %r", playlistfile); - } - b = smprint("%q %q\n", file, onum); - if(debug & DBGPLAY) - fprint(2, "sendplaylist @%s@\n", b); - if(write(fd , b, strlen(b)) != strlen(b)) - sysfatal("sendplaylist: %r"); -} - -void -playctlproc(void*a) -{ - int fd, n, nf; - static char buf[512+1]; - char *fields[4]; - Channel *chan; - - threadsetname("playctlproc"); - chan = a; - fd = open(playctlfile, OREAD); - if(fd < 0) - sysfatal("%s: %r", playctlfile); - for(;;){ - n = read(fd, buf, sizeof buf -1); - if(n == 0) - continue; - if(n < 0) - sysfatal("%s: %r", playctlfile); - buf[n] = '\0'; - nf = tokenize(buf, fields, nelem(fields)); - if(nf == 0) - continue; - switch (nf){ - default: - sysfatal("playctlproc: [%d]: %s", nf, fields[0]); - case 3: - chanprint(chan, "playctlproc: error %lud %q", strtoul(fields[1], nil, 0), fields[2]); - if(strcmp(fields[0], "error") == 0) - break; - // fall through - case 2: - chanprint(chan, "playctlproc: %s %lud", fields[0], strtoul(fields[1], nil, 0)); - } - } -} - -void -sendplayctl(char *fmt, ...) -{ - va_list arg; - static int fd = -1; - - va_start(arg, fmt); - if(debug & DBGPLAY){ - fprint(2, "sendplayctl: fmt=%s: ", fmt); - fprint(2, fmt, arg); - fprint(2, "\n"); - } - fprint(fd, fmt, arg); - va_end(arg); -} - -void -setvolume(char *volume) -{ - static int fd; - - if(fd == 0){ - fd = open(playvolfile, OWRITE); - if(fd < 0){ - fprint(2, "can't open %s, (%r) opening %s instead\n", playvolfile, "/dev/volume"); - if((fd = open("/dev/volume", OWRITE)) < 0){ - fprint(2, "setvolume: open: %r\n"); - return; - } - } - } - if(fd < 0) - return; - fprint(fd, "volume %s", volume); -} - -void -volumeproc(void *arg) -{ - int fd, n, nf, nnf, i, nlines; - static char buf[1024]; - char *lines[32]; - char *fields[8]; - char *subfields[8]; - Channel *ctl; - int volume, minvolume, maxvolume, nvolume; - - ctl = arg; - threadsetname("volumeproc"); - fd = open(volumefile, OREAD); - if(fd < 0){ - fprint(2, "%s: %r\n", volumefile); - threadexits(nil); - } - for(;;){ - n = read(fd, buf, sizeof buf -1); - if(n == 0) - continue; - if(n < 0){ - fprint(2, "volumeproc: read: %r\n"); - threadexits("volumeproc"); - } - buf[n] = '\0'; - nlines = getfields(buf, lines, nelem(lines), 1, "\n"); - for(i = 0; i < nlines; i++){ - nf = tokenize(lines[i], fields, nelem(fields)); - if(nf == 0) - continue; - if(nf != 6 || strcmp(fields[0], "volume") || strcmp(fields[1], "out")) - continue; - minvolume = strtol(fields[3], nil, 0); - maxvolume = strtol(fields[4], nil, 0); - if(minvolume >= maxvolume) - continue; - nnf = tokenize(fields[2], subfields, nelem(subfields)); - if(nnf <= 0 || nnf > 8){ - fprint(2, "volume format error\n"); - threadexits(nil); - } - volume = 0; - nvolume = 0; - for(i = 0; i < nnf; i++){ - volume += strtol(subfields[i], nil, 0); - nvolume++; - } - volume /= nvolume; - volume = 100*(volume - minvolume)/(maxvolume-minvolume); - chanprint(ctl, "volume value %d", volume); - } - } -} - -void -playvolproc(void*a) -{ - int fd, n, nf, volume, nvolume, i; - static char buf[256+1]; - static errors; - char *fields[3], *subfields[9]; - Channel *chan; - - threadsetname("playvolproc"); - chan = a; - fd = open(playvolfile, OREAD); - if(fd < 0) - sysfatal("%s: %r", playvolfile); - for(;;){ - n = read(fd, buf, sizeof buf -1); - if(n == 0) - continue; - if(n < 0){ - fprint(2, "%s: %r\n", playvolfile); - threadexits("playvolproc"); - } - buf[n] = '\0'; - if(debug) fprint(2, "volumestring: %s\n", buf); - nf = tokenize(buf, fields, nelem(fields)); - if(nf == 0) - continue; - if(nf != 2 || strcmp(fields[0], "volume")){ - fprint(2, "playvolproc: [%d]: %s\n", nf, fields[0]); - if(errors++ > 32) - threadexits("playvolproc"); - continue; - } - nvolume = tokenize(fields[1], subfields, nelem(subfields)); - if(nvolume <= 0 || nvolume > 8){ - fprint(2, "volume format error\n"); - if(errors++ > 32) - threadexits("playvolproc"); - continue; - } - volume = 0; - for(i = 0; i < nvolume; i++) - volume += strtol(subfields[i], nil, 0); - volume /= nvolume; - chanprint(chan, "volume value %d", volume); - } -} diff --git a/sys/src/games/music/jukebox/playlist.h b/sys/src/games/music/jukebox/playlist.h deleted file mode 100644 index ce3746ee3..000000000 --- a/sys/src/games/music/jukebox/playlist.h +++ /dev/null @@ -1,26 +0,0 @@ - -typedef struct Playlistentry { - char *file; - char *onum; -} Playlistentry; - -typedef struct Playlist { - QLock; - int nentries; - int selected; - Playlistentry *entry; -} Playlist; - -extern Playlist playlist; -extern char *playctlfile; -extern char *srvmount; -extern int playctlfd; - -void playctlproc(void*a); -void playlistproc(void*); -void playvolproc(void*a); -void sendplayctl(char *fmt, ...); -void sendplaylist(char*, char*); -void setvolume(char *volume); -void updateplaylist(int); -void volumeproc(void *arg); diff --git a/sys/src/games/music/jukefs/catset.c b/sys/src/games/music/jukefs/catset.c deleted file mode 100644 index 2886a9aab..000000000 --- a/sys/src/games/music/jukefs/catset.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include - -#include "object.h" -#include "catset.h" - -static int debug = 0; - -int -catsetneeded(int v) -{ - return (v / 8) + 1; -} - -static void -catsetprint(int f, Catset*cs) -{ - int i; - fprint(2, "(%p %d:", cs->bitpiece, cs->nbitpiece); - for (i = 0; i < cs->nbitpiece; i++) - fprint(f, "[%d]=%x", i, cs->bitpiece[i]); - fprint(2, ")"); -} - -void -catsetrealloc(Catset *cs, int sz) -{ - if (debug) fprint(2, "catsetrealloc %p %d (%p %d)", cs, sz, cs->bitpiece, cs->nbitpiece); - if (sz > cs->nbitpiece) { - cs->bitpiece = realloc(cs->bitpiece, sz*sizeof(uchar)); - memset(cs->bitpiece + cs->nbitpiece, 0, sz - cs->nbitpiece); - cs->nbitpiece = sz; - } - if (debug) fprint(2, " -> %p %d\n", cs->bitpiece, cs->nbitpiece); -} - -void -catsetfree(Catset *cs) -{ - free(cs->bitpiece); - cs->bitpiece = 0; - cs->nbitpiece = 0; -} - -void -catsetinit(Catset*cs, int v) -{ - int n; - - n = catsetneeded(v); - if (debug) fprint(2, "catsetinit %p %d -> ", cs, v); - catsetrealloc(cs, n); - catsetset(cs, v); - if (debug) catsetprint(2, cs); - if (debug) fprint(2, "\n"); -} - -void -catsetcopy(Catset*dst, Catset*src) -{ - if (debug) fprint(2, "catsetcopy %p %p ", dst, src); - if (debug) catsetprint(2, dst); - if (debug) fprint(2, " "); - if (debug) catsetprint(2, src); - if (dst->nbitpiece < src->nbitpiece) - catsetrealloc(dst, src->nbitpiece); - else - memset(dst->bitpiece, 0, dst->nbitpiece); - memcpy(dst->bitpiece, src->bitpiece, src->nbitpiece); - dst->nbitpiece = src->nbitpiece; - if (debug) fprint(2, "-> "); - if (debug) catsetprint(2, dst); - if (debug) fprint(2, "\n"); -} - -void -catsetset(Catset*cs, int v) -{ - int p = v / 8; - int b = v % 8; - if (debug) fprint(2, "catsetset %p %d ", cs, v); - if (debug) catsetprint(2, cs); - cs->bitpiece[p] = 1 << b; - if (debug) fprint(2, "-> "); - if (debug) catsetprint(2, cs); - if (debug) fprint(2, "\n"); -} - -int -catsetisset(Catset*cs) -{ - int i; - - if (debug) fprint(2, "catsetisset %p ", cs); - if (debug) catsetprint(2, cs); - if (debug) fprint(2, "\n"); - for (i =0; i < cs->nbitpiece; i++) { - if (cs->bitpiece[i]) - return 1; - } - return 0; -} - -void -catsetorset(Catset*dst, Catset*src) -{ - int i; - - if (debug) fprint(2, "catsetorset %p %p ", dst, src); - if (debug) catsetprint(2, dst); - if (debug) fprint(2, " "); - if (debug) catsetprint(2, src); - if (src->nbitpiece > dst->nbitpiece) - catsetrealloc(dst, src->nbitpiece); - - for (i =0; i < src->nbitpiece; i++) { - dst->bitpiece[i] |= src->bitpiece[i]; - } - if (debug) fprint(2, "-> "); - if (debug) catsetprint(2, dst); - if (debug) fprint(2, "\n"); -} - -int -catseteq(Catset*cs1, Catset*cs2) -{ - int i; - Catset *css, * csl; - - if (debug) fprint(2, "catseteq %p %p ", cs1, cs2); - if (debug) catsetprint(2, cs1); - if (debug) fprint(2, " "); - if (debug) catsetprint(2, cs2); - if (debug) fprint(2, "\n"); - if (cs1->nbitpiece > cs2->nbitpiece) { - csl = cs1; - css = cs2; - } else { - csl = cs2; - css = cs1; - } - for (i =0; i < css->nbitpiece; i++) { - if (css->bitpiece[i] != csl->bitpiece[i]) - return 0; - } - for (i = css->nbitpiece; i < csl->nbitpiece; i++) { - if (csl->bitpiece[i]) - return 0; - } - return 1; -} diff --git a/sys/src/games/music/jukefs/catset.h b/sys/src/games/music/jukefs/catset.h deleted file mode 100644 index 3d01b85b2..000000000 --- a/sys/src/games/music/jukefs/catset.h +++ /dev/null @@ -1,8 +0,0 @@ -void catsetrealloc(Catset*, int); -void catsetinit(Catset*, int); -void catsetfree(Catset*t); -void catsetcopy(Catset*, Catset*); -void catsetset(Catset*, int); -int catsetisset(Catset*); -void catsetorset(Catset*, Catset*); -int catseteq(Catset*, Catset*); diff --git a/sys/src/games/music/jukefs/fs.c b/sys/src/games/music/jukefs/fs.c deleted file mode 100644 index 744096520..000000000 --- a/sys/src/games/music/jukefs/fs.c +++ /dev/null @@ -1,747 +0,0 @@ -#include -#include -#include -#include -#include -#include "object.h" - -extern int debug; - -extern int mfd[]; - -enum { - DbgFs = 0x1000 -}; - -typedef struct Fid Fid; - -enum { - Busy = 0x01, - Open = 0x02, - Endf = 0x04, -}; - -struct Fid -{ - QLock; - Qid qid; - int fid; - ushort flags; - vlong offset; // offset of data[0] - Fid *next; -}; - -Fcall thdr; -Fcall rhdr; - -enum { - /* Files making up an object */ - Qchildren, /* Each of these must be in dirtab */ - Qdigest, - Qfiles, - Qfulltext, - Qkey, - Qminiparentage, - Qparent, - Qparentage, - Qtext, - Qtype, - - /* Other files */ - Qtop, /* Must follow Qtype */ - Qclassical, - Qdir, - Qroot, - Qctl, -}; - -#define PATH(id, f) (((id)<<8) | (f)) -#define FILE(p) ((p) & 0xff) -#define NUM(p) ((p) >> 8) - -char *dirtab[] = -{ -[Qchildren] "children", -[Qdigest] "digest", -[Qdir] ".", -[Qfiles] "files", -[Qfulltext] "fulltext", -[Qkey] "key", -[Qminiparentage]"miniparentage", -[Qparent] "parent", -[Qparentage] "parentage", -[Qtext] "text", -[Qtype] "type", -[Qtop] nil, -}; - -char *rflush(Fid*), *rauth(Fid*), - *rattach(Fid*), *rwalk(Fid*), - *ropen(Fid*), *rcreate(Fid*), - *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*), - *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*), - *rversion(Fid*); - -char *(*fcalls[])(Fid*) = { - [Tflush] rflush, - [Tversion] rversion, - [Tauth] rauth, - [Tattach] rattach, - [Twalk] rwalk, - [Topen] ropen, - [Tcreate] rcreate, - [Tread] rread, - [Twrite] rwrite, - [Tclunk] rclunk, - [Tremove] rremove, - [Tstat] rstat, - [Twstat] rwstat, -}; - -int messagesize = 8*1024+IOHDRSZ; -uchar mdata[8*1024+IOHDRSZ]; -uchar mbuf[8*1024+IOHDRSZ]; -char bigbuf[1<<23]; /* 8 megabytes */ -Fid *fids; - -char Eperm[] = "permission denied"; -char Enotdir[] = "not a directory"; -char Enoauth[] = "no authentication required"; -char Enotexist[] = "file does not exist"; -char Einuse[] = "file in use"; -char Eexist[] = "file exists"; -char Enotowner[] = "not owner"; -char Eisopen[] = "file already open for I/O"; -char Excl[] = "exclusive use file already open"; -char Ename[] = "illegal name"; -char Ebadctl[] = "unknown control message"; - -Fid *newfid(int fid); - -static int -lookup(char *cmd, char *list[]) -{ - int i; - - for (i = 0; list[i] != nil; i++) - if (strcmp(cmd, list[i]) == 0) - return i; - return -1; -} - -char* -rversion(Fid *) -{ - Fid *f; - - if(thdr.msize < 256) - return "max messagesize too small"; - if(thdr.msize < messagesize) - messagesize = thdr.msize; - rhdr.msize = messagesize; - if(strncmp(thdr.version, "9P2000", 6) != 0) - return "unknown 9P version"; - else - rhdr.version = "9P2000"; - for(f = fids; f; f = f->next) - if(f->flags & Busy) - rclunk(f); - return nil; -} - -char* -rauth(Fid*) -{ - return Enoauth; -} - -char* -rflush(Fid *) -{ - return 0; -} - -char* -rattach(Fid *f) -{ - f->flags |= Busy; - f->qid.type = QTDIR; - f->qid.vers = 0; - f->qid.path = PATH(0, Qtop); - rhdr.qid = f->qid; - return 0; -} - -static Fid* -doclone(Fid *f, int nfid) -{ - Fid *nf; - - nf = newfid(nfid); - nf->qid = f->qid; - if(nf->flags & Busy) - return nil; - nf->flags |= Busy; - nf->flags &= ~Open; - return nf; -} - -char* -dowalk(Fid *f, char *name) -{ - int t, n, m; - char *rv, *p; - - t = FILE(f->qid.path); /* Type */ - - rv = Enotexist; - - if(strcmp(name, ".") == 0 && f->qid.type == QTDIR) - return nil; - if(strcmp(name, "..") == 0){ - switch(t){ - case Qtop: - case Qclassical: - f->qid.path = PATH(0, Qtop); - f->qid.type = QTDIR; - f->qid.vers = 0; - rv = nil; - break; - case Qdir: - case Qroot: - f->qid.path = PATH(0, Qclassical); - f->qid.type = QTDIR; - f->qid.vers = 0; - rv = nil; - break; - } - return rv; - } - switch(t){ - case Qtop: - /* Contains classical */ - if(strcmp(name, "juke") == 0){ - f->qid.path = PATH(root->tabno, Qclassical); - f->qid.type = QTDIR; - f->qid.vers = 0; - rv = nil; - break; - } - break; - case Qclassical: - /* main dir, contains `root' and object dirs */ - if(strcmp(name, "root") == 0){ - f->qid.path = PATH(root->tabno, Qroot); - f->qid.type = QTDIR; - f->qid.vers = 0; - rv = nil; - break; - } - if(strcmp(name, "ctl") == 0){ - f->qid.path = PATH(root->tabno, Qctl); - f->qid.type = QTFILE; - f->qid.vers = 0; - rv = nil; - break; - } - n = strtol(name, &p, 0); - if(*p) - break; /* Not a number */ - if(n < 0 || n >= notab) - break; /* Outside range */ - if(otab[n] == nil) - break; /* Not in object table */ - f->qid.path = PATH(n, Qdir); - f->qid.type = QTDIR; - f->qid.vers = 0; - rv = nil; - break; - case Qroot: /* Root of the object hierarchy */ - case Qdir: /* Object directory */ - if((m = lookup(name, dirtab)) < 0) - break; - n = NUM(f->qid.path); - f->qid.path = PATH(n, m); - f->qid.type = QTFILE; - f->qid.vers = 0; - rv = nil; - break; - } - return rv; -} - -char* -rwalk(Fid *f) -{ - Fid *nf; - char *rv; - int i; - - if(f->flags & Open) - return Eisopen; - - rhdr.nwqid = 0; - nf = nil; - - /* clone if requested */ - if(thdr.newfid != thdr.fid){ - nf = doclone(f, thdr.newfid); - if(nf == nil) - return "new fid in use"; - f = nf; - } - - /* if it's just a clone, return */ - if(thdr.nwname == 0 && nf != nil) - return nil; - - /* walk each element */ - rv = nil; - for(i = 0; i < thdr.nwname; i++){ - rv = dowalk(f, thdr.wname[i]); - if(rv != nil){ - if(nf != nil) - rclunk(nf); - break; - } - rhdr.wqid[i] = f->qid; - } - rhdr.nwqid = i; - - /* we only error out if no walk */ - if(i > 0) - rv = nil; - - return rv; -} - -char * -ropen(Fid *f) -{ - if(f->flags & Open) - return Eisopen; - - if(thdr.mode != OREAD && FILE(f->qid.path) != Qctl) - return Eperm; - rhdr.iounit = 0; - rhdr.qid = f->qid; - f->flags |= Open; - f->flags &= ~Endf; - return nil; -} - -char * -rcreate(Fid*) -{ - return Eperm; -} - -static long -fileinfo(char *buf, int bufsize, int onum, int t) -{ - long n; - - n = 0; - switch(t){ - case Qchildren: - n = printchildren(buf, bufsize, otab[onum]); - break; - case Qdigest: - n = printdigest(buf, bufsize, otab[onum]); - break; - case Qfulltext: - n = printfulltext(buf, bufsize, otab[onum]); - break; - case Qkey: - n = printkey(buf, bufsize, otab[onum]); - break; - case Qparent: - n = printparent(buf, bufsize, otab[onum]); - break; - case Qtext: - n = printtext(buf, bufsize, otab[onum]); - break; - case Qtype: - n = printtype(buf, bufsize, otab[onum]); - break; - case Qfiles: - n = printfiles(buf, bufsize, otab[onum]); - break; - case Qparentage: - n = printparentage(buf, bufsize, otab[onum]); - break; - case Qminiparentage: - n = printminiparentage(buf, bufsize, otab[onum]); - break; - default: - sysfatal("rread: %d", t); - } - return n; -} - -static void -mkstat(Dir *d, int n, int t) -{ - static char buf[16]; - - d->uid = user; - d->gid = user; - d->muid = user; - d->qid.vers = 0; - d->qid.type = QTFILE; - d->type = 0; - d->dev = 0; - d->atime = time(0); - d->mtime = d->atime; - switch(t){ - case Qtop: - d->name = "."; - d->mode = DMDIR|0555; - d->atime = d->mtime = time(0); - d->length = 0; - d->qid.path = PATH(0, Qtop); - d->qid.type = QTDIR; - break; - case Qclassical: - d->name = "juke"; - d->mode = DMDIR|0555; - d->atime = d->mtime = time(0); - d->length = 0; - d->qid.path = PATH(0, Qclassical); - d->qid.type = QTDIR; - break; - case Qdir: - snprint(buf, sizeof buf, "%d", n); - d->name = buf; - d->mode = DMDIR|0555; - d->length = 0; - d->qid.path = PATH(n, Qdir); - d->qid.type = QTDIR; - break; - case Qroot: - d->name = "root"; - d->mode = DMDIR|0555; - d->length = 0; - d->qid.path = PATH(0, Qroot); - d->qid.type = QTDIR; - break; - case Qctl: - d->name = "ctl"; - d->mode = 0666; - d->length = 0; - d->qid.path = PATH(0, Qctl); - break; - d->name = "ctl"; - d->mode = 0666; - d->length = 0; - d->qid.path = PATH(0, Qctl); - break; - case Qchildren: - case Qdigest: - case Qfiles: - case Qfulltext: - case Qkey: - case Qminiparentage: - case Qparent: - case Qparentage: - case Qtext: - case Qtype: - d->name = dirtab[t]; - d->mode = 0444; - d->length = fileinfo(bigbuf, sizeof bigbuf, n, t); - d->qid.path = PATH(n, t); - break; - default: - sysfatal("mkstat: %d", t); - } -} - -int -readtopdir(Fid*, uchar *buf, long off, int cnt, int blen) -{ - int m, n; - Dir d; - - n = 0; - mkstat(&d, 0, Qclassical); - m = convD2M(&d, &buf[n], blen); - if(off <= 0){ - if(m <= BIT16SZ || m > cnt) - return n; - n += m; - } - return n; -} - -int -readclasdir(Fid*, uchar *buf, long off, int cnt, int blen) -{ - int m, n; - long pos; - Dir d; - Fid *fid; - - n = 0; - pos = 0; - mkstat(&d, 0, Qctl); - m = convD2M(&d, &buf[n], blen); - if(off <= pos){ - if(m <= BIT16SZ || m > cnt) - return 0; - n += m; - cnt -= m; - } - pos += m; - mkstat(&d, 0, Qroot); - m = convD2M(&d, &buf[n], blen); - if(off <= pos){ - if(m <= BIT16SZ || m > cnt) - return n; - n += m; - cnt -= m; - } - pos += m; - for (fid = fids; fid; fid = fid->next){ - if(FILE(fid->qid.path) != Qdir) - continue; - mkstat(&d, NUM(fid->qid.path), Qdir); - m = convD2M(&d, &buf[n], blen-n); - if(off <= pos){ - if(m <= BIT16SZ || m > cnt) - break; - n += m; - cnt -= m; - } - pos += m; - } - return n; -} - -int -readdir(Fid *f, uchar *buf, long off, int cnt, int blen) -{ - int i, m, n; - long pos; - Dir d; - - n = 0; - pos = 0; - for (i = 0; i < Qtop; i++){ - mkstat(&d, NUM(f->qid.path), i); - m = convD2M(&d, &buf[n], blen-n); - if(off <= pos){ - if(m <= BIT16SZ || m > cnt) - break; - n += m; - cnt -= m; - } - pos += m; - } - return n; -} - -void -readbuf(char *s, long n) -{ - rhdr.count = thdr.count; - if(thdr.offset >= n){ - rhdr.count = 0; - return; - } - if(thdr.offset+rhdr.count > n) - rhdr.count = n - thdr.offset; - rhdr.data = s + thdr.offset; -} - -char* -rread(Fid *f) -{ - long off; - int n, cnt, t; - - rhdr.count = 0; - off = thdr.offset; - cnt = thdr.count; - - if(cnt > messagesize - IOHDRSZ) - cnt = messagesize - IOHDRSZ; - - rhdr.data = (char*)mbuf; - - n = 0; - t = FILE(f->qid.path); - switch(t){ - case Qtop: - n = readtopdir(f, mbuf, off, cnt, messagesize - IOHDRSZ); - rhdr.count = n; - return nil; - case Qclassical: - n = readclasdir(f, mbuf, off, cnt, messagesize - IOHDRSZ); - rhdr.count = n; - return nil; - case Qdir: - case Qroot: - n = readdir(f, mbuf, off, cnt, messagesize - IOHDRSZ); - rhdr.count = n; - return nil; - case Qctl: - snprint(bigbuf, sizeof bigbuf, "%d objects in tree (%d holes)\n", notab, hotab); - break; - case Qchildren: - case Qdigest: - case Qfiles: - case Qfulltext: - case Qkey: - case Qminiparentage: - case Qparent: - case Qparentage: - case Qtext: - case Qtype: - n = fileinfo(bigbuf, sizeof bigbuf, NUM(f->qid.path), t); - break; - default: - sysfatal("rread: %d", t); - } - readbuf(bigbuf, n); - return nil; -} - -char* -rwrite(Fid *f) -{ - long cnt; - char *p; - - if(FILE(f->qid.path) != Qctl) - return Eperm; - rhdr.count = 0; - cnt = thdr.count; - if(p = strchr(thdr.data, '\n')) - *p = '\0'; - if(strncmp(thdr.data, "quit", cnt) == 0) - threadexitsall(nil); - else if(strncmp(thdr.data, "reread", cnt) == 0) - reread(); - else - return "illegal command"; - rhdr.count = thdr.count; - return nil; -} - -char * -rclunk(Fid *f) -{ - f->flags &= ~(Open|Busy); - return 0; -} - -char * -rremove(Fid *) -{ - return Eperm; -} - -char * -rstat(Fid *f) -{ - Dir d; - - mkstat(&d, NUM(f->qid.path), FILE(f->qid.path)); - rhdr.nstat = convD2M(&d, mbuf, messagesize - IOHDRSZ); - rhdr.stat = mbuf; - return 0; -} - -char * -rwstat(Fid*) -{ - return Eperm; -} - -Fid * -newfid(int fid) -{ - Fid *f, *ff; - - ff = nil; - for(f = fids; f; f = f->next) - if(f->fid == fid){ - return f; - }else if(ff == nil && (f->flags & Busy) == 0) - ff = f; - if(ff == nil){ - ff = malloc(sizeof *ff); - if (ff == nil) - sysfatal("malloc: %r"); - memset(ff, 0, sizeof *ff); - ff->next = fids; - fids = ff; - } - ff->fid = fid; - return ff; -} - -void -io(void *) -{ - char *err; - int n; - extern int p[]; - Fid *f; - - threadsetname("file server"); - close(p[1]); - while((n = read9pmsg(mfd[0], mdata, messagesize)) != 0){ - if(n < 0){ - char e[32]; - rerrstr(e, sizeof e); - if (strcmp(e, "interrupted") == 0){ - if (debug & DbgFs) fprint(2, "read9pmsg interrupted\n"); - continue; - } - sysfatal("mount read: %s", e); - } - if(convM2S(mdata, n, &thdr) != n) - sysfatal("convM2S format error: %r"); - - if(debug & DbgFs) - fprint(2, "io:<-%F\n", &thdr); - - rhdr.data = (char*)mbuf; - - if(!fcalls[thdr.type]) - err = "bad fcall type"; - else { - f = newfid(thdr.fid); - err = (*fcalls[thdr.type])(f); - } - if(err){ - rhdr.type = Rerror; - rhdr.ename = err; - }else{ - rhdr.type = thdr.type + 1; - rhdr.fid = thdr.fid; - } - rhdr.tag = thdr.tag; - if(debug & DbgFs) - fprint(2, "io:->%F\n", &rhdr);/**/ - n = convS2M(&rhdr, mdata, messagesize); - if(write(mfd[1], mdata, n) != n) - sysfatal("mount write"); - } - threadexitsall("die yankee pig dog"); -} - -int -newid(void) -{ - int rv; - static int id; - static Lock idlock; - - lock(&idlock); - rv = ++id; - unlock(&idlock); - - return rv; -} diff --git a/sys/src/games/music/jukefs/mk.dep b/sys/src/games/music/jukefs/mk.dep deleted file mode 100644 index 9772b03d8..000000000 --- a/sys/src/games/music/jukefs/mk.dep +++ /dev/null @@ -1,6 +0,0 @@ -catset.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/bio.h object.h catset.h -fs.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/bio.h /sys/include/fcall.h object.h -parse.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/bio.h /sys/include/ctype.h object.h catset.h parse.h -print.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/ctype.h /sys/include/bio.h /sys/include/thread.h object.h parse.h catset.h -search.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/bio.h /sys/include/thread.h object.h parse.h search.h -server.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/bio.h /sys/include/fcall.h object.h parse.h print.h catset.h diff --git a/sys/src/games/music/jukefs/mkfile b/sys/src/games/music/jukefs/mkfile deleted file mode 100644 index 57c34c193..000000000 --- a/sys/src/games/music/jukefs/mkfile +++ /dev/null @@ -1,18 +0,0 @@ - -#include -#include -#include -#include -#include "object.h" -#include "catset.h" -#include "parse.h" - -#define MAXTOKEN 1024 - -Biobuf *f; -static int str; -char *file; - -Token tokenlistinit[] = { - { "category", Obj, Category , "music" , {nil,0}}, - { "cddata", Obj, Cddata , nil , {nil,0}}, - { "command", Obj, Cmd , nil , {nil,0}}, - { "file", Obj, File , "file" , {nil,0}}, - { "include", Obj, Include , nil , {nil,0}}, - { "key", Obj, Key , nil , {nil,0}}, - { "lyrics", Obj, Lyrics , "lyrics" , {nil,0}}, - { "part", Obj, Part , "title" , {nil,0}}, - { "path", Obj, Path , nil , {nil,0}}, - { "performance",Obj, Performance , "artist" , {nil,0}}, - { "recording", Obj, Recording , "title" , {nil,0}}, - { "root", Obj, Root , nil , {nil,0}}, - { "search", Obj, Search , nil , {nil,0}}, - { "soloists", Obj, Soloists , "artist" , {nil,0}}, - { "time", Obj, Time , "time" , {nil,0}}, - { "track", Obj, Track , "title" , {nil,0}}, - { "work", Obj, Work , "title" , {nil,0}}, -}; -Token *tokenlist; -int ntoken = nelem(tokenlistinit); -int catnr = 0; - -Cmdlist cmdlist[] = { - { Sort, "sort" }, - { Enum, "number" }, - { 0x00, 0 }, -}; - -static char *curtext; - -void -inittokenlist(void) -{ - int i; - - ntoken = nelem(tokenlistinit); - tokenlist = malloc(sizeof(tokenlistinit)); - memmove(tokenlist, tokenlistinit, sizeof(tokenlistinit)); - for(i = 0; i< ntoken; i++){ - tokenlist[i].name = strdup(tokenlist[i].name); - catsetinit(&tokenlist[i].categories, tokenlist[i].value); - } - curtext = smprint("{"); -} - -Type -gettoken(char *token) -{ - char *p, *q; - int i, n; - Token *t; - - for(;;){ - if(curtext){ - p = &curtext[strspn(curtext, " \t")]; - if(*p && *p != '\n') - break; - } - do { - str++; - free(curtext); - if((curtext = Brdstr(f, '\n', 0)) == nil) - return Eof; - } while(curtext[0] == '#'); - } - if(*p == '{'){ - *token++ = *p; - *token = 0; - *p = ' '; - return BraceO; - } - if(*p == '}'){ - *token++ = *p; - *token = 0; - *p = ' '; - return BraceC; - } - if(*p == '='){ - *token++ = *p; - *token = 0; - *p = ' '; - return Equals; - } - t = nil; - n = 0; - for(i = 0; i < ntoken; i++){ - t = &tokenlist[i]; - if(strncmp(p, t->name, n=strlen(t->name)) == 0){ - q = &p[n]; - if(isalnum(*q) || *q == '-') continue; - q += strspn(q, " \t"); - if(t->kind == Obj && *q == '{') - break; - if(t->kind == Cat && *q == '=') - break; - } - } - if(i < ntoken){ - strcpy(token, t->name); - memset(p, ' ', n); - return i; - } - assert(strlen(token) < MAXTOKEN); - if(strchr(p, '{')) - sysfatal("Illegal keyword or parse error: %s", p); - if((q = strchr(p, '='))){ - if(q == p) goto tx; - *q = 0; - strcpy(token, p); - assert(strlen(token) < MAXTOKEN); - memset(p, ' ', q-p); - *q = '='; - for(q = token; *q; q++) - if(!isalnum(*q) && !isspace(*q)) break; - if(*q) return Txt; - while(isspace(*--q)) *q = 0; - return Newcat; - } -tx: if((q = strchr(p, '}'))){ - *q = 0; - strcpy(token, p); - assert(strlen(token) < MAXTOKEN); - memset(p, ' ', q-p); - *q = '}'; - return Txt; - } - strcpy(token, p); - assert(strlen(token) < MAXTOKEN); - free(curtext); - curtext = nil; - return Txt; -} - -Object * -getobject(Type t, Object *parent) -{ - char *token; - char *textbuf; - char *tp, *p, *q; - int i; - Object *o, *oo, *child; - Token *ot; - Type nt; - - token = malloc(MAXTOKEN); - textbuf = malloc(8192); - - tp = textbuf; - o = newobject(t, parent); - o->flags |= Hier; - if(parent == nil){ - root = o; - o->path = strdup(startdir); - setmalloctag(o->path, 0x100001); - } - if(gettoken(token) != BraceO) - sysfatal("Parse error: no brace, str %d", str); - for(;;){ - t = gettoken(token); - if(t >= 0) - switch(tokenlist[t].kind){ - case Obj: - switch(t){ - case Key: - case Cmd: - case Path: - if(getobject(t, o) != nil) - sysfatal("Non-null child?"); - break; - case Include: - case Category: - child = getobject(t, o); - if(child) addchild(o, child, "case Category"); - break; - default: - /* subobject */ - child = getobject(t, o); - if(child == nil) - sysfatal("Null child?"); - addchild(o, child, "default"); - break; - } - break; - case Cat: - catcase: nt = gettoken(token); - if(nt != Equals) - sysfatal("Expected Equals, not %s", token); - nt = gettoken(token); - if(nt != Txt) - sysfatal("Expected Text, not %s", token); - if((p = strchr(token, '\n'))) *p = 0; - p = token; - if(o->type == Category){ - if(catsetisset(&o->categories)){ - fprint(2, "Category object must have one category\n"); - } - catsetcopy(&o->categories, &tokenlist[t].categories); - strncpy(o->key, p, KEYLEN); - if(catobjects[t] == 0) - sysfatal("Class %s not yet defined", tokenlist[t].name); - for(i = 0; i < catobjects[t]->nchildren; i++) - if(strcmp(catobjects[t]->children[i]->key, p) == 0) - break; - if(i == catobjects[t]->nchildren){ - /* It's a new key for the category */ - addchild(catobjects[t], o, "new key for cat"); - }else{ - /* Key already existed */ - oo = catobjects[t]->children[i]; - if(oo->value) - sysfatal("Duplicate category object for %s", oo->value); - catobjects[t]->children[i] = o; - if(oo->nchildren){ - for(i = 0; i < oo->nchildren; i++){ - if(oo->children[i]->parent == oo) - oo->children[i]->parent = o; - addchild(o, oo->children[i], "key already existed"); - } - } - freeobject(oo, "a"); - } - o->parent = catobjects[t]; - }else{ - catsetorset(&o->categories, &tokenlist[t].categories); - for(i = 0; i < catobjects[t]->nchildren; i++) - if(strcmp(catobjects[t]->children[i]->key, p) == 0) - break; - if(i == catobjects[t]->nchildren){ - oo = newobject(Category, catobjects[t]); -/* - oo->value = strdup(token); -*/ - strncpy(oo->key, p, KEYLEN); - catsetcopy(&oo->categories, &tokenlist[t].categories); - addchild(catobjects[t], oo, "catobjects[t],oo"); - } - addchild(catobjects[t]->children[i], o, "children[i]"); - } - break; - } - else - switch(t){ - case Eof: - if(o->type == Root){ - free(token); - free(textbuf); - return o; - } - sysfatal("Unexpected Eof in %s, file %s", tokenlist[o->type].name, file); - case Newcat: - /* New category, make an entry in the tokenlist */ - tokenlist = realloc(tokenlist, (ntoken+1)*sizeof(Token)); - ot = &tokenlist[ntoken]; - ot->name = strdup(token); - setmalloctag(ot->name, 0x100002); - ot->kind = Cat; - ot->value = -1; - memset(&ot->categories, 0, sizeof(Catset)); - catsetinit(&ot->categories, catnr++); - /* And make an entry in the catobjects table */ - if(ncat <= ntoken){ - catobjects = realloc(catobjects, (ntoken+1)*sizeof(Object*)); - while(ncat <= ntoken) catobjects[ncat++] = nil; - } - if(catobjects[ntoken] != nil) - sysfatal("Class %s already defined in %s:%d", token, file, str); - if(0) fprint(2, "newcat: token %s catnr %d ntoken %d ncat %d\n", - token, catnr, ntoken, ncat); - catobjects[ntoken] = newobject(Category, root); - if(o->type == Category) - catobjects[ntoken]->flags = o->flags&Hier; - catobjects[ntoken]->flags |= Sort; - strncpy(catobjects[ntoken]->key, token, KEYLEN); - catsetcopy(&catobjects[ntoken]->categories, &ot->categories); - addchild(root, catobjects[ntoken], "root"); - t = ntoken; - ntoken++; - goto catcase; - case Txt: - strcpy(tp, token); - tp += strlen(token); - break; - case BraceC: - while(tp > textbuf && tp[-1] == '\n') *--tp = 0; - if((o->type == File || o->type == Include) && o->path){ - o->value = smprint("%s/%s", o->path, textbuf); - }else if(tp > textbuf){ - o->value = strdup(textbuf); - setmalloctag(o->value, 0x100003); - } - switch(o->type){ - case Cmd: - q = strtok(o->value, " \t,;\n"); - while(q){ - if(*q) for(i = 0; cmdlist[i].name; i++){ - if(strcmp(q, cmdlist[i].name) == 0){ - o->parent->flags |= cmdlist[i].flag; - break; - } - if(cmdlist[i].name == 0) - fprint(2, "Unknown command: %s\n", q); - } - q = strtok(nil, " \t,;\n"); - } - freeobject(o, "b"); - free(token); - free(textbuf); - return nil; - case Path: - p = o->value; - free(o->parent->path); - if(p[0] == '/' || o->path == nil){ - o->parent->path = strdup(p); - setmalloctag(o->parent->path, 0x100004); - }else{ - o->parent->path = smprint("%s/%s", o->path, p); - setmalloctag(o->parent->path, 0x100005); - } - freeobject(o, "b"); - free(token); - free(textbuf); - return nil; - case Include: - free(token); - free(textbuf); - return getinclude(o); - case Category: - /* - if(o->nchildren) break; - */ - free(token); - free(textbuf); - return nil; - case Key: - strncpy(o->parent->key, o->value, KEYLEN); - freeobject(o, "d"); - free(token); - free(textbuf); - return nil; - default: - break; - } - free(token); - free(textbuf); - return o; - default: - fprint(2, "Unexpected token: %s\n", token); - free(token); - free(textbuf); - return nil; - } - } -} - -Object * -getinclude(Object *o) -{ - char *savetext; - Biobuf *savef = f; - char *savefile, fname[256]; - Object *oo; - int savestr = str; - char token[MAXTOKEN], *dirname, *filename; - Type t; - - str = 0; - if(curtext){ - savetext = strdup(curtext); - setmalloctag(savetext, 0x100006); - }else - savetext = nil; - if((f = Bopen(o->value, OREAD)) == nil) - sysfatal("getinclude: %s: %r", o->value); - savefile = file; - file = strdup(o->value); - strncpy(fname, o->value, 256); - if((filename = strrchr(fname, '/'))){ - *filename = 0; - dirname = fname; - filename++; - }else{ - dirname = ""; - filename = fname; - } - while((t = gettoken(token)) != Eof){ - if(t < 0){ - if(*dirname) - sysfatal("Bad include file %s/%s, token %s, str %d", - dirname, filename, token, str); - else - sysfatal("Bad include file %s, token %s, str %d", - filename, token, str); - } - free(o->path); - o->path = strdup(dirname); - setmalloctag(o->path, 0x100007); - oo = getobject(t, o->parent); - if(oo) addchild(o->parent, oo, "o->parent, oo"); - } - freeobject(o, "e"); - free(curtext); - curtext = nil; - if(savetext) - curtext = savetext; - free(file); - file = savefile; - str = savestr; - Bterm(f); - f = savef; - return nil; -} - -void -addchild(Object *parent, Object *child, char *where) -{ - int i; - - /* First check if child's already been added - * This saves checking elsewhere - */ - for(i = 0; i < parent->nchildren; i++) - if(parent->children[i] == child) return; - parent->children = realloc(parent->children, (i+1)*sizeof(Object*)); - parent->children[i] = child; - parent->nchildren++; - if(parent->type == Category && child->type == Category) - return; - if(parent->type == Work && child->type == Work) - return; - if(parent->type == Work && child->type == Track) - return; - if(parent->type == Track && child->type == File) - return; - if(child->parent == child) - return; - if(parent->type == Root) - return; - if(parent->parent->type == Root) - return; -// addcatparent(parent, child); - i = child->ncatparents; - if(0) fprint(2, "addcatparent %s parent %d type %d child %d type %d\n",where, - parent->tabno, parent->type, child->tabno, child->type); - child->catparents = realloc(child->catparents, (i+1)*sizeof(Object*)); - child->catparents[i] = parent; - child->ncatparents++; -} - -void -addcatparent(Object *parent, Object *child) -{ - int i; - - /* First check if child's already been added - * This saves checking elsewhere - */ - if(child->parent == child) - return; -// for(i = 0; i < child->ncatparents; i++) -// if(child->catparents[i] == parent) return; - i = child->ncatparents; - fprint(2, "addcatparent parent %d child %d\n", parent->tabno, child->tabno); - child->catparents = realloc(child->catparents, (i+1)*sizeof(Object*)); - child->catparents[i] = parent; - child->ncatparents++; -} - -void -sortprep(char *out, int n, Object *o) -{ - char *p, *q; - - if(*o->key) - q = o->key; - else if (o->value) - q = o->value; - else - q = ""; - if(p = strchr(q, '~')) - p++; - else - p = q; - for(q = out; *p && q < out+n-1; q++) - *q = tolower(*p++); - *q = 0; -} - -void -childsort(Object *o) -{ - Object *oo; - int i, j, n; - char si[256], sj[256]; - /* sort the kids by key or by value */ - - n = o->nchildren; - if(n > 1){ - for(i = 0; i < n-1; i++){ - sortprep(si, nelem(si), o->children[i]); - for(j = i+1; j < n; j++){ - sortprep(sj, nelem(sj), o->children[j]); - if(strncmp(si, sj, sizeof(si)) > 0){ - oo = o->children[i]; - o->children[i] = o->children[j]; - o->children[j] = oo; - strncpy(si, sj, sizeof(si)); - } - } - } - } -} - -void -childenum(Object *o){ - Object *oo; - int i, n = 1; - - for(i = 0; i < o->nchildren; i++){ - oo = o->children[i]; - if(tokenlist[oo->type].kind == Cat) - oo->num = n++; - else - switch(oo->type){ - case Category: - case Part: - case Recording: - case Track: - case Work: - oo->num = n++; - default: - break; - } - } -} - -Object * -newobject(Type t, Object *parent){ - Object *o; - int tabno; - - if(hotab){ - for(tabno = 0; tabno < notab; tabno++) - if(otab[tabno] == nil) - break; - if(tabno == notab) - sysfatal("lost my hole"); - hotab--; - }else{ - if(sotab < notab+1){ - sotab += 512; - otab = realloc(otab, sizeof(Object*)*sotab); - if(otab == nil) - sysfatal("realloc: %r"); - } - tabno = notab++; - } - o = mallocz(sizeof(Object), 1); - o->tabno = tabno; - otab[tabno] = o; - o->type = t; - o->parent = parent; - if(parent && parent->path){ - o->path = strdup(parent->path); - setmalloctag(o->path, 0x100008); - } - return o; -} - -void -freeobject(Object *o, char*){ - - free(o->children); - if(o->orig == nil) - free(o->value); - free(o->path); - free(o->catparents); - catsetfree(&o->categories); - otab[o->tabno] = nil; - hotab++; - free(o); -} - -void -freetree(Object *o) -{ - int i; - - for(i = 0; i < o->nchildren; i++) - if(o->children[i]->parent == o) - freetree(o->children[i]); - free(o->children); - if(o->orig == nil) - free(o->value); - free(o->path); - free(o->catparents); - catsetfree(&o->categories); - otab[o->tabno] = nil; - hotab++; - free(o); -} diff --git a/sys/src/games/music/jukefs/parse.h b/sys/src/games/music/jukefs/parse.h deleted file mode 100644 index a83e16cb2..000000000 --- a/sys/src/games/music/jukefs/parse.h +++ /dev/null @@ -1,15 +0,0 @@ -Object *getobject(Type, Object *); -Object *getinclude(Object *); -void childsort(Object *); -void childenum(Object *); -Object *newobject(Type, Object *); -void freeobject(Object *, char *); -void freetree(Object *); -void *mymalloc(void *old, int size); -void addchild(Object *, Object *, char*); -void addcatparent(Object *, Object *); -void inittokenlist(void); -void initparse(void); -void exit(int); - -extern char *startdir; diff --git a/sys/src/games/music/jukefs/print.c b/sys/src/games/music/jukefs/print.c deleted file mode 100644 index 31a1def67..000000000 --- a/sys/src/games/music/jukefs/print.c +++ /dev/null @@ -1,489 +0,0 @@ -#include -#include -#include -#include -#include -#include "object.h" -#include "parse.h" -#include "catset.h" - -int fflag; - -void -listfiles(Object *o) -{ - int i; - - if(o->type == File){ - print("%s\n", o->value); - return; - } - for(i = 0; i < o->nchildren; i++) - if(o->children[i]->parent == o) - listfiles(o->children[i]); -} - -int -indent(char *lp, int ln, int n, char *buf) { - int sln; - char *p, c; - - sln = ln; - if (ln <= 0) - return 0; - if (n < 0) - n = -n; - else { - if (ln < 4*n) - goto out; - memset(lp, ' ', 4*n); - lp += 4*n; - ln -= 4*n; - } - if(p = buf) while (ln > 1) { - c = *p++; - if(c == '\0') - break; - if(c == '~') - continue; - *lp++ = c; - ln--; - if (c == '\n' && p[1]) { - if (ln < 4*n) - break; - memset(lp, ' ', 4*n); - lp += 4*n; - ln -= 4*n; - } - } - *lp = '\0'; -out: - return sln - ln; -} - -long -printchildren(char *lp, int ln, Object *o) { - int i, r; - char *sp; - - sp = lp; - if (o->flags & Sort) { - childsort(o); - o->flags &= ~Sort; - } - for(i = 0; i < o->nchildren && ln > 0; i++){ - r = snprint(lp, ln, "%d\n", o->children[i]->tabno); - lp += r; - ln -= r; - } - return lp - sp; -} - -long -printminiparentage(char *lp, int ln, Object *o) { - char *p, c; - int r, sln; - - if (ln <= 0) return 0; - *lp = '\0'; - if (o == 0 || o->type == Root) - return 0; - sln = ln; - if(o->orig) o = o->orig; - r = printminiparentage(lp, ln, o->parent); - lp += r; - ln -= r; - if (ln <= 0) return 0; - if(o->value && o->type != File){ - if(r && o->value && ln > 1){ - *lp++ = '/'; - ln--; - } - p = o->value; - while(ln > 0){ - c = *p++; - if(c == '\n' || c == '\0') - break; - if(c == '~') - continue; - *lp++ = c; - ln--; - } - } - if(ln > 0) - *lp = '\0'; - return sln - ln; -} - -long -printparentage(char *lp, int ln, Object *o) { - int i; - int r, k, sln; - - if(ln <= 0) - return 0; - *lp = '\0'; - if(o == 0 || o->type == Root) - return 0; - if(0)fprint(2, "parentage 0x%p %d type %d value 0x%p parent 0x%p %d\n", o, o->tabno, o->type, o->value, o->parent, o->parent->tabno); - if(o->orig){ - if(0)fprint(2, "parentage 0x%p %d type %d orig %d type %d parent 0x%p %d\n", o, o->tabno, o->type, o->orig->tabno, o->orig->type, o->orig->parent, o->orig->parent->tabno); - o = o->orig; - } - sln = ln; - r = printparentage(lp, ln, o->parent); - lp += r; ln -= r; - if(o->type == File && fflag == 0){ - if(ln > 0) - *lp = '\0'; - return sln - ln; - } - if(o->value && *o->value && ln > 0){ - if(o->type == Category){ - if(o->parent == root){ - r = snprint(lp, ln, "category: "); - lp += r; ln -= r; - }else{ - for(k = Ntoken; k < ntoken; k++) - if(catseteq(&o->categories,&tokenlist[k].categories)){ - r = snprint(lp, ln, "%s: ", tokenlist[k].name); - lp += r; ln -= r; - break; - } - } - }else{ - r = snprint(lp, ln, "%s: ", tokenlist[o->type].name); - lp += r; ln -= r; - } - if(ln <= 0) - return sln - ln; - if(o->num){ - r = snprint(lp, ln, "%2d. ", o->num); - lp += r; ln -= r; - } - if(ln <= 0) - return sln - ln; - r = indent(lp, ln, -1, o->value); - lp += r; ln -= r; - if(ln > 1){ - *lp++ = '\n'; - ln--; - } - }else{ - if(0)fprint(2, "parentage 0x%p %d type %d no value\n", o, o->tabno, o->type); - } - for(i = 0; i < o->nchildren && ln > 0; i++) - switch(o->children[i]->type){ - case Performance: - case Soloists: - case Lyrics: - r = snprint(lp, ln, "%s: ", tokenlist[o->children[i]->type].name); - lp += r; ln -= r; - if(ln <= 0) - break; - r = indent(lp, ln, -1, o->children[i]->value); - lp += r; ln -= r; - if(ln > 1){ - *lp++ = '\n'; - ln--; - } - break; - case Time: - r = snprint(lp, ln, "%s: %s\n", "duration", o->children[i]->value); - lp += r; ln -= r; - break; - case File: - if(fflag){ - r = snprint(lp, ln, "%s: %s\n", "file", o->children[i]->value); - lp += r; ln -= r; - } - break; - default: - break; - } - if(ln > 0) - *lp = '\0'; - return sln - ln; -} - -long -printparent(char *lp, int ln, Object *o) { - return snprint(lp, ln, "%d", o->parent->tabno); -} - -long -printkey(char *lp, int ln, Object *o) { - return snprint(lp, ln, "%s", o->key?o->key:o->value); -} - -long -printtype(char *lp, int ln, Object *o) { - return snprint(lp, ln, "%s", tokenlist[o->type].name); -} - -long -printtext(char *lp, int ln, Object *o) { - return snprint(lp, ln, "%s", o->value?o->value:o->key); -} - -long -printfulltext(char *lp, int ln, Object *o) { - char *sp, *p, *q; - int i, j, k, c, depth; - Object *oo; - - depth = 0; - sp = lp; - switch(o->type){ - case Category: - if(o->parent == root){ - j = snprint(lp, ln, "category:"); - lp += j; ln -= j; - }else{ - for(k = Ntoken; k < ntoken; k++) - if(catseteq(&o->categories, &tokenlist[k].categories)){ - j = snprint(lp, ln, "%s:", tokenlist[k].name); - lp += j; ln -= j; - break; - } - } - if(ln <= 0) - return lp - sp; - p = o->value; - if(p == nil) - p = o->key; - if((q = strchr(p, '\n')) && q[1] != '\0'){ - // multiple lines - *lp++ = '\n'; ln--; - if(ln <= 0) - break; - j = indent(lp, ln, depth+1, p); - lp += j; ln -= j; - }else{ - *lp++ = ' '; ln--; - while((c=*p++) && ln > 0){ - if(c == '~') - continue; - *lp++ = c; - ln--; - if(c == '\n') - break; - } - } - break; - case Track: - case Part: - case Recording: - case Root: - case Search: - case Work: - j = snprint(lp, ln, "%s:", tokenlist[o->type].name); - lp += j; ln -= j; - if(ln <= 0) - break; - if(o->num){ - j = snprint(lp, ln, " %2d.", o->num); - lp += j; ln -= j; - } - if(ln <= 0) - break; - p = o->value; - if(p == nil) - p = o->key; - if((q = strchr(p, '\n')) && q[1] != '\0'){ - // multiple lines - *lp++ = '\n'; ln--; - if(ln <= 0) - break; - j = indent(lp, ln, depth+1, p); - lp += j; ln -= j; - }else{ - *lp++ = ' '; ln--; - while((c =*p++) && ln > 0){ - if(c == '~') - continue; - *lp++ = c; - ln--; - if(c == '\n') - break; - } - } - default: - break; - } - depth++; - for(i = 0; i < o->nchildren && ln > 0; i++){ - oo = o->children[i]; - switch(oo->type){ - case Lyrics: - case Performance: - case Soloists: - case Time: - if (ln <= 4*depth + 1) - break; - *lp++ = '\n'; ln--; - memset(lp, ' ', 4*depth); - lp += 4*depth; - ln -= 4*depth; - if(ln <= 0) - break; - j = snprint(lp, ln, "%s:", tokenlist[oo->type].name); - lp += j; ln -= j; - if(ln <= 0) - break; - p = oo->value; - if(ln <= 1) - break; - if((q = strchr(p, '\n')) && q[1] != '\0'){ - // multiple lines - *lp++ = '\n'; ln--; - j = indent(lp, ln, depth+1, p); - lp += j; ln -= j; - }else{ - *lp++ = ' '; ln--; - while((c =*p++) && ln > 0){ - if(c == '~') - continue; - *lp++ = c; - ln--; - if(c == '\n') - break; - } - } - } - } - *lp = '\0'; - return lp - sp; -} - -long -printfiles(char *lp, int ln, Object *o) { - int i, r; - char *sp; - - sp = lp; - if (o->type == File) - lp += snprint(lp, ln, "%d %s\n", o->tabno, o->value); - else { - for (i = 0; i < o->nchildren && ln > 0; i++){ - r = printfiles(lp, ln, o->children[i]); - lp += r; - ln -= r; - } - } - return lp - sp; -} - -long -printdigest(char *lp, int ln, Object *o) { - char *p; - int j, c, k; - char *sp; - - sp = lp; - switch(o->type){ - case Category: - if (o->parent == root) { - j = snprint(lp, ln, "category: "); - lp += j; ln -= j; - } else { - for (k = Ntoken; k < ntoken; k++) - if (catseteq(&o->categories,& tokenlist[k].categories)) { - j = snprint(lp, ln, "%s: ", tokenlist[k].name); - lp += j; ln -= j; -// break; - } - } - p = o->value; - if (p == 0) p = o->key; - while ((c=*p++) && c != '\n' && ln > 0) { - if(c == '~') - continue; - *lp++ = c; - ln--; - } - break; - case Track: - case Part: - case Recording: - case Root: - case Search: - case Work: - j = snprint(lp, ln, "%s: ", tokenlist[o->type].name); - lp += j; ln -= j; - if (o->num) { - j = snprint(lp, ln, "%2d. ", o->num); - lp += j; ln -= j; - } - p = o->value; - if (p == 0) p = o->key; - while ((c = *p++) && c != '\n' && ln > 0) { - if(c == '~') - continue; - *lp++ = c; - ln--; - } - default: - break; - } - if(ln) - *lp = '\0'; - return lp - sp; -} - -#ifdef UNDEF - -void -printtree(Object *o, int ind) { - char *p; - char buf[2048]; - int i; - - sprintf(buf, "%s {\n", tokenlist[o->type].name); - indent(ind, buf); - ind++; - if ((p = o->value)) { - sprintf(buf, "%s\n", p); - indent(ind, buf); - } - for (i = 0; i < o->nchildren; i++) - printtree(o->children[i], ind); - indent(--ind, "}\n"); -} - -void -mapdump(Object *o, int depth, char *inheritance) { - Object *oo; - char *data; - int n, l; - - if (o == root) { - depth = 0; - inheritance = ""; - data = NULL; - } else { - if (o->value) { - l = nlines(o->value); - n = strlen(inheritance) + - l * (strlen(tokenlist[o->type].name) + 2) + - strlen(o->value) + 2; - data = mymalloc(NULL, n); - strcpy(data, inheritance); - p = data + strlen(inheritance); - q = o->value; - while (*q) { - p += sprintf(p, "%s:\t", tokenlist[o->type].name); - do { - *p++ = *q; - while (*q++ != '\n'); - } - if (p[-1] != '\n') *p++ = '\n'; - *p = 0; - inheritance = data; - } - indent(depth, inheritance); - } - c = 0; -} - -#endif diff --git a/sys/src/games/music/jukefs/print.h b/sys/src/games/music/jukefs/print.h deleted file mode 100644 index 82e4a7c1a..000000000 --- a/sys/src/games/music/jukefs/print.h +++ /dev/null @@ -1,6 +0,0 @@ -extern int fflag; - -void printtree(Object *, int); -int parentage(char *, int, Object *); -int miniparentage(char *, int, Object *); -int indent(char *, int, int n, char *buf); diff --git a/sys/src/games/music/jukefs/search.c b/sys/src/games/music/jukefs/search.c deleted file mode 100644 index 8f009ddbb..000000000 --- a/sys/src/games/music/jukefs/search.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include "object.h" -#include "parse.h" -#include "search.h" - -Object * -search(Object *rt, Object *parent, Reprog *preg) { - /* Create a `search object', a subtree of rt containing - * only objects with s in their value of key fields plus - * their parentage. - * - * Algorithm: depth-first traversal of rt. On the way down, - * copy rt to nr (new root), on the way back up, delete - * subtrees without match. - * - * returns null when there are no matches in rt's subtree - */ - Object *o, *nr; - char *s; - int i; - int yes = 0; - - nr = newobject(rt->type, parent); - nr->orig = rt->orig?rt->orig:rt; - nr->value = rt->value; - strncpy(nr->key, rt->key, KEYLEN); - - if((((s = nr->value)) && regexec(preg, s, nil, 0) == 1) - || (((s = nr->value)) && regexec(preg, s, nil, 0) == 1)) - yes = 1; - for(i = 0; i < rt->nchildren; i++) - if((o = search((Object*)rt->children[i], nr, preg))){ - yes = 1; - addchild(nr, o, "search"); - } - if(yes == 0){ - freeobject(nr, "s"); - return nil; - } - return nr; -} diff --git a/sys/src/games/music/jukefs/search.h b/sys/src/games/music/jukefs/search.h deleted file mode 100644 index 6ff100ee6..000000000 --- a/sys/src/games/music/jukefs/search.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -extern Object *sobj; - -Object *search(Object *rt, Object *parent, Reprog *preg); diff --git a/sys/src/games/music/jukefs/server.c b/sys/src/games/music/jukefs/server.c deleted file mode 100644 index ab29a7bc6..000000000 --- a/sys/src/games/music/jukefs/server.c +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include -#include -#include -#include "object.h" -#include "parse.h" -#include "print.h" -#include "catset.h" -#include "../debug.h" - -char *user, *mapname, *svrname; -int p[2]; -int mfd[2]; -int debug = 0; //DBGSERVER|DBGSTATE|DBGPICKLE|DBGPLAY; -Biobuf *f; -char *file; - -Object *root; - -Object ** otab; // object table -int notab; // no of entries used -int sotab; // no of entries mallocated (invariant sotab >= notab) -int hotab; // no of holes in otab; - -char usage[] = "Usage: %s [-f] [-l] [mapfile]\n"; - -char *startdir; - -Object **catobjects; /* for quickly finding category objects */ -int ncat = 0; - -void -post(char *name, char *envname, int srvfd) -{ - int fd; - char buf[32]; - - fd = create(name, OWRITE, 0666); - if(fd < 0) - return; - sprint(buf, "%d",srvfd); - if(write(fd, buf, strlen(buf)) != strlen(buf)) - sysfatal("srv write: %r"); - close(fd); - putenv(envname, name); -} - -int -robusthandler(void*, char *s) -{ - if (debug) fprint(2, "inthandler: %s\n", s); - return (s && (strstr(s, "interrupted") || strstr(s, "hangup"))); -} - -long -robustread(int fd, void *buf, long sz) -{ - long r; - char err[32]; - - do { - r = read(fd , buf, sz); - if (r < 0) - rerrstr(err, sizeof(err)); - } while (r < 0 && robusthandler(nil, err)); - return r; -} - -void -delobject(Object *o) -{ - /* Free an object and all its descendants */ - Object *oo; - int i; - - for (i = 0; i < o->nchildren; i++){ - oo = o->children[i]; - if (oo->parent == o) - delobject(oo); - } - freeobject(o, "r"); -} - -void -threadmain(int argc, char *argv[]) { - char *q; - char *srvname; - char *mntpt; - int list; - - mntpt = "/mnt"; - user = strdup(getuser()); - srvname = nil; - list = 0; - - ARGBEGIN{ - case 'l': - list = 1; - break; - case 'm': - mntpt = ARGF(); - break; - case 'd': - debug = strtoul(ARGF(), nil, 0); - break; - case 's': - srvname = ARGF(); - break; - case 'f': - fflag = 1; - break; - default: - fprint(2, usage, argv0); - exits("usage"); - }ARGEND - - switch (argc) { - default: - fprint(2, usage, argv0); - exits("usage"); - case 0: - mapname = DEFAULTMAP; - break; - case 1: - mapname = argv[0]; - break; - } - - quotefmtinstall(); - - if((f = Bopen(mapname, OREAD)) == nil) - sysfatal("%s: %r", mapname); - free(file); - file = strdup(mapname); - free(startdir); - startdir = strdup(mapname); - if ((q = strrchr(startdir, '/'))) - *q = '\0'; - else - startdir[0] = '\0'; - inittokenlist(); - getobject(Root, nil); - Bterm(f); - f = nil; - root->parent = root; - - if(list){ - listfiles(root); - threadexits(nil); - } - - if(pipe(p) < 0) - sysfatal("pipe failed: %r"); - mfd[0] = p[0]; - mfd[1] = p[0]; - - threadnotify(robusthandler, 1); - user = strdup(getuser()); - - if(debug) - fmtinstall('F', fcallfmt); - - procrfork(io, nil, 8192, RFFDG); //RFNOTEG? - - close(p[0]); /* don't deadlock if child fails */ - - if(srvname){ - srvname = smprint("/srv/jukefs.%s", srvname); - remove(srvname); - post(srvname, "jukefs", p[1]); - } - if(mount(p[1], -1, mntpt, MBEFORE, "") < 0) - sysfatal("mount failed: %r"); - threadexits(nil); -} - -void -reread(void) -{ - int i; - extern int catnr; - char *q; - - assert(f == nil); - if((f = Bopen(mapname, OREAD)) == nil) - fprint(2, "reread: %s: %r\n", mapname); - freetree(root); - root = nil; - for(i = 0; i< ntoken; i++){ - free(tokenlist[i].name); - catsetfree(&tokenlist[i].categories); - } - catnr = 0; - free(tokenlist); - free(catobjects); - catobjects = nil; - ncat = 0; - tokenlist = nil; - ntoken = Ntoken; - inittokenlist(); - free(file); - file = strdup(mapname); - free(startdir); - startdir = strdup(mapname); - if ((q = strrchr(startdir, '/'))) - *q = '\0'; - else - startdir[0] = '\0'; - getobject(Root, nil); - root->parent = root; - Bterm(f); - f = nil; -} diff --git a/sys/src/games/music/mkfile b/sys/src/games/music/mkfile deleted file mode 100644 index c6820db8b..000000000 --- a/sys/src/games/music/mkfile +++ /dev/null @@ -1,51 +0,0 @@ -dirs = playlistfs jukefs jukebox - -# DEFAULTMAP = /lib/audio/map -ICONPATH = /lib/audio/icon - -ICONS = \ - next.bit\ - pause.bit\ - play.bit\ - prev.bit\ - question.bit\ - root.bit\ - skull.bit\ - stop.bit\ - trash.bit\ - -ICONFILES = ${ICONS:%.bit=icon/%.bit} - -default:V: all - -all dep clean nuke:V: - for (i in $dirs) @ { - echo $i - cd $i - mk $MKFLAGS $target - } - -rcinstall:V: juke.rc - cp juke.rc /rc/bin/juke - chmod +x /rc/bin/juke - -$ICONPATH: - mkdir $ICONPATH - -iconinstall:V: $ICONFILES $ICONPATH - for (i in $ICONS) - cp $ICONFILES $ICONPATH - -install:V: - for (i in $dirs) @ { - echo $i - cd $i - mk $MKFLAGS $target - } - mk rcinstall - mk iconinstall - -installall:V: - for(objtype in $CPUS) - mk $MKFLAGS install - mk rcinstall diff --git a/sys/src/games/music/mkinc b/sys/src/games/music/mkinc deleted file mode 100644 index c57141646..000000000 --- a/sys/src/games/music/mkinc +++ /dev/null @@ -1,9 +0,0 @@ -base = .. -CFLAGS=$CFLAGS $DEFINES - -all: - -dep:Q: - mkdep $INCLUDES $CFILES > mk.dep - -< mk.dep diff --git a/sys/src/games/music/playlistfs/boilerplate.c b/sys/src/games/music/playlistfs/boilerplate.c deleted file mode 100644 index 3918b0529..000000000 --- a/sys/src/games/music/playlistfs/boilerplate.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include -#include "playlist.h" - -static Channel *reqs; - -Req* -reqalloc(void) -{ - Req *r; - - if(reqs == nil) - reqs = chancreate(sizeof(Req*), 256); - if(r = nbrecvp(reqs)) - return r; - r = malloc(sizeof(Req)); - return r; -} - -void -reqfree(Req *r) -{ - if(!nbsendp(reqs, r)) - free(r); -} - -Wmsg -waitmsg(Worker *w, Channel *q) -{ - Wmsg m; - - sendp(q, w); - recv(w->eventc, &m); - return m; -} - -int -sendmsg(Channel *q, Wmsg *m) -{ - Worker *w; - - while(w = nbrecvp(q)){ - /* Test for markerdom (see bcastmsg) */ - if(w->eventc){ - send(w->eventc, m); - return 1; - } - sendp(q, w); /* put back */ - } - return 0; -} - -void -bcastmsg(Channel *q, Wmsg *m) -{ - Worker *w, marker; - void *a; - - a = m->arg; - /* - * Use a marker to mark the end of the queue. - * This prevents workers from getting the - * broadcast and putting themselves back on the - * queue before the broadcast has finished - */ - marker.eventc = nil; /* Only markers have eventc == nil */ - sendp(q, &marker); - while((w = recvp(q)) != &marker){ - if(w->eventc == nil){ - /* somebody else's marker, put it back */ - sendp(q, w); - }else{ - if(a) m->arg = strdup(a); - send(w->eventc, m); - } - } - free(a); - m->arg = nil; -} - -void -readbuf(Req *r, void *s, long n) -{ - r->ofcall.count = r->ifcall.count; - if(r->ifcall.offset >= n){ - r->ofcall.count = 0; - return; - } - if(r->ifcall.offset+r->ofcall.count > n) - r->ofcall.count = n - r->ifcall.offset; - memmove(r->ofcall.data, (char*)s+r->ifcall.offset, r->ofcall.count); -} - -void -readstr(Req *r, char *s) -{ - readbuf(r, s, strlen(s)); -} diff --git a/sys/src/games/music/playlistfs/fs.c b/sys/src/games/music/playlistfs/fs.c deleted file mode 100644 index 47195e0df..000000000 --- a/sys/src/games/music/playlistfs/fs.c +++ /dev/null @@ -1,882 +0,0 @@ -#include -#include -#include -#include -#include "pool.h" -#include "playlist.h" - -typedef struct Wmsg Wmsg; - -enum { - Busy = 0x01, - Open = 0x02, - Trunc = 0x04, - Eof = 0x08, -}; - -File files[] = { -[Qdir] = {.dir = {0,0,{Qdir, 0,QTDIR}, 0555|DMDIR, 0,0,0, "."}}, -[Qplayctl] = {.dir = {0,0,{Qplayctl, 0,QTFILE}, 0666, 0,0,0, "playctl"}}, -[Qplaylist] = {.dir = {0,0,{Qplaylist, 0,QTFILE}, 0666|DMAPPEND, 0,0,0, "playlist"}}, -[Qplayvol] = {.dir = {0,0,{Qplayvol, 0,QTFILE}, 0666, 0,0,0, "playvol"}}, -[Qplaystat] = {.dir = {0,0,{Qplaystat, 0,QTFILE}, 0444, 0,0,0, "playstat"}}, -}; - -Channel *reqs; -Channel *workers; -Channel *volumechan; -Channel *playchan; -Channel *playlistreq; -Playlist playlist; -int volume[8]; - -char *statetxt[] = { - [Nostate] = "panic!", - [Error] = "error", - [Stop] = "stop", - [Pause] = "pause", - [Play] = "play", - [Resume] = "resume", - [Skip] = "skip", - nil -}; - -// low-order bits: position in play list, high-order: play state: -Pmsg playstate = {Stop, 0}; - -char *rflush(Worker*), *rauth(Worker*), - *rattach(Worker*), *rwalk(Worker*), - *ropen(Worker*), *rcreate(Worker*), - *rread(Worker*), *rwrite(Worker*), *rclunk(Worker*), - *rremove(Worker*), *rstat(Worker*), *rwstat(Worker*), - *rversion(Worker*); - -char *(*fcalls[])(Worker*) = { - [Tflush] rflush, - [Tversion] rversion, - [Tauth] rauth, - [Tattach] rattach, - [Twalk] rwalk, - [Topen] ropen, - [Tcreate] rcreate, - [Tread] rread, - [Twrite] rwrite, - [Tclunk] rclunk, - [Tremove] rremove, - [Tstat] rstat, - [Twstat] rwstat, -}; - -int messagesize = Messagesize; -Fid *fids; - - -char Eperm[] = "permission denied"; -char Enotdir[] = "not a directory"; -char Enoauth[] = "authentication not required"; -char Enotexist[] = "file does not exist"; -char Einuse[] = "file in use"; -char Eexist[] = "file exists"; -char Enotowner[] = "not owner"; -char Eisopen[] = "file already open for I/O"; -char Excl[] = "exclusive use file already open"; -char Ename[] = "illegal name"; -char Ebadctl[] = "unknown control message"; -char Epast[] = "reading past eof"; - -Fid *oldfid(int); -Fid *newfid(int); -void volumeupdater(void*); -void playupdater(void*); - -char *playerror; - -static int -lookup(char *cmd, char *list[]) -{ - int i; - - for (i = 0; list[i] != nil; i++) - if (strcmp(cmd, list[i]) == 0) - return i; - return -1; -} - -char* -rversion(Worker *w) -{ - Req *r; - Fid *f; - - r = w->r; - if(r->ifcall.msize < 256) - return "max messagesize too small"; - if(r->ifcall.msize < messagesize) - messagesize = r->ifcall.msize; - r->ofcall.msize = messagesize; - if(strncmp(r->ifcall.version, "9P2000", 6) != 0) - return "unknown 9P version"; - else - r->ofcall.version = "9P2000"; - for(f = fids; f; f = f->next) - if(f->flags & Busy) - f->flags &= ~(Open|Busy); - return nil; -} - -char* -rauth(Worker*) -{ - return Enoauth; -} - -char* -rflush(Worker *w) -{ - Wmsg m; - int i; - Req *r; - - r = w->r; - m.cmd = Flush; - m.off = r->ifcall.oldtag; - m.arg = nil; - for(i = 1; i < nelem(files); i++) - bcastmsg(files[i].workers, &m); - if (debug & DbgWorker) - fprint(2, "flush done on tag %d\n", r->ifcall.oldtag); - return 0; -} - -char* -rattach(Worker *w) -{ - Fid *f; - Req *r; - - r = w->r; - r->fid = newfid(r->ifcall.fid); - f = r->fid; - f->flags |= Busy; - f->file = &files[Qdir]; - r->ofcall.qid = f->file->dir.qid; - if(!aflag && strcmp(r->ifcall.uname, user) != 0) - return Eperm; - return 0; -} - -static Fid* -doclone(Fid *f, int nfid) -{ - Fid *nf; - - nf = newfid(nfid); - if(nf->flags & Busy) - return nil; - nf->flags |= Busy; - nf->flags &= ~(Open); - nf->file = f->file; - return nf; -} - -char* -dowalk(Fid *f, char *name) -{ - int t; - - if (strcmp(name, ".") == 0) - return nil; - if (strcmp(name, "..") == 0){ - f->file = &files[Qdir]; - return nil; - } - if(f->file != &files[Qdir]) - return Enotexist; - for (t = 1; t < Nqid; t++){ - if(strcmp(name, files[t].dir.name) == 0){ - f->file = &files[t]; - return nil; - } - } - return Enotexist; -} - -char* -rwalk(Worker *w) -{ - Fid *f, *nf; - char *rv; - int i; - File *savefile; - Req *r; - - r = w->r; - r->fid = oldfid(r->ifcall.fid); - if((f = r->fid) == nil) - return Enotexist; - if(f->flags & Open) - return Eisopen; - - r->ofcall.nwqid = 0; - nf = nil; - savefile = f->file; - /* clone if requested */ - if(r->ifcall.newfid != r->ifcall.fid){ - nf = doclone(f, r->ifcall.newfid); - if(nf == nil) - return "new fid in use"; - f = nf; - } - - /* if it's just a clone, return */ - if(r->ifcall.nwname == 0 && nf != nil) - return nil; - - /* walk each element */ - rv = nil; - for(i = 0; i < r->ifcall.nwname; i++){ - rv = dowalk(f, r->ifcall.wname[i]); - if(rv != nil){ - if(nf != nil) - nf->flags &= ~(Open|Busy); - else - f->file = savefile; - break; - } - r->ofcall.wqid[i] = f->file->dir.qid; - } - r->ofcall.nwqid = i; - - /* we only error out if no walk */ - if(i > 0) - rv = nil; - - return rv; -} - -char * -ropen(Worker *w) -{ - Fid *f, *ff; - Wmsg m; - Req *r; - - r = w->r; - r->fid = oldfid(r->ifcall.fid); - if((f = r->fid) == nil) - return Enotexist; - if(f->flags & Open) - return Eisopen; - - if(r->ifcall.mode != OREAD) - if((f->file->dir.mode & 0x2) == 0) - return Eperm; - if((r->ifcall.mode & OTRUNC) && f->file == &files[Qplaylist]){ - playlist.nlines = 0; - playlist.ndata = 0; - free(playlist.lines); - free(playlist.data); - playlist.lines = nil; - playlist.data = nil; - f->file->dir.length = 0; - f->file->dir.qid.vers++; - /* Mark all fids for this file `Trunc'ed */ - for(ff = fids; ff; ff = ff->next) - if(ff->file == &files[Qplaylist] && (ff->flags & Open)) - ff->flags |= Trunc; - m.cmd = Check; - m.off = 0; - m.arg = nil; - bcastmsg(f->file->workers, &m); - } - r->ofcall.iounit = 0; - r->ofcall.qid = f->file->dir.qid; - f->flags |= Open; - return nil; -} - -char * -rcreate(Worker*) -{ - return Eperm; -} - -int -readtopdir(Fid*, uchar *buf, long off, int cnt, int blen) -{ - int i, m, n; - long pos; - - n = 0; - pos = 0; - for (i = 1; i < Nqid; i++){ - m = convD2M(&files[i].dir, &buf[n], blen-n); - if(off <= pos){ - if(m <= BIT16SZ || m > cnt) - break; - n += m; - cnt -= m; - } - pos += m; - } - return n; -} - -char* -rread(Worker *w) -{ - Fid *f; - Req *r; - long off, cnt; - int n, i; - Wmsg m; - char *p; - - r = w->r; - r->fid = oldfid(r->ifcall.fid); - if((f = r->fid) == nil) - return Enotexist; - r->ofcall.count = 0; - off = r->ifcall.offset; - cnt = r->ifcall.count; - - if(cnt > messagesize - IOHDRSZ) - cnt = messagesize - IOHDRSZ; - - if(f->file == &files[Qdir]){ - n = readtopdir(f, r->indata, off, cnt, messagesize - IOHDRSZ); - r->ofcall.count = n; - return nil; - } - - if(f->file == files + Qplaystat){ - p = getplaystat(r->ofcall.data, r->ofcall.data + sizeof r->indata); - readbuf(r, r->ofcall.data, p - r->ofcall.data); - return nil; - } - - m.cmd = 0; - while(f->vers == f->file->dir.qid.vers && (f->flags & Eof)){ - /* Wait until file state changes (f->file->dir.qid.vers is incremented) */ - m = waitmsg(w, f->file->workers); - if(m.cmd == Flush && m.off == r->ifcall.tag) - return (char*)~0; /* no answer needed */ - assert(m.cmd != Work); - yield(); - } - if(f->file == files + Qplaylist){ - f->flags &= ~Eof; - if((f->flags & Trunc) && r->ifcall.offset != 0){ - f->flags &= ~Trunc; - return Epast; - } - f->flags &= ~Trunc; - if(r->ifcall.offset < playlist.ndata) - readbuf(r, playlist.data, playlist.ndata); - else if(r->ifcall.offset == playlist.ndata){ - r->ofcall.count = 0; - /* Arrange for this fid to wait next time: */ - f->vers = f->file->dir.qid.vers; - f->flags |= Eof; - }else{ - /* Beyond eof, bad seek? */ - return Epast; - } - }else if(f->file == files + Qplayctl){ - f->flags &= ~Eof; - if(m.cmd == Error){ - snprint(r->ofcall.data, sizeof r->indata, "%s %ud %q", - statetxt[m.cmd], m.off, m.arg); - free(m.arg); - }else if(f->vers == f->file->dir.qid.vers){ - r->ofcall.count = 0; - /* Arrange for this fid to wait next time: */ - f->flags |= Eof; - return nil; - }else{ - snprint(r->ofcall.data, sizeof r->indata, "%s %ud", - statetxt[playstate.cmd], playstate.off); - f->vers = f->file->dir.qid.vers; - } - r->ofcall.count = strlen(r->ofcall.data); - if(r->ofcall.count > r->ifcall.count) - r->ofcall.count = r->ifcall.count; - }else if(f->file == files + Qplayvol){ - f->flags &= ~Eof; - if(f->vers == f->file->dir.qid.vers){ - r->ofcall.count = 0; - /* Arrange for this fid to wait next time: */ - f->flags |= Eof; - }else{ - p = seprint(r->ofcall.data, r->ofcall.data + sizeof r->indata, "volume '"); - for(i = 0; i < nelem(volume); i++){ - if(volume[i] == Undef) - break; - p = seprint(p, r->ofcall.data + sizeof r->indata, "%d ", volume[i]); - } - p = seprint(p, r->ofcall.data + sizeof r->indata, "'"); - r->ofcall.count = p - r->ofcall.data; - if(r->ofcall.count > r->ifcall.count) - r->ofcall.count = r->ifcall.count; - f->vers = f->file->dir.qid.vers; - } - }else - abort(); - return nil; -} - -char* -rwrite(Worker *w) -{ - long cnt, i, nf, cmd; - Pmsg newstate; - char *fields[3], *p, *q; - Wmsg m; - Fid *f; - Req *r; - - r = w->r; - r->fid = oldfid(r->ifcall.fid); - if((f = r->fid) == nil) - return Enotexist; - r->ofcall.count = 0; - cnt = r->ifcall.count; - - if(cnt > messagesize - IOHDRSZ) - cnt = messagesize - IOHDRSZ; - - if(f->file == &files[Qplayctl]){ - r->ifcall.data[cnt] = '\0'; - if (debug & DbgPlayer) - fprint(2, "rwrite playctl: %s\n", r->ifcall.data); - nf = tokenize(r->ifcall.data, fields, 4); - if (nf == 0){ - r->ofcall.count = r->ifcall.count; - return nil; - } - if (nf == 2) - i = strtol(fields[1], nil, 0); - else - i = playstate.off; - newstate = playstate; - if ((cmd = lookup(fields[0], statetxt)) < 0) - return Ebadctl; - switch(cmd){ - case Play: - newstate.cmd = cmd; - newstate.off = i; - break; - case Pause: - if (playstate.cmd != Play) - break; - // fall through - case Stop: - newstate.cmd = cmd; - newstate.off = playstate.off; - break; - case Resume: - if(playstate.cmd == Stop) - break; - newstate.cmd = Resume; - newstate.off = playstate.off; - break; - case Skip: - if (nf == 2) - i += playstate.off; - else - i = playstate.off +1; - if(i < 0) - i = 0; - else if (i >= playlist.nlines) - i = playlist.nlines - 1; - newstate.cmd = Play; - newstate.off = i; - } - if (newstate.off >= playlist.nlines){ - newstate.cmd = Stop; - newstate.off = playlist.nlines; - } - if (debug & DbgPlayer) - fprint(2, "new state %s-%ud\n", - statetxt[newstate.cmd], newstate.off); - if (newstate.m != playstate.m) - sendul(playc, newstate.m); - f->file->dir.qid.vers++; - } else if(f->file == &files[Qplayvol]){ - char *subfields[nelem(volume)]; - int v[nelem(volume)]; - - r->ifcall.data[cnt] = '\0'; - if (debug & DbgPlayer) - fprint(2, "rwrite playvol: %s\n", r->ifcall.data); - nf = tokenize(r->ifcall.data, fields, 4); - if (nf == 0){ - r->ofcall.count = r->ifcall.count; - return nil; - } - if (nf != 2 || strcmp(fields[0], "volume") != 0) - return Ebadctl; - if (debug & DbgPlayer) - fprint(2, "new volume '"); - nf = tokenize(fields[1], subfields, nelem(subfields)); - if (nf <= 0 || nf > nelem(volume)) - return "volume"; - for (i = 0; i < nf; i++){ - v[i] = strtol(subfields[i], nil, 0); - if (debug & DbgPlayer) - fprint(2, " %d", v[i]); - } - if (debug & DbgPlayer) - fprint(2, "'\n"); - while (i < nelem(volume)) - v[i++] = Undef; - volumeset(v); - r->ofcall.count = r->ifcall.count; - return nil; - } else if(f->file == &files[Qplaylist]){ - if (debug & DbgPlayer){ - fprint(2, "rwrite playlist: `"); - write(2, r->ifcall.data, cnt); - fprint(2, "'\n"); - } - playlist.data = realloc(playlist.data, playlist.ndata + cnt + 2); - if (playlist.data == 0) - sysfatal("realloc: %r"); - memmove(playlist.data + playlist.ndata, r->ifcall.data, cnt); - if (playlist.data[playlist.ndata + cnt-1] != '\n') - playlist.data[playlist.ndata + cnt++] = '\n'; - playlist.data[playlist.ndata + cnt] = '\0'; - p = playlist.data + playlist.ndata; - while (*p){ - playlist.lines = realloc(playlist.lines, (playlist.nlines+1)*sizeof(playlist.lines[0])); - if(playlist.lines == nil) - sysfatal("realloc: %r"); - playlist.lines[playlist.nlines] = playlist.ndata; - q = strchr(p, '\n'); - if (q == nil) - break; - if(debug & DbgPlayer) - fprint(2, "[%lud]: ", playlist.nlines); - playlist.nlines++; - q++; - if(debug & DbgPlayer) - write(2, p, q-p); - playlist.ndata += q - p; - p = q; - } - f->file->dir.length = playlist.ndata; - f->file->dir.qid.vers++; - }else - return Eperm; - r->ofcall.count = r->ifcall.count; - m.cmd = Check; - m.off = 0; - m.arg = nil; - bcastmsg(f->file->workers, &m); - return nil; -} - -char * -rclunk(Worker *w) -{ - Fid *f; - - f = oldfid(w->r->ifcall.fid); - if(f == nil) - return Enotexist; - f->flags &= ~(Open|Busy); - return 0; -} - -char * -rremove(Worker*) -{ - return Eperm; -} - -char * -rstat(Worker *w) -{ - Req *r; - - r = w->r; - r->fid = oldfid(r->ifcall.fid); - if(r->fid == nil) - return Enotexist; - r->ofcall.nstat = convD2M(&r->fid->file->dir, r->indata, messagesize - IOHDRSZ); - r->ofcall.stat = r->indata; - return 0; -} - -char * -rwstat(Worker*) -{ - return Eperm; -} - -Fid * -oldfid(int fid) -{ - Fid *f; - - for(f = fids; f; f = f->next) - if(f->fid == fid) - return f; - return nil; -} - -Fid * -newfid(int fid) -{ - Fid *f, *ff; - - ff = nil; - for(f = fids; f; f = f->next) - if(f->fid == fid){ - return f; - }else if(ff == nil && (f->flags & Busy) == 0) - ff = f; - if(ff == nil){ - ff = mallocz(sizeof *ff, 1); - if (ff == nil) - sysfatal("malloc: %r"); - ff->next = fids; - ff->readers = 0; - fids = ff; - } - ff->fid = fid; - ff->file = nil; - ff->vers = ~0; - return ff; -} - -void -work(Worker *w) -{ - Req *r; - char *err; - int n; - - r = w->r; - r->ofcall.data = (char*)r->indata; - if(!fcalls[r->ifcall.type]) - err = "bad fcall type"; - else - err = (*fcalls[r->ifcall.type])(w); - if(err != (char*)~0){ /* ~0 indicates Flush received */ - if(err){ - r->ofcall.type = Rerror; - r->ofcall.ename = err; - }else{ - r->ofcall.type = r->ifcall.type + 1; - r->ofcall.fid = r->ifcall.fid; - } - r->ofcall.tag = r->ifcall.tag; - if(debug & DbgFs) - fprint(2, "io:->%F\n", &r->ofcall);/**/ - n = convS2M(&r->ofcall, r->outdata, messagesize); - if(write(srvfd[0], r->outdata, n) != n) - sysfatal("mount write"); - } - reqfree(r); - w->r = nil; -} - -void -worker(void *arg) -{ - Worker *w; - Wmsg m; - - w = arg; - recv(w->eventc, &m); - for(;;){ - assert(m.cmd == Work); - w->r = m.arg; - if(debug & DbgWorker) - fprint(2, "worker 0x%p:<-%F\n", w, &w->r->ifcall); - work(w); - if(debug & DbgWorker) - fprint(2, "worker 0x%p wait for next\n", w); - m = waitmsg(w, workers); - } -} - -void -allocwork(Req *r) -{ - Worker *w; - Wmsg m; - - m.cmd = Work; - m.off = 0; - m.arg = r; - if(sendmsg(workers, &m)) - return; - /* No worker ready to accept request, allocate one */ - w = malloc(sizeof(Worker)); - w->eventc = chancreate(sizeof(Wmsg), 1); - if(debug & DbgWorker) - fprint(2, "new worker 0x%p\n", w);/**/ - threadcreate(worker, w, 4096); - send(w->eventc, &m); -} - -void -srvio(void *arg) -{ - int n; - Req *r; - Channel *dispatchc; - - threadsetname("file server IO"); - dispatchc = arg; - - r = reqalloc(); - while((n = read9pmsg(srvfd[0], r->indata, messagesize)) != 0){ - if(n < 0){ - char e[32]; - rerrstr(e, sizeof e); - if (strcmp(e, "interrupted") == 0){ - if (debug & DbgFs) fprint(2, "read9pmsg interrupted\n"); - continue; - } - sysfatal("srvio: read: %s", e); - } - if(convM2S(r->indata, n, &r->ifcall) != n) - sysfatal("srvio: convM2S: %r"); - - if(debug & DbgFs) - fprint(2, "io:<-%F\n", &r->ifcall); - sendp(dispatchc, r); - r = reqalloc(); - } - threadexitsall(nil); -} - -char * -getplaylist(int n) -{ - Wmsg m; - - m.cmd = Preq; - m.off = n; - m.arg = nil; - send(playlistreq, &m); - recv(playlistreq, &m); - if(m.cmd == Error) - return nil; - assert(m.cmd == Prep); - assert(m.arg); - return m.arg; -} - -void -playlistsrv(void*) -{ - Wmsg m; - char *p, *q, *r; - char *fields[2]; - int n; - /* Runs in the srv proc */ - - threadsetname("playlistsrv"); - while(recv(playlistreq, &m)){ - assert(m.cmd == Preq); - m.cmd = Error; - if(m.off < playlist.nlines){ - p = playlist.data + playlist.lines[m.off]; - q = strchr(p, '\n'); - if (q == nil) - sysfatal("playlistsrv: no newline character found"); - n = q-p; - r = malloc(n+1); - memmove(r, p, n); - r[n] = 0; - tokenize(r, fields, nelem(fields)); - assert(fields[0] == r); - m.cmd = Prep; - m.arg = r; - } - send(playlistreq, &m); - } -} - -void -srv(void*) -{ - Req *r; - Channel *dispatchc; - /* - * This is the proc with all the action. - * When a file request comes in, it is dispatched to this proc - * for processing. Two extra threads field changes in play state - * and volume state. - * By keeping all the action in this proc, we won't need locks - */ - - threadsetname("srv"); - close(srvfd[1]); - - dispatchc = chancreate(sizeof(Req*), 1); - procrfork(srvio, dispatchc, 4096, RFFDG); - - threadcreate(volumeupdater, nil, 4096); - threadcreate(playupdater, nil, 4096); - threadcreate(playlistsrv, nil, 4096); - - while(r = recvp(dispatchc)) - allocwork(r); - -} - -void -playupdater(void*) -{ - Wmsg m; - /* This is a thread in the srv proc */ - - while(recv(playchan, &m)){ - if(debug & DbgPlayer) - fprint(2, "playupdate: %s %d %s\n", statetxt[m.cmd], m.off, m.arg?m.arg:""); - if(playstate.m == m.m) - continue; - if(m.cmd == Stop && m.off == 0xffff) - m.off = playlist.nlines; - if(m.cmd != Error){ - playstate.m = m.m; - m.cmd = Check; - assert(m.arg == nil); - } - files[Qplayctl].dir.qid.vers++; - bcastmsg(files[Qplayctl].workers, &m); - } -} - -void -volumeupdater(void*) -{ - Wmsg m; - int v[nelem(volume)]; - /* This is a thread in the srv proc */ - - while(recv(volumechan, v)){ - if(debug & DbgPlayer) - fprint(2, "volumeupdate: volume now %d %d %d %d\n", volume[0], volume[1], volume[2], volume[3]); - memmove(volume, v, sizeof(volume)); - files[Qplayvol].dir.qid.vers++; - m.cmd = Check; - m.arg = nil; - bcastmsg(files[Qplayvol].workers, &m); - } -} - -void -playupdate(Pmsg p, char *s) -{ - Wmsg m; - - m.m = p.m; - m.arg = s ? strdup(s) : nil; - send(playchan, &m); -} diff --git a/sys/src/games/music/playlistfs/main.c b/sys/src/games/music/playlistfs/main.c deleted file mode 100644 index 806c631a7..000000000 --- a/sys/src/games/music/playlistfs/main.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include "playlist.h" - -int debug; -char *user; -int srvfd[2]; -int aflag; - -void -usage(void) -{ - sysfatal("usage: %s [-d bitmask] [-s] [-m mountpoint]", argv0); -} - -void -post(char *name, int sfd) -{ - int fd; - char buf[32]; - - fd = create(name, OWRITE, 0666); - if(fd < 0) - return; - sprint(buf, "%d", sfd); - if(write(fd, buf, strlen(buf)) != strlen(buf)) - sysfatal("srv write: %r"); - close(fd); -} - -void -threadmain(int argc, char *argv[]) -{ - char *srvfile; - char *srvpost; - char *mntpt; - int i; - - mntpt = "/mnt"; - srvpost = nil; - - rfork(RFNOTEG); - - ARGBEGIN{ - case 'a': - aflag = 1; - break; - case 'm': - mntpt = ARGF(); - break; - case 'd': - debug = strtoul(ARGF(), nil, 0); - break; - case 's': - srvpost = ARGF(); - break; - default: - usage(); - }ARGEND - - user = strdup(getuser()); - - quotefmtinstall(); - - if(debug) - fmtinstall('F', fcallfmt); - - volumechan = chancreate(sizeof(volume), 1); - playchan = chancreate(sizeof(Wmsg), 1); - playlistreq = chancreate(sizeof(Wmsg), 0); /* No storage! requires rendez-vous */ - workers = chancreate(sizeof(Worker*), 256); - for(i = 1; i < Nqid; i++) - files[i].workers = chancreate(sizeof(Worker*), 256); - - if(pipe(srvfd) < 0) - sysfatal("pipe failed: %r"); - procrfork(srv, nil, 8192, RFFDG); - close(srvfd[0]); /* don't deadlock if child fails */ - - procrfork(volumeproc, nil, 8192, RFFDG); - playinit(); - - if(srvpost){ - srvfile = smprint("/srv/playlist.%s", srvpost); - remove(srvfile); - post(srvfile, srvfd[1]); - free(srvfile); - } - if(mount(srvfd[1], -1, mntpt, MBEFORE, "") < 0) - sysfatal("mount failed: %r"); - threadexits(nil); -} diff --git a/sys/src/games/music/playlistfs/mk.dep b/sys/src/games/music/playlistfs/mk.dep deleted file mode 100644 index 4bba8a1d7..000000000 --- a/sys/src/games/music/playlistfs/mk.dep +++ /dev/null @@ -1,5 +0,0 @@ -main.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/fcall.h playlist.h -fs.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/fcall.h /sys/include/pool.h playlist.h -player.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/fcall.h /sys/include/pool.h playlist.h -volume.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/fcall.h /sys/include/pool.h playlist.h -boilerplate.$O: /$objtype/include/u.h /sys/include/libc.h /sys/include/thread.h /sys/include/fcall.h playlist.h diff --git a/sys/src/games/music/playlistfs/mkfile b/sys/src/games/music/playlistfs/mkfile deleted file mode 100644 index e7bba2333..000000000 --- a/sys/src/games/music/playlistfs/mkfile +++ /dev/null @@ -1,16 +0,0 @@ - -#include -#include -#include -#include "pool.h" -#include "playlist.h" - -typedef struct Playfd Playfd; - -struct Playfd { - /* Describes a file to play for starting up pac4dec/mp3,... */ - char *filename; /* mallocated */ - int fd; /* filedesc to use */ - int cfd; /* fildesc to close */ -}; - -Channel *full, *empty, *playout, *spare; -Channel *playc, *pacc; - -ulong totbytes, totbuffers; - -static char curfile[8192]; - -void -decexec(void *a) -{ - char buf[256]; - Playfd *pfd; - Pacbuf *pb; - - threadsetname("decexec"); - pfd = a; - close(pfd->cfd); /* read fd */ - if(pfd->fd != 1){ - dup(pfd->fd, 1); - close(pfd->fd); - } - close(0); open("/dev/null", OREAD); - close(2); open("/dev/null", OWRITE); - strncpy(buf, pfd->filename, sizeof(buf)-1); - buf[sizeof(buf)-1] = 0; - free(pfd->filename); - free(pfd); - procexecl(nil, "/bin/play", "play", "-o", "/fd/1", buf, nil); - if((pb = nbrecvp(spare)) == nil) - pb = malloc(sizeof(Pacbuf)); - pb->cmd = Error; - pb->off = 0; - pb->len = snprint(pb->data, sizeof(pb->data), "startplay: exec play failed"); - sendp(full, pb); - threadexits("exec"); -} - -static int -startplay(ushort n) -{ - int fd[2]; - Playfd *pfd; - char *file; - - file = getplaylist(n); - if(file == nil) - return Undef; - if (debug & DbgPlayer) - fprint(2, "startplay: file is `%s'\n", file); - if(pipe(fd) < 0) - sysfatal("pipe: %r"); - pfd = malloc(sizeof(Playfd)); - pfd->filename = file; /* mallocated already */ - pfd->fd = fd[1]; - pfd->cfd = fd[0]; - procrfork(decexec, pfd, 4096, RFFDG|RFENVG); - close(fd[1]); /* write fd, for pac4dec */ - return fd[0]; /* read fd */ -} - -static void -rtsched(void) -{ - int fd; - char *ctl; - - ctl = smprint("/proc/%ud/ctl", getpid()); - if((fd = open(ctl, OWRITE)) < 0) - sysfatal("%s: %r", ctl); - if(fprint(fd, "period 20ms") < 0) - sysfatal("%s: %r", ctl); - if(fprint(fd, "cost 100µs") < 0) - sysfatal("%s: %r", ctl); - if(fprint(fd, "sporadic") < 0) - sysfatal("%s: %r", ctl); - if(fprint(fd, "admit") < 0) - sysfatal("%s: %r", ctl); - close(fd); - free(ctl); -} - -static void -boost(void) -{ - int fd; - char *ctl; - - ctl = smprint("/proc/%ud/ctl", getpid()); - if((fd = open(ctl, OWRITE)) >= 0) { - fprint(fd, "pri 13"); - close(fd); - } - free(ctl); -} - -void -decproc(void*) -{ - Pmsg playstate, newstate; - int fd; - Pacbuf *pb; - Alt a[3] = { - {empty, &pb, CHANNOP}, - {playc, &newstate.m, CHANRCV}, - {nil, nil, CHANEND}, - }; - - threadsetname("decproc"); - close(srvfd[1]); - newstate.cmd = playstate.cmd = Stop; - newstate.off = playstate.off = 0; - fd = -1; - for(;;){ - switch(alt(a)){ - case 0: - /* Play out next buffer (pb points to one already) */ - assert(fd >= 0); /* Because we must be in Play mode */ - pb->m = playstate.m; - pb->len = read(fd, pb->data, sizeof pb->data); - if(pb->len > 0){ - sendp(full, pb); - break; - } - if(pb->len < 0){ - if(debug & DbgPlayer) - fprint(2, "pac, error: %d\n", playstate.off); - pb->cmd = Error; - pb->len = snprint(pb->data, sizeof pb->data, "%s: %r", curfile); - sendp(full, pb); - }else{ - /* Simple end of file */ - sendp(empty, pb); /* Don't need buffer after all */ - } - close(fd); - fd = -1; - if(debug & DbgPlayer) - fprint(2, "pac, eof: %d\n", playstate.off); - /* End of file, do next by falling through */ - newstate.cmd = playstate.cmd; - newstate.off = playstate.off + 1; - case 1: - if((debug & DbgPac) && newstate.cmd) - fprint(2, "Pacproc: newstate %s-%d, playstate %s-%d\n", - statetxt[newstate.cmd], newstate.off, - statetxt[playstate.cmd], playstate.off); - /* Deal with an incoming command */ - if(newstate.cmd == Pause || newstate.cmd == Resume){ - /* Just pass them on, don't change local state */ - pb = recvp(spare); - pb->m = newstate.m; - sendp(full, pb); - break; - } - /* Stop whatever we're doing */ - if(fd >= 0){ - if(debug & DbgPlayer) - fprint(2, "pac, stop\n"); - /* Stop any active (pac) decoders */ - close(fd); - fd = -1; - } - a[0].op = CHANNOP; - switch(newstate.cmd){ - default: - sysfatal("decproc: unexpected newstate %d", newstate.cmd); - case Stop: - /* Wait for state to change */ - break; - case Skip: - case Play: - fd = startplay(newstate.off); - if(fd >=0){ - playstate = newstate; - a[0].op = CHANRCV; - continue; /* Start reading */ - } - newstate.cmd = Stop; - } - pb = recvp(spare); - pb->m = newstate.m; - sendp(full, pb); - playstate = newstate; - } - } -} - -void -pcmproc(void*) -{ - Pmsg localstate, newstate, prevstate; - int fd, n; - Pacbuf *pb, *b; - Alt a[3] = { - {full, &pb, CHANRCV}, - {playout, &pb, CHANRCV}, - {nil, nil, CHANEND}, - }; - - /* - * This is the real-time proc. - * It gets its input from two sources, full data/control buffers from the decproc - * which mixes decoded data with control messages, and data buffers from the pcmproc's - * (*this* proc's) own internal playout buffer. - * When a command is received on the `full' channel containing a command that warrants - * an immediate change of audio source (e.g., to silence or to another number), we just - * toss everything in the pipeline -- i.e., the playout channel - * Finally, we report all state changes using `playupdate' (another message channel) - */ - threadsetname("pcmproc"); - close(srvfd[1]); - fd = -1; - localstate.cmd = 0; /* Force initial playupdate */ - newstate.cmd = Stop; - newstate.off = 0; -// rtsched(); - boost(); - for(;;){ - if(newstate.m != localstate.m){ - playupdate(newstate, nil); - localstate = newstate; - } - switch(alt(a)){ - case 0: - /* buffer received from decproc */ - if((debug & DbgPcm) && localstate.m != prevstate.m){ - fprint(2, "pcm, full: %s-%d, local state is %s-%d\n", - statetxt[pb->cmd], pb->off, - statetxt[localstate.cmd], localstate.off); - prevstate.m = localstate.m; - } - switch(pb->cmd){ - default: - sysfatal("pcmproc: unknown newstate: %s-%d", statetxt[pb->cmd], pb->off); - case Resume: - a[1].op = CHANRCV; - newstate.cmd = Play; - break; - case Pause: - a[1].op = CHANNOP; - newstate.cmd = Pause; - if(fd >= 0){ - close(fd); - fd = -1; - } - break; - case Stop: - /* Dump all data in the buffer */ - while(b = nbrecvp(playout)) - if(b->cmd == Error){ - playupdate(b->Pmsg, b->data); - sendp(spare, b); - }else - sendp(empty, b); - newstate.m = pb->m; - a[1].op = CHANRCV; - if(fd >= 0){ - close(fd); - fd = -1; - } - break; - case Skip: - /* Dump all data in the buffer, then fall through */ - while(b = nbrecvp(playout)) - if(b->cmd == Error){ - playupdate(pb->Pmsg, pb->data); - sendp(spare, pb); - }else - sendp(empty, b); - a[1].op = CHANRCV; - newstate.cmd = Play; - case Error: - case Play: - /* deal with at playout, just requeue */ - sendp(playout, pb); - pb = nil; - localstate = newstate; - break; - } - /* If we still have a buffer, free it */ - if(pb) - sendp(spare, pb); - break; - case 1: - /* internal buffer */ - if((debug & DbgPlayer) && localstate.m != prevstate.m){ - fprint(2, "pcm, playout: %s-%d, local state is %s-%d\n", - statetxt[pb->cmd], pb->off, - statetxt[localstate.cmd], localstate.off); - prevstate.m = localstate.m; - } - switch(pb->cmd){ - default: - sysfatal("pcmproc: unknown newstate: %s-%d", statetxt[pb->cmd], pb->off); - case Error: - playupdate(pb->Pmsg, pb->data); - localstate = newstate; - sendp(spare, pb); - break; - case Play: - if(fd < 0 && (fd = open("/dev/audio", OWRITE)) < 0){ - a[1].op = CHANNOP; - newstate.cmd = Pause; - pb->cmd = Error; - snprint(pb->data, sizeof(pb->data), - "/dev/audio: %r"); - playupdate(pb->Pmsg, pb->data); - sendp(empty, pb); - break; - } - /* play out this buffer */ - totbytes += pb->len; - totbuffers++; - n = write(fd, pb->data, pb->len); - if (n != pb->len){ - if (debug & DbgPlayer) - fprint(2, "pcmproc: file %d: %r\n", pb->off); - if (n < 0) - sysfatal("pcmproc: write: %r"); - } - newstate.m = pb->m; - sendp(empty, pb); - break; - } - break; - } - } -} - -void -playinit(void) -{ - int i; - - full = chancreate(sizeof(Pacbuf*), 1); - empty = chancreate(sizeof(Pacbuf*), NPacbuf); - spare = chancreate(sizeof(Pacbuf*), NSparebuf); - playout = chancreate(sizeof(Pacbuf*), NPacbuf+NSparebuf); - for(i = 0; i < NPacbuf; i++) - sendp(empty, malloc(sizeof(Pacbuf))); - for(i = 0; i < NSparebuf; i++) - sendp(spare, malloc(sizeof(Pacbuf))); - - playc = chancreate(sizeof(ulong), 1); - procrfork(decproc, nil, 32*1024, RFFDG); - procrfork(pcmproc, nil, 32*1024, RFFDG); -} - -char * -getplaystat(char *p, char *e) -{ - p = seprint(p, e, "empty buffers %d of %d\n", empty->n, empty->s); - p = seprint(p, e, "full buffers %d of %d\n", full->n, full->s); - p = seprint(p, e, "playout buffers %d of %d\n", playout->n, playout->s); - p = seprint(p, e, "spare buffers %d of %d\n", spare->n, spare->s); - p = seprint(p, e, "bytes %lud / buffers %lud played\n", totbytes, totbuffers); - return p; -} diff --git a/sys/src/games/music/playlistfs/playlist.h b/sys/src/games/music/playlistfs/playlist.h deleted file mode 100644 index ba9259767..000000000 --- a/sys/src/games/music/playlistfs/playlist.h +++ /dev/null @@ -1,147 +0,0 @@ -typedef struct Worker Worker; -typedef struct Req Req; -typedef struct Fid Fid; -typedef struct File File; -typedef struct Playlist Playlist; -typedef struct Wmsg Wmsg; -typedef union Pmsg Pmsg; -typedef struct Pacbuf Pacbuf; - -enum { - Qdir, - Qplayctl, - Qplaylist, - Qplayvol, - Qplaystat, - Nqid, -}; - -enum { - DbgPcm = 0x01000, - DbgPac = 0x02000, - DbgFs = 0x10000, - DbgWorker = 0x20000, - DbgPlayer = 0x40000, - DbgError = 0x80000, -}; - -enum { - Messagesize = 8*1024+IOHDRSZ, - Undef = 0x80000000, - /* 256 buffers of 4096 bytes represents 5.9 seconds - * of playout at 44100 Hz (2*16bit samples) - */ - NPacbuf = 256, - Pacbufsize = 4096, - NSparebuf = 16, /* For in-line commands (Pause, Resume, Error) */ -}; - -enum { - /* Named commands (see fs.c): */ - Nostate, // can't use zero for state - Error, - Stop, - Pause, - Play, - Resume, - Skip, - /* Unnamed commands */ - Work, - Check, - Flush, - Prep, - Preq, -}; - -union Pmsg { - ulong m; - struct{ - ushort cmd; - ushort off; - }; -}; - -struct Wmsg { - Pmsg; - void *arg; /* if(cmd != Work) mallocated by sender, freed by receiver */ -}; - -struct Playlist { - /* The play list consists of a sequence of {objectref, filename} - * entries. Object ref and file name are separated by a tab. - * An object ref may not contain a tab. Entries are seperated - * by newline characters. Neither file names, nor object refs - * may contain newlines. - */ - ulong *lines; - ulong nlines; - char *data; - ulong ndata; -}; - -struct File { - Dir dir; - Channel *workers; -}; - -struct Worker -{ - Req *r; - Channel *eventc; -}; - -struct Fid -{ - int fid; - File *file; - ushort flags; - short readers; - ulong vers; /* set to file's version when completely read */ - Fid *next; -}; - -struct Req -{ - uchar indata[Messagesize]; - uchar outdata[Messagesize]; - Fcall ifcall; - Fcall ofcall; - Fid* fid; -}; - -struct Pacbuf { - Pmsg; - int len; - char data[Pacbufsize]; -}; - -void allocwork(Req*); -Wmsg waitmsg(Worker*, Channel*); -int sendmsg(Channel*, Wmsg*); -void bcastmsg(Channel*, Wmsg*); -void reqfree(Req*); -Req *reqalloc(void); -void readbuf(Req*, void*, long); -void readstr(Req*, char*); -void volumeset(int *v); -void playupdate(Pmsg, char*); -void playinit(void); -void volumeproc(void*); -void srv(void *); -long robustread(int, void*, long); -void volumeupdate(int*); -char *getplaylist(int); -char *getplaystat(char*, char*); - -extern int debug, aflag; -extern char *user; -extern Channel *playc; -extern char *statetxt[]; -extern int volume[8]; -extern Playlist playlist; -extern Channel *workers; -extern Channel *volumechan; -extern Channel *playchan; -extern Channel *playlistreq; -extern File files[]; -extern int srvfd[]; diff --git a/sys/src/games/music/playlistfs/playplumb.c b/sys/src/games/music/playlistfs/playplumb.c deleted file mode 100644 index 2533359ab..000000000 --- a/sys/src/games/music/playlistfs/playplumb.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -void -main(int argc, char *argv[]) -{ - Plumbmsg *m; - int fd; - - fd = plumbopen("audioplay", OREAD); - if (fd < 0) - sysfatal("port audioplay: %r"); - for (;;) { - m = plumbrecv(fd); - if (m == nil) - sysfatal("plumrecv: %r"); - - plumbfree(m); - } -} diff --git a/sys/src/games/music/playlistfs/volume.c b/sys/src/games/music/playlistfs/volume.c deleted file mode 100644 index d1bb3740e..000000000 --- a/sys/src/games/music/playlistfs/volume.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include -#include "pool.h" -#include "playlist.h" - -int minvolume, maxvolume; - -void -volumeproc(void *) -{ - int fd, n, nf, i, nlines; - static char buf[1024]; - char *lines[32]; - char *fields[8]; - char *subfields[9]; - int volume[8], nvolumes; - - threadsetname("volumeproc"); - close(srvfd[1]); - fd = open("/dev/audioctl", OREAD); - if (fd < 0) - threadexits(nil); - for(;;){ - n = read(fd, buf, sizeof buf -1); - if (n == 0) - continue; - if (n < 0){ - fprint(2, "volumeproc: read: %r\n"); - threadexits("volumeproc"); - } - buf[n] = '\0'; - nlines = getfields(buf, lines, nelem(lines), 1, "\n"); - for(i = 0; i < nlines; i++){ - nf = tokenize(lines[i], fields, nelem(fields)); - if (nf == 0) - continue; - if (nf != 6 || strcmp(fields[0], "volume") || strcmp(fields[1], "out")) - continue; - minvolume = strtol(fields[3], nil, 0); - maxvolume = strtol(fields[4], nil, 0); - if (minvolume >= maxvolume) - continue; - nvolumes = tokenize(fields[2], subfields, nelem(subfields)); - if (nvolumes <= 0 || nvolumes > 8) - sysfatal("bad volume data"); - if (debug) - fprint(2, "volume changed to '"); - for (i = 0; i < nvolumes; i++){ - volume[i] = strtol(subfields[i], nil, 0); - volume[i]= 100*(volume[i]- minvolume)/(maxvolume-minvolume); - if (debug) - fprint(2, " %d", volume[i]); - } - if (debug) - fprint(2, "'\n"); - while (i < 8) - volume[i++] = Undef; - send(volumechan, volume); - } - } -} - -void -volumeset(int *v) -{ - int fd, i; - char buf[256], *p; - - fd = open("/dev/audioctl", OWRITE); - if (fd < 0){ - fd = open("/dev/volume", OWRITE); - if (fd < 0){ - fprint(2, "Can't set volume: %r"); - return; - } - fprint(fd, "audio out %d", v[0]); - send(volumechan, v); - } else { - p = buf; - for (i = 0; i < 8; i++){ - if (v[i] == Undef) break; - p = seprint(p, buf+sizeof buf, (p==buf)?"volume out '%d":" %d", - minvolume + v[i] * (maxvolume-minvolume) / 100); - } - p = seprint(p, buf+sizeof buf, "'\n"); - write(fd, buf, p-buf); - } - close(fd); -} diff --git a/sys/src/games/music/readcd b/sys/src/games/music/readcd deleted file mode 100644 index 47ee84475..000000000 --- a/sys/src/games/music/readcd +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/rc - -cdrom=/dev/sdC1 - -switch($#*){ -case 3 - starttrack = `{echo $1 - 1 | hoc} - endtrack = `{echo $2 - 1 | hoc} - desttrack = $3 -case * - echo Usage readcd starttrack endtrack desttrack -} - -if(test -e /mnt/cd/ctl){ - echo -n ingest >/mnt/cd/ctl >[2]/dev/null -} -if not { - if (~ $cdrom '') cdfs - if not cdfs -d $cdrom -} - ->/tmp/readcd ->/tmp/map -cat /mnt/cd/ctl -sed 1q /mnt/cd/ctl | rc -echo $starttrack $endtrack $desttrack | awk '{ - start = $1 - finish = $2 - dest = $3 - print "read cd tracks " start "-" finish " starting at " dest - for (i = start; i <= finish; i++) { - cmd = sprintf("ls -l /mnt/cd/a%3.3d | awk ''{print $6}''>>/tmp/readcd", i) - system(cmd) - getline x<"/tmp/readcd" - sec = x/44100/4 - min = sec/60 - sec = sec%60 - printf("track {\n\t\n\tfile {%3.3d}\n\ttime {%d:%2.2d}\n}\n",i+dest-start,min,sec)>"/tmp/map" - } - for (i = start; i <= finish; i++) { - cmd = sprintf("/bin/games/pacenc /mnt/cd/a%3.3d %3.3d",i,i+dest-start) - print cmd - system(cmd) - } -}' -echo eject >/mnt/cd/ctl