Major changes to webserver backend. All socket functions are abstracted to allow support for stream_* which seems to be both more widely supported and better at handling blocking and timeouts, at the cost of a small bit of speed. Keep-Alive times out properly and thanks to a bit of IPC code from stream_create_pair(), zombie children are mostly eliminated by proper pcntl_wait() being called when a child shuts down normally, and children die within 0.2sec if the parent receives a SIGTERM or SIGINT, even if the children are waiting on the socket.
/**
* Based upon the AmaroK WebControl interface by:
* Jonas Christian Drewsen ( kde at xspect dot dk )
* André Kelpe ( fs111 at web dot de )
* Peter C. Ndikuwera ( pndiku at gmail dot com )
*/
body {
font-family: sans-serif;
background-color: #9cb2cd;
color: #ffffff;
margin: 0;
padding: 0;
width: 320px;
}
div.tblholder {
padding: 1px;
background-color: #ffffff;
border: 1px solid #000000;
}
div.tblholder table {
background-color: #596082;
}
tr th {
background-color: #697092;
}
tr.row1 td {
background-color: #394062;
}
tr.row2 td {
background-color: #202050;
}
tr.current td {
background-color: #495072;
color: #ffff00;
}
div#playbar {
width: 320px;
padding: 0;
margin: 0 0 10px 0;
background-image: url(images/playbar.gif);
background-repeat: repeat-x;
background-color: #383f61;
border-bottom: 1px solid #000000;
text-align: center;
position: absolute;
top: 0px;
left: 0px;
}
div.playbar-inner {
padding: 5px;
line-height: 22px;
}
a img {
border-width: 0;
}
div#playlist {
margin: 174px 8px 0 8px;
}
a.tracklink {
text-decoration: none;
color: white;
}
div.track_inner {
display: none;
}
div#playlist tr.current a.tracklink {
color: #ffff00;
}
span#playmeter, span#volume_wrap {
position: relative;
top: -7px;
}
a.volume_button {
padding-right: 18px;
margin-right: 1px;
background-color: #33395d;
border: 1px solid #909090;
text-decoration: none;
}
a.volume_button_active {
background-color: #9090c2;
border-color: #d0d0d0;
}
div#footer {
background-image: url(images/playbar.gif);
background-repeat: repeat-x;
text-align: center;
margin-top: 10px;
padding: 5px;
}
/* Position slider (playhead) */
div#playhead {
background-image: url(images/position-empty.png);
width: 250px;
background-repeat: no-repeat;
background-position: center center;
margin: 0 auto 10px auto;
}
div#playhead-filler {
background-image: url(images/position-full.png);
width: 150px;
background-repeat: no-repeat;
background-position: left center;
}
div#playhead-button {
background-image: url(images/playhead.png);
width: 16px;
height: 16px;
font-size: 1px;
position: absolute;
background-repeat: no-repeat;
background-position: center center;
}
/* The list of colors that will be cycled through as playback takes place */
tr.pulsar0 td { background-color: #47507a; }
tr.pulsar1 td { background-color: #424a73; }
tr.pulsar2 td { background-color: #3c436c; }
tr.pulsar3 td { background-color: #383d64; }
tr.pulsar4 td { background-color: #31365d; }
tr.pulsar5 td { background-color: #2c3155; }
tr.pulsar6 td { background-color: #272a4e; }
tr.pulsar7 td { background-color: #222447; }
tr.pulsar8 td { background-color: #1c1d3f; }
tr.pulsar9 td { background-color: #171738; }
div.poweredby {
font-size: smaller;
text-align: center;
margin: 10px 0;
}
div.poweredby a {
color: #57608a;
}