1 /* 2 Vimpc 3 Copyright (C) 2010 - 2012 Nathan Sweetman 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 mpdclient.hpp - provides interaction with the music player daemon 19 */ 20 21 #ifndef __MPC__CLIENT 22 #define __MPC__CLIENT 23 24 25 #include <mpd/client.h> 26 27 #include "compiler.hpp" 28 #include "output.hpp" 29 #include "screen.hpp" 30 #include "buffers.hpp" 31 #include "buffer/library.hpp" 32 #include "buffer/list.hpp" 33 #include "window/debug.hpp" 34 35 // The library check in 2.1.0 doesn't seem to work 36 // since we don't support versions older than that anyway, just return false 37 // instead of using the check macro 38 #if ((LIBMPDCLIENT_MAJOR_VERSION <= 2) && (LIBMPDCLIENT_MINOR_VERSION <= 1)) 39 #undef LIBMPDCLIENT_CHECK_VERSION 40 #define LIBMPDCLIENT_CHECK_VERSION(major, minor, patch) \ 41 ((major) < LIBMPDCLIENT_MAJOR_VERSION || \ 42 ((major) == LIBMPDCLIENT_MAJOR_VERSION && \ 43 ((minor) < LIBMPDCLIENT_MINOR_VERSION || \ 44 ((minor) == LIBMPDCLIENT_MINOR_VERSION && \ 45 (patch) <= LIBMPDCLIENT_PATCH_VERSION)))) 46 #endif 47 48 #ifndef LIBMPDCLIENT_MAJOR_VERSION 49 #define LIBMPDCLIENT_MAJOR_VERSION 0 50 #endif 51 #ifndef LIBMPDCLIENT_MINOR_VERSION 52 #define LIBMPDCLIENT_MINOR_VERSION 0 53 #endif 54 #ifndef LIBMPDCLIENT_PATCH_VERSION 55 #define LIBMPDCLIENT_PATCH_VERSION 0 56 #endif 57 58 namespace Main 59 { 60 class Settings; 61 class Vimpc; 62 } 63 64 namespace Ui 65 { 66 class Screen; 67 } 68 69 // \todo cache all the values that we can 70 namespace Mpc 71 { 72 class Client; 73 class Output; 74 class Song; 75 76 uint32_t SecondsToMinutes(uint32_t duration); 77 uint32_t RemainingSeconds(uint32_t duration); 78 79 class CommandList 80 { 81 public: 82 CommandList(Mpc::Client & client, bool condition = true); 83 ~CommandList(); 84 85 private: 86 bool condition_; 87 Mpc::Client & client_; 88 }; 89 90 class Client 91 { 92 friend class Mpc::CommandList; 93 94 public: 95 Client(Main::Vimpc * vimpc, Main::Settings & settings, Mpc::Lists & lists, Ui::Screen & screen); 96 ~Client(); 97 98 public: 99 void QueueCommand(FUNCTION<void()> const & function); 100 void WaitForCompletion(); 101 102 private: 103 Client(Client & client); 104 Client & operator=(Client & client); 105 106 public: 107 // Mpd Connections 108 void Connect(std::string const & hostname = "", uint16_t port = 0, uint32_t timeout_ms = 0); 109 void ConnectImpl(std::string const & hostname = "", uint16_t port = 0, uint32_t timeout_ms = 0); 110 void Disconnect(); 111 void Reconnect(); 112 void Password(std::string const & password); 113 114 public: 115 // Playback functions 116 void Play(uint32_t playId); 117 void Pause(); 118 void Stop(); 119 void Next(); 120 void Previous(); 121 void Seek(int32_t Offset); 122 void SeekTo(uint32_t Time); 123 void SeekToPercent(double Percent); 124 125 public: 126 // Toggle settings 127 void SetRandom(bool random); 128 void SetSingle(bool single); 129 void SetConsume(bool consume); 130 void SetRepeat(bool repeat); 131 void SetCrossfade(bool crossfade); 132 void SetCrossfade(uint32_t crossfade); 133 void SetVolume(uint32_t volume); 134 void SetMute(bool mute); 135 void DeltaVolume(int32_t Delta); 136 137 // Toggle settings 138 void ToggleRandom(); 139 void ToggleSingle(); 140 void ToggleConsume(); 141 void ToggleRepeat(); 142 void ToggleCrossfade(); 143 144 public: 145 // Playlist editing 146 void Shuffle(); 147 void Move(uint32_t position1, uint32_t position2); 148 void Swap(uint32_t position1, uint32_t position2); 149 150 public: 151 // Playlist management 152 bool HasPlaylist(std::string const & name); 153 bool HasLoadedPlaylist(); 154 void SaveLoadedPlaylist(); 155 void CreatePlaylist(std::string const & name); 156 void SavePlaylist(std::string const & name); 157 void LoadPlaylist(std::string const & name); 158 void AppendPlaylist(std::string const & name); 159 void RemovePlaylist(std::string const & name); 160 void AddToNamedPlaylist(std::string const & name, Mpc::Song * song); 161 162 void PlaylistContents(std::string const & name); 163 void PlaylistContentsForRemove(std::string const & name); 164 165 public: 166 // Outputs 167 void SetOutput(Mpc::Output * output, bool enable); 168 void EnableOutput(Mpc::Output * output); 169 void DisableOutput(Mpc::Output * output); 170 171 public: 172 // Queue manipulation 173 void Add(Mpc::Song * song); 174 void Add(std::vector<Mpc::Song *> song); 175 void Add(Mpc::Song & song); 176 void Add(Mpc::Song & song, uint32_t position); 177 void AddAllSongs(); 178 179 //! This add is only used by a command when a full uri is specified 180 //! it should not be used to add songs from the library, you should use the 181 //! versions above for that purpose 182 void Add(std::string const & URI); 183 184 // Call after all songs have been added 185 void AddComplete(); 186 187 void Delete(uint32_t position); 188 void Delete(uint32_t position1, uint32_t position2); 189 void Clear(); 190 191 public: 192 // Searching the database 193 void SearchAny(std::string const & search, bool exact = false); 194 void SearchArtist(std::string const & search, bool exact = false); 195 void SearchAlbum(std::string const & search, bool exact = false); 196 void SearchGenre(std::string const & search, bool exact = false); 197 void SearchSong(std::string const & search, bool exact = false); 198 void AddAllSearchResults(); 199 void SearchResults(std::string const & name); 200 201 public: 202 // Database state 203 void Rescan(std::string const & Path); 204 void Update(std::string const & Path); 205 void StartCommandList(); 206 void SendCommandList(); 207 void UpdateCurrentSong(); 208 void UpdateStatus(bool ExpectUpdate = false); 209 void QueueMetaChanges(); 210 211 public: 212 void GetAllOutputs(); 213 void GetAllMetaInformation(); 214 void GetAllMetaFromRoot(); 215 216 private: 217 bool Connected() const; 218 void IncrementTime(long time); 219 void StateEvent(); 220 void CheckForEvents(); 221 void IdleMode(); 222 void ExitIdleMode(); 223 void ClientQueueExecutor(Mpc::Client * client); 224 void SetStateAndEvent(int, bool & state, bool value); 225 226 private: 227 void ClearCommand(); 228 bool IsPasswordRequired(); 229 void Initialise(); 230 231 private: 232 unsigned int QueueVersion(); 233 Song * CreateSong(mpd_song const * const) const; 234 235 private: 236 void GetVersion(); 237 bool CheckError(); 238 void DeleteConnection(); 239 240 private: 241 Main::Vimpc * vimpc_; 242 Main::Settings & settings_; 243 struct mpd_connection * connection_; 244 int fd_; 245 246 std::string hostname_; 247 uint16_t port_; 248 uint32_t versionMajor_; 249 uint32_t versionMinor_; 250 uint32_t versionPatch_; 251 long timeSinceUpdate_; 252 bool retried_; 253 bool ready_; 254 255 uint32_t volume_; 256 uint32_t mVolume_; 257 bool mute_; 258 bool updating_; 259 bool random_; 260 bool repeat_; 261 bool single_; 262 bool consume_; 263 bool crossfade_; 264 uint32_t crossfadeTime_; 265 uint32_t elapsed_; 266 uint32_t mpdelapsed_; 267 mpd_state state_; 268 mpd_state mpdstate_; 269 270 struct mpd_song * currentSong_; 271 struct mpd_status * currentStatus_; 272 int32_t currentSongId_; 273 uint32_t totalNumberOfSongs_; 274 std::string currentSongURI_; 275 std::string currentState_; 276 277 Mpc::Lists * lists_; 278 std::string loadedList_; 279 280 Ui::Screen & screen_; 281 int queueVersion_; 282 int oldVersion_; 283 bool forceUpdate_; 284 bool listMode_; 285 bool idleMode_; 286 bool queueUpdate_; 287 bool autoscroll_; 288 Thread clientThread_; 289 290 bool error_; 291 }; 292 } 293 294 #endif 295 /* vim: set sw=3 ts=3: */ 296