screen_interface: make cols/rows unsigned
[ncmpc.git] / src / screen_chat.c
blobf79e73fcf7b0195b2a97885a6b0ab0e6ee640e36
1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2017 The Music Player Daemon Project
3 * Project homepage: http://musicpd.org
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.
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.
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.
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"
29 #include "options.h"
31 #include <glib.h>
32 #include <mpd/idle.h>
34 static struct screen_text text; /* rename? */
35 static const char chat_channel[] = "chat";
37 static bool
38 check_chat_support(struct mpdclient *c)
40 static unsigned last_connection_id = 0;
41 static bool was_supported = false;
43 /* if we're using the same connection as the last time
44 check_chat_support was called, we can use the cached information
45 about whether chat is supported */
46 if (c->connection_id == last_connection_id)
47 return was_supported;
49 last_connection_id = c->connection_id;
51 if (c->connection == NULL)
52 return (was_supported = false);
54 if (mpd_connection_cmp_server_version(c->connection, 0, 17, 0) == -1) {
55 const unsigned *version = mpd_connection_get_server_version(c->connection);
56 char *str;
58 str = g_strdup_printf(
59 _("connected to MPD %u.%u.%u (you need at least \n"
60 "version 0.17.0 to use the chat feature)"),
61 version[0], version[1], version[2]);
62 screen_text_append(&text, str);
63 g_free(str);
65 return (was_supported = false);
68 /* mpdclient_get_connection? */
69 if (!mpdclient_cmd_subscribe(c, chat_channel))
70 return (was_supported = false);
71 /* mpdclient_put_connection? */
73 return (was_supported = true);
76 static void
77 screen_chat_init(WINDOW *w, unsigned cols, unsigned rows)
79 screen_text_init(&text, w, cols, rows);
82 static void
83 screen_chat_exit(void)
85 screen_text_deinit(&text);
88 static void
89 screen_chat_open(struct mpdclient *c)
91 (void) check_chat_support(c);
94 static void
95 screen_chat_resize(unsigned cols, unsigned rows)
97 screen_text_resize(&text, cols, rows);
100 static void
101 screen_chat_paint(void)
103 screen_text_paint(&text);
106 static void
107 process_message(struct mpd_message *message)
109 assert(message != NULL);
110 /* You'll have to move this out of screen_chat, if you want to use
111 client-to-client messages anywhere else */
112 assert(g_strcmp0(mpd_message_get_channel(message), chat_channel) == 0);
114 char *message_text = utf8_to_locale(mpd_message_get_text(message));
115 screen_text_append(&text, message_text);
116 g_free(message_text);
118 screen_chat_paint();
121 static void
122 screen_chat_update(struct mpdclient *c)
124 if (check_chat_support(c) && (c->events & MPD_IDLE_MESSAGE)) {
125 if (!mpdclient_send_read_messages(c))
126 return;
128 struct mpd_message *message;
129 while ((message = mpdclient_recv_message(c)) != NULL) {
130 process_message(message);
131 mpd_message_free(message);
134 mpdclient_finish_command(c);
136 c->events &= ~MPD_IDLE_MESSAGE;
140 static char *
141 screen_chat_get_prefix(void)
143 static char *prefix = NULL;
145 if (prefix)
146 return prefix;
148 if (options.chat_prefix) {
149 /* Options are encoded in the "locale" charset */
150 prefix = locale_to_utf8(options.chat_prefix);
151 return prefix;
154 prefix = g_strconcat("<", g_get_user_name(), "> ", NULL);
155 return prefix;
158 static void
159 screen_chat_send_message(struct mpdclient *c, char *msg)
161 char *utf8 = locale_to_utf8(msg);
162 char *prefix = screen_chat_get_prefix();
163 char *full_msg = g_strconcat(prefix, utf8, NULL);
164 g_free(utf8);
166 (void) mpdclient_cmd_send_message(c, chat_channel, full_msg);
167 g_free(full_msg);
170 static bool
171 screen_chat_cmd(struct mpdclient *c, command_t cmd)
173 if (screen_text_cmd(&text, c, cmd))
174 return true;
176 if (cmd == CMD_PLAY) {
177 char *message = screen_readln(_("Your message"), NULL, NULL, NULL);
179 /* the user entered an empty line */
180 if (message == NULL)
181 return true;
183 if (check_chat_support(c))
184 screen_chat_send_message(c, message);
185 else
186 screen_status_message(_("Message could not be sent"));
188 g_free(message);
190 return true;
193 return false;
196 static const char *
197 screen_chat_title(gcc_unused char *s, gcc_unused size_t size)
199 return _("Chat");
202 const struct screen_functions screen_chat = {
203 .init = screen_chat_init,
204 .exit = screen_chat_exit,
205 .open = screen_chat_open,
206 /* close */
207 .resize = screen_chat_resize,
208 .paint = screen_chat_paint,
209 .update = screen_chat_update,
210 .cmd = screen_chat_cmd,
211 .get_title = screen_chat_title,