Code

b4d3aaca89844e97aa36d6dd4513577657a8e313
[ncmpc.git] / src / screen_chat.c
1 /* ncmpc (Ncurses MPD Client)
2  * (c) 2004-2012 The Music Player Daemon Project
3  * Project homepage: http://musicpd.org
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 2 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 along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
20 #include "screen_chat.h"
22 #include "screen_interface.h"
23 #include "screen_utils.h"
24 #include "screen_status.h"
25 #include "screen_text.h"
26 #include "mpdclient.h"
27 #include "i18n.h"
28 #include "charset.h"
30 #include <glib.h>
31 #include <mpd/idle.h>
33 static struct screen_text text; /* rename? */
34 static const char chat_channel[] = "chat";
36 static bool
37 check_chat_support(struct mpdclient *c)
38 {
39         static unsigned last_connection_id = 0;
40         static bool was_supported = false;
42         /* if we're using the same connection as the last time
43            check_chat_support was called, we can use the cached information
44            about whether chat is supported */
45         if (c->connection_id == last_connection_id)
46                 return was_supported;
48         last_connection_id = c->connection_id;
50         if (c->connection == NULL)
51                 return (was_supported = false);
53         if (mpd_connection_cmp_server_version(c->connection, 0, 17, 0) == -1) {
54                 const unsigned *version = mpd_connection_get_server_version(c->connection);
55                 char *str;
57                 str = g_strdup_printf(
58                         _("connected to MPD %u.%u.%u (you need at least \n"
59                           "version 0.17.0 to use the chat feature)"),
60                         version[0], version[1], version[2]);
61                 screen_text_append(&text, str);
62                 g_free(str);
64                 return (was_supported = false);
65         }
67         /* mpdclient_get_connection? */
68         if (!mpdclient_cmd_subscribe(c, chat_channel))
69                 return (was_supported = false);
70         /* mpdclient_put_connection? */
72         return (was_supported = true);
73 }
75 static void
76 screen_chat_init(WINDOW *w, int cols, int rows)
77 {
78         screen_text_init(&text, w, cols, rows);
79 }
81 static void
82 screen_chat_exit(void)
83 {
84         screen_text_deinit(&text);
85 }
87 static void
88 screen_chat_open(struct mpdclient *c)
89 {
90         (void) check_chat_support(c);
91 }
93 static void
94 screen_chat_resize(int cols, int rows)
95 {
96         screen_text_resize(&text, cols, rows);
97 }
99 static void
100 screen_chat_paint(void)
102         screen_text_paint(&text);
105 static void
106 process_message(struct mpd_message *message)
108         char *message_text;
110         assert(message != NULL);
111         /* You'll have to move this out of screen_chat, if you want to use
112            client-to-client messages anywhere else */
113         assert(g_strcmp0(mpd_message_get_channel(message), chat_channel) == 0);
115         message_text = utf8_to_locale(mpd_message_get_text(message));
116         screen_text_append(&text, message_text);
117         g_free(message_text);
119         screen_chat_paint();
122 static void
123 screen_chat_update(struct mpdclient *c)
125         if (check_chat_support(c) && (c->events & MPD_IDLE_MESSAGE)) {
126                 if (!mpdclient_send_read_messages(c))
127                         return;
129                 struct mpd_message *message;
130                 while ((message = mpdclient_recv_message(c)) != NULL) {
131                         process_message(message);
132                         mpd_message_free(message);
133                 }
135                 mpdclient_finish_command(c);
137                 c->events &= ~MPD_IDLE_MESSAGE;
138         }
141 static void
142 screen_chat_send_message(struct mpdclient *c, char *msg)
144         char *utf8 = locale_to_utf8(msg);
146         (void) mpdclient_cmd_send_message(c, chat_channel, utf8);
147         g_free(utf8);
150 static bool
151 screen_chat_cmd(struct mpdclient *c, command_t cmd)
153         if (screen_text_cmd(&text, c, cmd))
154                 return true;
156         if (cmd == CMD_PLAY) {
157                 char *message = screen_readln(_("Your message"), NULL, NULL, NULL);
159                 /* the user entered an empty line */
160                 if (message == NULL)
161                         return true;
163                 if (check_chat_support(c))
164                         screen_chat_send_message(c, message);
165                 else
166                         screen_status_message(_("Message could not be sent"));
168                 g_free(message);
170                 return true;
171         }
173         return false;
176 static const char *
177 screen_chat_title(G_GNUC_UNUSED char *s, G_GNUC_UNUSED size_t size)
179         return _("Chat");
182 const struct screen_functions screen_chat = {
183         .init = screen_chat_init,
184         .exit = screen_chat_exit,
185         .open = screen_chat_open,
186         /* close */
187         .resize = screen_chat_resize,
188         .paint = screen_chat_paint,
189         .update = screen_chat_update,
190         .cmd = screen_chat_cmd,
191         .get_title = screen_chat_title,
192 };