diff options
-rw-r--r-- | doc/user-guide/commands.xml | 27 | ||||
-rw-r--r-- | irc.c | 1 | ||||
-rw-r--r-- | irc.h | 1 | ||||
-rw-r--r-- | irc_im.c | 54 | ||||
-rw-r--r-- | irc_util.c | 12 | ||||
-rw-r--r-- | protocols/bee.h | 4 | ||||
-rw-r--r-- | protocols/bee_chat.c | 9 | ||||
-rw-r--r-- | protocols/bee_user.c | 6 | ||||
-rw-r--r-- | protocols/nogaim.h | 3 |
9 files changed, 98 insertions, 19 deletions
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index d671f6d0..32c3b24e 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -1403,6 +1403,33 @@ </description> </bitlbee-setting> + <bitlbee-setting name="self_messages" type="string" scope="global"> + <default>true</default> + <possible-values>true, false, prefix, prefix_notice</possible-values> + + <description> + <para> + Change this setting to customize how (or whether) to show self-messages, which are messages sent by yourself from other locations (for example, mobile clients), for IM protocols that support it. + </para> + + <para> + When this is set to "true", it will send those messages in the "standard" way, which is a PRIVMSG with source and target fields swapped. + </para> + + <para> + Since this isn't very well supported by some clients (the messages might appear in the wrong window), you can set it to "prefix" to show them as a normal message prefixed with "-> ", or use "prefix_notice" which is the same thing but with a NOTICE instead. + </para> + + <para> + You can also set it to "false" to disable these messages completely. + </para> + + <para> + This setting only applies to private messages. Self messages in groupchats are always shown, since they haven't caused issues in any clients so far. + </para> + </description> + </bitlbee-setting> + <bitlbee-setting name="server" type="string" scope="account"> <description> <para> @@ -128,6 +128,7 @@ irc_t *irc_new(int fd) s->flags |= SET_HIDDEN; s = set_add(&b->set, "show_offline", "false", set_eval_bw_compat, irc); s->flags |= SET_HIDDEN; + s = set_add(&b->set, "self_messages", "true", set_eval_self_messages, irc); s = set_add(&b->set, "simulate_netsplit", "true", set_eval_bool, irc); s = set_add(&b->set, "timezone", "local", set_eval_timezone, irc); s = set_add(&b->set, "to_char", ": ", set_eval_to_char, irc); @@ -353,6 +353,7 @@ void irc_user_quit(irc_user_t *iu, const char *msg); /* irc_util.c */ char *set_eval_timezone(struct set *set, char *value); char *irc_format_timestamp(irc_t *irc, time_t msg_ts); +char *set_eval_self_messages(struct set *set, char *value); /* irc_im.c */ void bee_irc_channel_update(irc_t *irc, irc_channel_t *ic, irc_user_t *iu); @@ -200,14 +200,17 @@ void bee_irc_channel_update(irc_t *irc, irc_channel_t *ic, irc_user_t *iu) } } -static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at) +static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, guint32 flags, time_t sent_at) { irc_t *irc = bee->ui_data; irc_user_t *iu = (irc_user_t *) bu->ui_data; + irc_user_t *src_iu = iu; + irc_user_t *dst_iu = irc->user; const char *dst; char *prefix = NULL; char *wrapped, *ts = NULL; char *msg = g_strdup(msg_); + char *message_type = "PRIVMSG"; GSList *l; if (sent_at > 0 && set_getbool(&irc->b->set, "display_timestamps")) { @@ -215,9 +218,44 @@ static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, t } dst = irc_user_msgdest(iu); - if (dst != irc->user->nick) { - /* if not messaging directly, call user by name */ - prefix = g_strdup_printf("%s%s%s", irc->user->nick, set_getstr(&bee->set, "to_char"), ts ? : ""); + + if (flags & OPT_SELFMESSAGE) { + char *setting = set_getstr(&irc->b->set, "self_messages"); + + if (is_bool(setting)) { + if (bool2int(setting)) { + /* set to true, send it with src/dst flipped */ + + dst_iu = iu; + src_iu = irc->user; + + if (dst == irc->user->nick) { + dst = dst_iu->nick; + } + } else { + /* set to false, skip the message completely */ + goto cleanup; + } + } else if (g_strncasecmp(setting, "prefix", 6) == 0) { + /* third state, prefix, loosely imitates the znc privmsg_prefix module */ + + g_free(msg); + if (g_strncasecmp(msg_, "/me ", 4) == 0) { + msg = g_strdup_printf("/me -> %s", msg_ + 4); + } else { + msg = g_strdup_printf("-> %s", msg_); + } + + if (g_strcasecmp(setting, "prefix_notice") == 0) { + message_type = "NOTICE"; + } + } + + } + + if (dst != dst_iu->nick) { + /* if not messaging directly (control channel), call user by name */ + prefix = g_strdup_printf("%s%s%s", dst_iu->nick, set_getstr(&bee->set, "to_char"), ts ? : ""); } else { prefix = ts; ts = NULL; /* don't double-free */ @@ -248,7 +286,7 @@ static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, t } wrapped = word_wrap(msg, 425); - irc_send_msg(iu, "PRIVMSG", dst, wrapped, prefix); + irc_send_msg(src_iu, message_type, dst, wrapped, prefix); g_free(wrapped); cleanup: @@ -259,7 +297,7 @@ cleanup: return TRUE; } -static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, uint32_t flags) +static gboolean bee_irc_user_typing(bee_t *bee, bee_user_t *bu, guint32 flags) { irc_t *irc = (irc_t *) bee->ui_data; @@ -616,10 +654,10 @@ static gboolean bee_irc_chat_log(bee_t *bee, struct groupchat *c, const char *te return TRUE; } -static gboolean bee_irc_chat_msg(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at) +static gboolean bee_irc_chat_msg(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at) { irc_t *irc = bee->ui_data; - irc_user_t *iu = bu->ui_data; + irc_user_t *iu = flags & OPT_SELFMESSAGE ? irc->user : bu->ui_data; irc_channel_t *ic = c->ui_data; char *wrapped, *ts = NULL; @@ -118,3 +118,15 @@ char *irc_format_timestamp(irc_t *irc, time_t msg_ts) msg.tm_hour, msg.tm_min, msg.tm_sec); } } + + +char *set_eval_self_messages(set_t *set, char *value) +{ + if (is_bool(value) || + g_strcasecmp(value, "prefix") == 0 || + g_strcasecmp(value, "prefix_notice") == 0) { + return value; + } else { + return SET_INVALID; + } +} diff --git a/protocols/bee.h b/protocols/bee.h index fc27d424..a9678a6e 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -104,7 +104,7 @@ typedef struct bee_ui_funcs { /* State info is already updated, old is provided in case the UI needs a diff. */ gboolean (*user_status)(bee_t *bee, struct bee_user *bu, struct bee_user *old); /* On every incoming message. sent_at = 0 means unknown. */ - gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at); + gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at); /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */ gboolean (*user_typing)(bee_t *bee, bee_user_t *bu, guint32 flags); /* CTCP-like stuff (buddy action) response */ @@ -117,7 +117,7 @@ typedef struct bee_ui_funcs { gboolean (*chat_free)(bee_t *bee, struct groupchat *c); /* System messages of any kind. */ gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text); - gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at); + gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, guint32 flags, time_t sent_at); gboolean (*chat_add_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu); gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *reason); gboolean (*chat_topic)(bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu); diff --git a/protocols/bee_chat.c b/protocols/bee_chat.c index 6ea86c3a..2fcb0396 100644 --- a/protocols/bee_chat.c +++ b/protocols/bee_chat.c @@ -94,16 +94,15 @@ static gboolean handle_is_self(struct im_connection *ic, const char *handle) (ic->acc->prpl->handle_cmp(ic->acc->user, handle) == 0); } -void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at) +void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at) { struct im_connection *ic = c->ic; bee_t *bee = ic->bee; bee_user_t *bu; - gboolean temp; + gboolean temp = FALSE; char *s; - /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ - if (handle_is_self(ic, who)) { + if (handle_is_self(ic, who) && !(flags & OPT_SELFMESSAGE)) { return; } @@ -121,7 +120,7 @@ void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_t fla } if (bee->ui->chat_msg) { - bee->ui->chat_msg(bee, c, bu, msg, sent_at); + bee->ui->chat_msg(bee, c, bu, msg, flags, sent_at); } if (temp) { diff --git a/protocols/bee_user.c b/protocols/bee_user.c index 2d63bfb4..ced92ee9 100644 --- a/protocols/bee_user.c +++ b/protocols/bee_user.c @@ -246,7 +246,7 @@ void imcb_buddy_times(struct im_connection *ic, const char *handle, time_t login bu->idle_time = idle; } -void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, uint32_t flags, time_t sent_at) +void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32 flags, time_t sent_at) { bee_t *bee = ic->bee; bee_user_t *bu; @@ -264,7 +264,7 @@ void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *ms } if (bee->ui->user_msg && bu) { - bee->ui->user_msg(bee, bu, msg, sent_at); + bee->ui->user_msg(bee, bu, msg, flags, sent_at); } else { imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg); } @@ -296,7 +296,7 @@ void imcb_notify_email(struct im_connection *ic, char *format, ...) g_free(msg); } -void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags) +void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags) { bee_user_t *bu; diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 6e7343ba..548b22f9 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -69,6 +69,7 @@ #define OPT_NOOTR 0x00001000 /* protocol not suitable for OTR */ #define OPT_PONGS 0x00010000 /* Service sends us keep-alives */ #define OPT_PONGED 0x00020000 /* Received a keep-alive during last interval */ +#define OPT_SELFMESSAGE 0x00080000 /* A message sent by self from another location */ /* ok. now the fun begins. first we create a connection structure */ struct im_connection { @@ -324,7 +325,7 @@ G_MODULE_EXPORT void imcb_rename_buddy(struct im_connection *ic, const char *han G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick); G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data); -G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags); +G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags); G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle(struct im_connection *ic, const char *handle); G_MODULE_EXPORT void imcb_clean_handle(struct im_connection *ic, char *handle); |