Switch to side-by-side view

--- a/upmpd/upmpd.cxx
+++ b/upmpd/upmpd.cxx
@@ -41,8 +41,12 @@
 // The UPnP MPD frontend device with its 2 services
 class UpMpd : public UpnpDevice {
 public:
+	enum Options {
+		upmpdNone,
+		upmpdOwnQueue, // The MPD belongs to us, we shall clear it as we like
+	};
 	UpMpd(const string& deviceid, const unordered_map<string, string>& xmlfiles,
-		  MPDCli *mpdcli);
+		  MPDCli *mpdcli, Options opts = upmpdNone);
 
 	// RenderingControl
 	int setMute(const SoapArgs& sc, SoapData& data);
@@ -96,6 +100,7 @@
 	// changes to avoid saturating with small requests.
 	int m_desiredvolume;
 
+	int m_options;
 };
 
 static const string serviceIdRender("urn:upnp-org:serviceId:RenderingControl");
@@ -103,8 +108,9 @@
 
 UpMpd::UpMpd(const string& deviceid, 
 			 const unordered_map<string, string>& xmlfiles,
-			 MPDCli *mpdcli)
-	: UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_desiredvolume(-1)
+			 MPDCli *mpdcli, Options opts)
+	: UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_desiredvolume(-1),
+	  m_options(opts)
 {
 	addServiceType(serviceIdRender,
 				   "urn:schemas-upnp-org:service:RenderingControl:1");
@@ -629,6 +635,14 @@
 	if (it != sc.args.end())
 		metadata = it->second;
 
+	if ((m_options & upmpdOwnQueue) && !setnext) {
+		// If we own the queue, just clear it before setting the
+		// track.  Else it's difficult to impossible to prevent it
+		// from growing if upmpdcli restarts. If the option is not set, the
+		// user prefers to live with the issue.
+		m_mpdcli->clearQueue();
+	}
+
 	const struct MpdStatus &mpds = m_mpdcli->getStatus();
 	bool is_song = (mpds.state == MpdStatus::MPDS_PLAY) || 
 		(mpds.state == MpdStatus::MPDS_PAUSE);
@@ -639,8 +653,9 @@
 
 	// curpos == -1 means that the playlist was cleared or we just started. A
 	// play will use position 0, so it's actually equivalent to curpos == 0
-	if (curpos == -1)
+	if (curpos == -1) {
 		curpos = 0;
+	}
 
 	if (mpds.qlen == 0 && setnext) {
 		LOGDEB("setNextAVTRansportURI invoked but empty queue!" << endl);
@@ -974,6 +989,8 @@
 #define OPT_c     0x20
 #define OPT_l     0x40
 #define OPT_f     0x80
+#define OPT_q     0x100
+
 static const char usage[] = 
 "-c configfile \t configuration file to use\n"
 "-h host    \t specify host MPD is running on\n"
@@ -982,6 +999,7 @@
 "-l loglevel\t  log level (0-6)\n"
 "-D          \t run as a daemon\n"
 "-f friendlyname\t define device displayed name\n"
+"-q 0|1      \t if set, we own the mpd queue, else avoid clearing it whenever we feel like it"
 "  \n\n"
 			;
 static void
@@ -1005,6 +1023,7 @@
 	int loglevel(upnppdebug::Logger::LLINF);
 	string configfile;
 	string friendlyname(dfltFriendlyName);
+	bool ownqueue = true;
 
 	const char *cp;
 	if ((cp = getenv("UPMPD_HOST")))
@@ -1037,6 +1056,8 @@
 				loglevel = atoi(*(++argv)); argc--; goto b1;
 			case 'p':	op_flags |= OPT_p; if (argc < 2)  Usage();
 				mpdport = atoi(*(++argv)); argc--; goto b1;
+			case 'q':	op_flags |= OPT_q; if (argc < 2)  Usage();
+				ownqueue = atoi(*(++argv)) != 0; argc--; goto b1;
 			default: Usage();	break;
 			}
 	b1: argc--; argv++;
@@ -1063,6 +1084,9 @@
 		if (!(op_flags & OPT_p) && config.get("mpdport", value)) {
 			mpdport = atoi(value.c_str());
 		}
+		if (!(op_flags & OPT_q) && config.get("ownqueue", value)) {
+			ownqueue = atoi(value.c_str()) != 0;
+		}
 	}
 
 	if (upnppdebug::Logger::getTheLog(logfilename) == 0) {
@@ -1135,7 +1159,8 @@
 	xmlfiles["AVTransport.xml"] = avt_scdp;
 
 	// Initialize the UPnP device object.
-	UpMpd device(string("uuid:") + UUID, xmlfiles, &mpdcli);
+	UpMpd device(string("uuid:") + UUID, xmlfiles, &mpdcli,
+				 ownqueue?UpMpd::upmpdOwnQueue:UpMpd::upmpdNone);
 
 	LOGDEB("Entering event loop" << endl);