From: Jonathan Neuschäfer Date: Wed, 4 Jan 2012 17:33:31 +0000 (+0100) Subject: screen_chat: make it useful X-Git-Tag: release-0.21~25^2~2 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=bf7dc3e0c2779ef1a8e1bc08e3a76e19784514bb;p=ncmpc.git screen_chat: make it useful This patch adds basic functionality to the chat screen. --- diff --git a/NEWS b/NEWS index 0af6a1b..804b6d2 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ 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 94aee1d..b4d3aac 100644 --- a/src/screen_chat.c +++ b/src/screen_chat.c @@ -17,16 +17,176 @@ * 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 +#include + +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 ed4db1f..913ab5f 100644 --- a/src/screen_help.c +++ b/src/screen_help.c @@ -181,7 +181,7 @@ static const struct help_text_row help_text[] = { { 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 },