aboutsummaryrefslogtreecommitdiff
path: root/xC.c
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2022-09-21 12:13:30 +0200
committerPřemysl Eric Janouch <p@janouch.name>2022-09-21 12:15:27 +0200
commit919b12510b49b7b32850b1153d04bb40506bf0a1 (patch)
tree93401102c09f5a2185b64fe9b3708e97102fc1ae /xC.c
parent414859d309df7282fbb044c5303f8ce7a32461c8 (diff)
downloadxK-919b12510b49b7b32850b1153d04bb40506bf0a1.tar.gz
xK-919b12510b49b7b32850b1153d04bb40506bf0a1.tar.xz
xK-919b12510b49b7b32850b1153d04bb40506bf0a1.zip
xC/xP: relay and render channel topics
Diffstat (limited to 'xC.c')
-rw-r--r--xC.c205
1 files changed, 119 insertions, 86 deletions
diff --git a/xC.c b/xC.c
index 2027a6a..38f2c00 100644
--- a/xC.c
+++ b/xC.c
@@ -2883,84 +2883,9 @@ relay_prepare_ping (struct app_context *ctx)
relay_prepare (ctx)->data.event = RELAY_EVENT_PING;
}
-static void
-relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
-{
- struct relay_event_message *m = relay_prepare (ctx);
- struct relay_event_data_buffer_update *e = &m->data.buffer_update;
- e->event = RELAY_EVENT_BUFFER_UPDATE;
- e->buffer_name = str_from_cstr (buffer->name);
- e->hide_unimportant = buffer->hide_unimportant;
-
- struct str *server_name = NULL;
- switch (buffer->type)
- {
- case BUFFER_GLOBAL:
- e->context.kind = RELAY_BUFFER_KIND_GLOBAL;
- break;
- case BUFFER_SERVER:
- e->context.kind = RELAY_BUFFER_KIND_SERVER;
- server_name = &e->context.server.server_name;
- break;
- case BUFFER_CHANNEL:
- e->context.kind = RELAY_BUFFER_KIND_CHANNEL;
- server_name = &e->context.channel.server_name;
- break;
- case BUFFER_PM:
- e->context.kind = RELAY_BUFFER_KIND_PRIVATE_MESSAGE;
- server_name = &e->context.private_message.server_name;
- break;
- }
- if (server_name)
- *server_name = str_from_cstr (buffer->server->name);
-}
-
-static void
-relay_prepare_buffer_stats (struct app_context *ctx, struct buffer *buffer)
-{
- struct relay_event_message *m = relay_prepare (ctx);
- struct relay_event_data_buffer_stats *e = &m->data.buffer_stats;
- e->event = RELAY_EVENT_BUFFER_STATS;
- e->buffer_name = str_from_cstr (buffer->name);
- e->new_messages = MIN (UINT32_MAX,
- buffer->new_messages_count - buffer->new_unimportant_count);
- e->new_unimportant_messages = MIN (UINT32_MAX,
- buffer->new_unimportant_count);
- e->highlighted = buffer->highlighted;
-}
-
-static void
-relay_prepare_buffer_rename (struct app_context *ctx, struct buffer *buffer,
- const char *new_name)
-{
- struct relay_event_message *m = relay_prepare (ctx);
- struct relay_event_data_buffer_rename *e = &m->data.buffer_rename;
- e->event = RELAY_EVENT_BUFFER_RENAME;
- e->buffer_name = str_from_cstr (buffer->name);
- e->new = str_from_cstr (new_name);
-}
-
-static void
-relay_prepare_buffer_remove (struct app_context *ctx, struct buffer *buffer)
-{
- struct relay_event_message *m = relay_prepare (ctx);
- struct relay_event_data_buffer_remove *e = &m->data.buffer_remove;
- e->event = RELAY_EVENT_BUFFER_REMOVE;
- e->buffer_name = str_from_cstr (buffer->name);
-}
-
-static void
-relay_prepare_buffer_activate (struct app_context *ctx, struct buffer *buffer)
-{
- struct relay_event_message *m = relay_prepare (ctx);
- struct relay_event_data_buffer_activate *e = &m->data.buffer_activate;
- e->event = RELAY_EVENT_BUFFER_ACTIVATE;
- e->buffer_name = str_from_cstr (buffer->name);
-}
-
static union relay_item_data *
relay_translate_formatter (struct app_context *ctx, union relay_item_data *p,
- struct formatter_item *i)
+ const struct formatter_item *i)
{
// XXX: See attr_printer_decode_color(), this is a footgun.
int16_t c16 = i->color;
@@ -3016,6 +2941,23 @@ relay_translate_formatter (struct app_context *ctx, union relay_item_data *p,
return p;
}
+static union relay_item_data *
+relay_items (struct app_context *ctx, const struct formatter_item *items,
+ uint32_t *len)
+{
+ size_t items_len = 0;
+ for (size_t i = 0; items[i].type; i++)
+ items_len++;
+
+ // Beware of the upper bound, currently dominated by FORMATTER_ITEM_ATTR.
+ union relay_item_data *a = xcalloc (items_len * 9, sizeof *a), *p = a;
+ for (const struct formatter_item *i = items; items_len--; i++)
+ p = relay_translate_formatter (ctx, p, i);
+
+ *len = p - a;
+ return a;
+}
+
static void
relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
struct buffer_line *line, bool leak_to_active)
@@ -3029,17 +2971,94 @@ relay_prepare_buffer_line (struct app_context *ctx, struct buffer *buffer,
e->rendition = 1 + line->r;
e->when = line->when * 1000;
e->leak_to_active = leak_to_active;
+ e->items = relay_items (ctx, line->items, &e->items_len);
+}
- size_t len = 0;
- for (size_t i = 0; line->items[i].type; i++)
- len++;
+// TODO: Consider pushing this whole block of code much further down.
+static void formatter_add (struct formatter *self, const char *format, ...);
- // Beware of the upper bound, currently dominated by FORMATTER_ITEM_ATTR.
- union relay_item_data *p = e->items = xcalloc (len * 9, sizeof *e->items);
- for (struct formatter_item *i = line->items; len--; i++)
- p = relay_translate_formatter (ctx, p, i);
+static void
+relay_prepare_buffer_update (struct app_context *ctx, struct buffer *buffer)
+{
+ struct relay_event_message *m = relay_prepare (ctx);
+ struct relay_event_data_buffer_update *e = &m->data.buffer_update;
+ e->event = RELAY_EVENT_BUFFER_UPDATE;
+ e->buffer_name = str_from_cstr (buffer->name);
+ e->hide_unimportant = buffer->hide_unimportant;
+
+ struct str *server_name = NULL;
+ switch (buffer->type)
+ {
+ case BUFFER_GLOBAL:
+ e->context.kind = RELAY_BUFFER_KIND_GLOBAL;
+ break;
+ case BUFFER_SERVER:
+ e->context.kind = RELAY_BUFFER_KIND_SERVER;
+ server_name = &e->context.server.server_name;
+ break;
+ case BUFFER_CHANNEL:
+ {
+ e->context.kind = RELAY_BUFFER_KIND_CHANNEL;
+ server_name = &e->context.channel.server_name;
- e->items_len = p - e->items;
+ struct formatter f = formatter_make (ctx, buffer->server);
+ if (buffer->channel->topic)
+ formatter_add (&f, "#m", buffer->channel->topic);
+ e->context.channel.topic =
+ relay_items (ctx, f.items, &e->context.channel.topic_len);
+ formatter_free (&f);
+ break;
+ }
+ case BUFFER_PM:
+ e->context.kind = RELAY_BUFFER_KIND_PRIVATE_MESSAGE;
+ server_name = &e->context.private_message.server_name;
+ break;
+ }
+ if (server_name)
+ *server_name = str_from_cstr (buffer->server->name);
+}
+
+static void
+relay_prepare_buffer_stats (struct app_context *ctx, struct buffer *buffer)
+{
+ struct relay_event_message *m = relay_prepare (ctx);
+ struct relay_event_data_buffer_stats *e = &m->data.buffer_stats;
+ e->event = RELAY_EVENT_BUFFER_STATS;
+ e->buffer_name = str_from_cstr (buffer->name);
+ e->new_messages = MIN (UINT32_MAX,
+ buffer->new_messages_count - buffer->new_unimportant_count);
+ e->new_unimportant_messages = MIN (UINT32_MAX,
+ buffer->new_unimportant_count);
+ e->highlighted = buffer->highlighted;
+}
+
+static void
+relay_prepare_buffer_rename (struct app_context *ctx, struct buffer *buffer,
+ const char *new_name)
+{
+ struct relay_event_message *m = relay_prepare (ctx);
+ struct relay_event_data_buffer_rename *e = &m->data.buffer_rename;
+ e->event = RELAY_EVENT_BUFFER_RENAME;
+ e->buffer_name = str_from_cstr (buffer->name);
+ e->new = str_from_cstr (new_name);
+}
+
+static void
+relay_prepare_buffer_remove (struct app_context *ctx, struct buffer *buffer)
+{
+ struct relay_event_message *m = relay_prepare (ctx);
+ struct relay_event_data_buffer_remove *e = &m->data.buffer_remove;
+ e->event = RELAY_EVENT_BUFFER_REMOVE;
+ e->buffer_name = str_from_cstr (buffer->name);
+}
+
+static void
+relay_prepare_buffer_activate (struct app_context *ctx, struct buffer *buffer)
+{
+ struct relay_event_message *m = relay_prepare (ctx);
+ struct relay_event_data_buffer_activate *e = &m->data.buffer_activate;
+ e->event = RELAY_EVENT_BUFFER_ACTIVATE;
+ e->buffer_name = str_from_cstr (buffer->name);
}
static void
@@ -5291,6 +5310,20 @@ irc_make_channel (struct server *s, char *name)
return channel;
}
+static void
+irc_channel_set_topic (struct channel *channel, const char *topic)
+{
+ cstr_set (&channel->topic, xstrdup (topic));
+
+ struct server *s = channel->s;
+ struct buffer *buffer = str_map_find (&s->irc_buffer_map, channel->name);
+ if (buffer)
+ {
+ relay_prepare_buffer_update (s->ctx, buffer);
+ relay_broadcast (s->ctx);
+ }
+}
+
static struct channel_user *
irc_channel_get_user (struct channel *channel, struct user *user)
{
@@ -8074,7 +8107,7 @@ irc_handle_topic (struct server *s, const struct irc_message *msg)
// It would be weird for this to be false
if (channel)
- cstr_set (&channel->topic, xstrdup (topic));
+ irc_channel_set_topic (channel, topic);
if (buffer)
{
@@ -8486,7 +8519,7 @@ irc_handle_rpl_topic (struct server *s, const struct irc_message *msg)
hard_assert (channel || !buffer);
if (channel)
- cstr_set (&channel->topic, xstrdup (topic));
+ irc_channel_set_topic (channel, topic);
if (buffer)
log_server_status (s, buffer, "The topic is: #m", topic);