Compiler.h: move to util/
[ncmpc-debian.git] / src / mpdclient.hxx
1 #ifndef MPDCLIENT_H
2 #define MPDCLIENT_H
3
4 #include "config.h"
5 #include "Queue.hxx"
6 #include "util/Compiler.h"
7
8 #include <mpd/client.h>
9
10 #include <string>
11
12 struct AsyncMpdConnect;
13 struct MpdQueue;
14 struct MpdIdleSource;
15 class FileList;
16
17 struct mpdclient {
18 #ifdef ENABLE_ASYNC_CONNECT
19         /**
20          * These settings are used to connect to MPD asynchronously.
21          */
22         struct mpd_settings *settings;
23
24 #ifndef _WIN32
25         /**
26          * A second set of settings, just in case #settings did not
27          * work.  This is only used if #settings refers to a local
28          * socket path, and this one is supposed to be a fallback to
29          * IP on the default port (6600).
30          */
31         struct mpd_settings *settings2;
32 #endif
33
34 #else
35         const char *host;
36         unsigned port;
37 #endif
38
39         const unsigned timeout_ms;
40
41         const char *const password;
42
43         /* playlist */
44         MpdQueue playlist;
45
46 #ifdef ENABLE_ASYNC_CONNECT
47         AsyncMpdConnect *async_connect = nullptr;
48 #endif
49
50         struct mpd_connection *connection = nullptr;
51
52         /**
53          * Tracks idle events.  It is automatically called by
54          * mpdclient_get_connection().
55          */
56         MpdIdleSource *source = nullptr;
57
58         struct mpd_status *status = nullptr;
59         const struct mpd_song *song = nullptr;
60
61         /**
62          * The GLib source id which re-enters MPD idle mode before the
63          * next main loop interation.
64          */
65         unsigned enter_idle_source_id = 0;
66
67         /**
68          * This attribute is incremented whenever the connection changes
69          * (i.e. on disconnection and (re-)connection).
70          */
71         unsigned connection_id = 0;
72
73         int volume = -1;
74
75         /**
76          * A bit mask of idle events occurred since the last update.
77          */
78         unsigned events = 0;
79
80         enum mpd_state state = MPD_STATE_UNKNOWN;
81
82 #if defined(ENABLE_ASYNC_CONNECT) && !defined(_WIN32)
83         bool connecting2;
84 #endif
85
86         /**
87          * This attribute is true when the connection is currently in
88          * "idle" mode, and the #mpd_glib_source waits for an event.
89          */
90         bool idle = false;
91
92         /**
93          * Is MPD currently playing?
94          */
95         bool playing = false;
96
97         /**
98          * Is MPD currently playing or paused?
99          */
100         bool playing_or_paused = false;
101
102         mpdclient(const char *host, unsigned port,
103                   unsigned _timeout_ms, const char *_password);
104
105         ~mpdclient() {
106                 Disconnect();
107
108 #ifdef ENABLE_ASYNC_CONNECT
109                 mpd_settings_free(settings);
110
111 #ifndef _WIN32
112                 if (settings2 != nullptr)
113                         mpd_settings_free(settings2);
114 #endif
115 #endif
116         }
117
118         /**
119          * Determine a human-readable "name" of the settings currently used to
120          * connect to MPD.
121          *
122          * @return an allocated string that needs to be freed (with g_free())
123          * by the caller
124          */
125         std::string GetSettingsName() const;
126
127         bool IsConnected() const {
128                 return connection != nullptr;
129         }
130
131         /**
132          * Is this object "dead"?  i.e. not connected and not
133          * currently doing anything to connect.
134          */
135         gcc_pure
136         bool IsDead() const {
137                 return connection == nullptr
138 #ifdef ENABLE_ASYNC_CONNECT
139                         && async_connect == nullptr
140 #endif
141                         ;
142         }
143
144         gcc_pure
145         const struct mpd_song *GetCurrentSong() const {
146                 return song != nullptr && playing_or_paused
147                         ? song
148                         : nullptr;
149         }
150
151         void Connect();
152
153         void Disconnect();
154
155         bool HandleError();
156
157         struct mpd_connection *GetConnection();
158
159         bool FinishCommand() {
160                 return mpd_response_finish(connection) || HandleError();
161         }
162
163         bool Update();
164
165 private:
166         bool UpdateQueue();
167         bool UpdateQueueChanges();
168 };
169
170 enum {
171         /**
172          * all idle events the version of libmpdclient, ncmpc is compiled
173          * against, supports
174          */
175         MPD_IDLE_ALL = MPD_IDLE_DATABASE
176                 | MPD_IDLE_STORED_PLAYLIST
177                 | MPD_IDLE_QUEUE
178                 | MPD_IDLE_PLAYER
179                 | MPD_IDLE_MIXER
180                 | MPD_IDLE_OUTPUT
181                 | MPD_IDLE_OPTIONS
182                 | MPD_IDLE_UPDATE
183                 | MPD_IDLE_STICKER
184                 | MPD_IDLE_SUBSCRIPTION
185                 | MPD_IDLE_MESSAGE
186 };
187
188 /*** MPD Commands  **********************************************************/
189
190 bool
191 mpdclient_cmd_crop(struct mpdclient *c);
192
193 bool
194 mpdclient_cmd_clear(struct mpdclient *c);
195
196 bool
197 mpdclient_cmd_volume(struct mpdclient *c, int value);
198
199 bool
200 mpdclient_cmd_volume_up(struct mpdclient *c);
201
202 bool
203 mpdclient_cmd_volume_down(struct mpdclient *c);
204
205 bool
206 mpdclient_cmd_add_path(struct mpdclient *c, const char *path);
207
208 bool
209 mpdclient_cmd_add(struct mpdclient *c, const struct mpd_song *song);
210
211 bool
212 mpdclient_cmd_delete(struct mpdclient *c, int index);
213
214 bool
215 mpdclient_cmd_delete_range(struct mpdclient *c, unsigned start, unsigned end);
216
217 bool
218 mpdclient_cmd_move(struct mpdclient *c, unsigned dest, unsigned src);
219
220 bool
221 mpdclient_cmd_subscribe(struct mpdclient *c, const char *channel);
222
223 bool
224 mpdclient_cmd_unsubscribe(struct mpdclient *c, const char *channel);
225
226 bool
227 mpdclient_cmd_send_message(struct mpdclient *c, const char *channel,
228                            const char *text);
229
230 #endif