summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4510f23)
raw | patch | inline | side by side (parent: 4510f23)
author | Jonathan Neuschäfer <j.neuschaefer@gmx.net> | |
Wed, 4 Jan 2012 17:33:31 +0000 (18:33 +0100) | ||
committer | Jonathan Neuschäfer <j.neuschaefer@gmx.net> | |
Wed, 23 May 2012 01:50:50 +0000 (03:50 +0200) |
This patch adds basic functionality to the chat screen.
NEWS | patch | blob | history | |
src/screen_chat.c | patch | blob | history | |
src/screen_help.c | patch | blob | history |
index 0af6a1bfc8d9428d77bd8e64187a73891ccb9bc3..804b6d2dec35dfaeb2168c676db66e98dfaac8b8 100644 (file)
--- a/NEWS
+++ b/NEWS
ncmpc 0.21 - not yet released
+* add a chat screen for communication with other clients on the same server
ncmpc 0.20 - (02/05/2012)
diff --git a/src/screen_chat.c b/src/screen_chat.c
index 94aee1dcebb8bddd111140bfbfb9c47c3d18f897..b4d3aaca89844e97aa36d6dd4513577657a8e313 100644 (file)
--- a/src/screen_chat.c
+++ b/src/screen_chat.c
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "screen_chat.h"
+
#include "screen_interface.h"
+#include "screen_utils.h"
+#include "screen_status.h"
+#include "screen_text.h"
#include "mpdclient.h"
+#include "i18n.h"
+#include "charset.h"
+
+#include <glib.h>
+#include <mpd/idle.h>
+
+static struct screen_text text; /* rename? */
+static const char chat_channel[] = "chat";
static bool
-screen_chat_cmd(G_GNUC_UNUSED struct mpdclient *c,
- G_GNUC_UNUSED command_t cmd)
+check_chat_support(struct mpdclient *c)
+{
+ static unsigned last_connection_id = 0;
+ static bool was_supported = false;
+
+ /* if we're using the same connection as the last time
+ check_chat_support was called, we can use the cached information
+ about whether chat is supported */
+ if (c->connection_id == last_connection_id)
+ return was_supported;
+
+ last_connection_id = c->connection_id;
+
+ if (c->connection == NULL)
+ return (was_supported = false);
+
+ if (mpd_connection_cmp_server_version(c->connection, 0, 17, 0) == -1) {
+ const unsigned *version = mpd_connection_get_server_version(c->connection);
+ char *str;
+
+ str = g_strdup_printf(
+ _("connected to MPD %u.%u.%u (you need at least \n"
+ "version 0.17.0 to use the chat feature)"),
+ version[0], version[1], version[2]);
+ screen_text_append(&text, str);
+ g_free(str);
+
+ return (was_supported = false);
+ }
+
+ /* mpdclient_get_connection? */
+ if (!mpdclient_cmd_subscribe(c, chat_channel))
+ return (was_supported = false);
+ /* mpdclient_put_connection? */
+
+ return (was_supported = true);
+}
+
+static void
+screen_chat_init(WINDOW *w, int cols, int rows)
{
+ screen_text_init(&text, w, cols, rows);
+}
+
+static void
+screen_chat_exit(void)
+{
+ screen_text_deinit(&text);
+}
+
+static void
+screen_chat_open(struct mpdclient *c)
+{
+ (void) check_chat_support(c);
+}
+
+static void
+screen_chat_resize(int cols, int rows)
+{
+ screen_text_resize(&text, cols, rows);
+}
+
+static void
+screen_chat_paint(void)
+{
+ screen_text_paint(&text);
+}
+
+static void
+process_message(struct mpd_message *message)
+{
+ char *message_text;
+
+ assert(message != NULL);
+ /* You'll have to move this out of screen_chat, if you want to use
+ client-to-client messages anywhere else */
+ assert(g_strcmp0(mpd_message_get_channel(message), chat_channel) == 0);
+
+ message_text = utf8_to_locale(mpd_message_get_text(message));
+ screen_text_append(&text, message_text);
+ g_free(message_text);
+
+ screen_chat_paint();
+}
+
+static void
+screen_chat_update(struct mpdclient *c)
+{
+ if (check_chat_support(c) && (c->events & MPD_IDLE_MESSAGE)) {
+ if (!mpdclient_send_read_messages(c))
+ return;
+
+ struct mpd_message *message;
+ while ((message = mpdclient_recv_message(c)) != NULL) {
+ process_message(message);
+ mpd_message_free(message);
+ }
+
+ mpdclient_finish_command(c);
+
+ c->events &= ~MPD_IDLE_MESSAGE;
+ }
+}
+
+static void
+screen_chat_send_message(struct mpdclient *c, char *msg)
+{
+ char *utf8 = locale_to_utf8(msg);
+
+ (void) mpdclient_cmd_send_message(c, chat_channel, utf8);
+ g_free(utf8);
+}
+
+static bool
+screen_chat_cmd(struct mpdclient *c, command_t cmd)
+{
+ if (screen_text_cmd(&text, c, cmd))
+ return true;
+
+ if (cmd == CMD_PLAY) {
+ char *message = screen_readln(_("Your message"), NULL, NULL, NULL);
+
+ /* the user entered an empty line */
+ if (message == NULL)
+ return true;
+
+ if (check_chat_support(c))
+ screen_chat_send_message(c, message);
+ else
+ screen_status_message(_("Message could not be sent"));
+
+ g_free(message);
+
+ return true;
+ }
+
return false;
}
+static const char *
+screen_chat_title(G_GNUC_UNUSED char *s, G_GNUC_UNUSED size_t size)
+{
+ return _("Chat");
+}
+
const struct screen_functions screen_chat = {
+ .init = screen_chat_init,
+ .exit = screen_chat_exit,
+ .open = screen_chat_open,
+ /* close */
+ .resize = screen_chat_resize,
+ .paint = screen_chat_paint,
+ .update = screen_chat_update,
.cmd = screen_chat_cmd,
+ .get_title = screen_chat_title,
};
diff --git a/src/screen_help.c b/src/screen_help.c
index ed4db1fc2f668d17411ab662a0efc0486aadadc5..913ab5fa80884521a2da31c0faf29a1777b95cd7 100644 (file)
--- a/src/screen_help.c
+++ b/src/screen_help.c
{ 0, CMD_NONE, NULL },
{ 1, CMD_NONE, N_("Chat screen") },
{ 2, CMD_NONE, NULL },
- { 0, CMD_PLAY, N_("Write a message (not yet implemented)") },
+ { 0, CMD_PLAY, N_("Write a message") },
#endif
#ifdef ENABLE_KEYDEF_SCREEN
{ 0, CMD_NONE, NULL },