static void print_nick_change(SERVER_REC *server, const char *newnick, const char *oldnick, const char *address, int ownnick) { GSList *tmp, *windows; int msgprint; msgprint = FALSE; /* Print to each channel/query where the nick is. Don't print more than once to the same window. */ windows = NULL; for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *channel = tmp->data; WINDOW_REC *window = window_item_window((WI_ITEM_REC *) channel); if (nicklist_find(channel, newnick) == NULL || g_slist_find(windows, window) != NULL) continue; windows = g_slist_append(windows, window); print_nick_change_channel(server, channel->name, newnick, oldnick, address, ownnick); msgprint = TRUE; } for (tmp = server->queries; tmp != NULL; tmp = tmp->next) { QUERY_REC *query = tmp->data; WINDOW_REC *window = window_item_window((WI_ITEM_REC *) query); if (g_strcasecmp(query->name, oldnick) != 0 || g_slist_find(windows, window) != NULL) continue; windows = g_slist_append(windows, window); print_nick_change_channel(server, query->name, newnick, oldnick, address, ownnick); msgprint = TRUE; } g_slist_free(windows); if (!msgprint && ownnick) { printformat(server, NULL, MSGLEVEL_NICKS, TXT_YOUR_NICK_CHANGED, oldnick, newnick, ""); } }
static void cmd_join(const char *data, SERVER_REC *server) { WINDOW_REC *window; CHANNEL_REC *channel; GHashTable *optlist; char *channelname; void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS, "join", &optlist, &channelname)) return; /* -<server tag> */ server = cmd_options_get_server("join", optlist, server); channel = channel_find(server, channelname); if (channel != NULL) { /* already joined to channel, set it active */ window = window_item_window(channel); if (window != active_win) window_set_active(window); window_item_set_active(active_win, (WI_ITEM_REC *) channel); } cmd_params_free(free_arg); }
static void signal_query_nick_changed(QUERY_REC *query, const char *oldnick) { g_return_if_fail(query != NULL); signal_emit("window item changed", 2, window_item_window((WI_ITEM_REC *) query), query); }
static void print_own_channel_message(SERVER_REC *server, CHANNEL_REC *channel, const char *target, const char *msg) { WINDOW_REC *window; const char *nickmode; char *freemsg = NULL; int print_channel; nickmode = channel_get_nickmode(channel, server->nick); window = channel == NULL ? NULL : window_item_window((WI_ITEM_REC *) channel); print_channel = window == NULL || window->active != (WI_ITEM_REC *) channel; if (!print_channel && settings_get_bool("print_active_channel") && window != NULL && g_slist_length(window->items) > 1) print_channel = TRUE; if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) channel, msg); if (!print_channel) { printformat(server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, TXT_OWN_MSG, server->nick, msg, nickmode); } else { printformat(server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, TXT_OWN_MSG_CHANNEL, server->nick, target, msg, nickmode); } g_free_not_null(freemsg); }
static void cmd_query(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item) { WINDOW_REC *window; QUERY_REC *query; g_return_if_fail(data != NULL); if (*data == '\0') { /* remove current query */ cmd_unquery("", server, item); return; } if (*data != '=' && (server == NULL || !server->connected)) cmd_return_error(CMDERR_NOT_CONNECTED); query = query_find(server, data); if (query != NULL) { /* query already existed - change to query window */ window = window_item_window((WI_ITEM_REC *) query); g_return_if_fail(window != NULL); window_set_active(window); window_item_set_active(window, (WI_ITEM_REC *) query); return; } query_create(server, data, FALSE); }
WINDOW_REC *window_find_item(SERVER_REC *server, const char *name) { WINDOW_REC *rec; WI_ITEM_REC *item; g_return_val_if_fail(name != NULL, NULL); rec = window_find_name(name); if (rec != NULL) return rec; item = server == NULL ? NULL : window_item_find(server, name); if (item == NULL && server == NULL) { /* not found from the active server - any server? */ item = window_item_find(NULL, name); } if (item == NULL) { char *chan; /* still nothing? maybe user just left the # in front of channel, try again with it.. */ chan = g_strdup_printf("#%s", name); item = server == NULL ? NULL : window_item_find(server, chan); if (item == NULL) item = window_item_find(NULL, chan); g_free(chan); } if (item == NULL) return 0; return window_item_window(item); }
WINDOW_REC *window_find_closest(void *server, const char *name, int level) { WINDOW_REC *window,*namewindow=NULL; WI_ITEM_REC *item; /* match by name */ item = name == NULL ? NULL : window_item_find(server, name); if (item != NULL) { namewindow = window_item_window(item); if (namewindow != NULL && ((namewindow->level & level) != 0 || !settings_get_bool("window_check_level_first"))) return namewindow; } /* match by level */ if (level != MSGLEVEL_HILIGHT) level &= ~(MSGLEVEL_HILIGHT | MSGLEVEL_NOHILIGHT); window = window_find_level(server, level); if (window != NULL) return window; /* match by level - ignore server */ window = window_find_level(NULL, level); if (window != NULL) return window; /* still return item's window if we didnt find anything */ if (namewindow != NULL) return namewindow; /* fallback to active */ return active_win; }
/* SYNTAX: CYCLE [<channel>] [<message>] */ static void cmd_cycle(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { CHANNEL_REC *chanrec; char *channame, *msg, *joindata; void *free_arg; g_return_if_fail(data != NULL); if (!IS_SERVER(server) || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN, item, &channame, &msg)) return; if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); chanrec = channel_find(server, channame); if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND); joindata = chanrec->get_join_data(chanrec); window_bind_add(window_item_window(chanrec), chanrec->server->tag, chanrec->name); /* FIXME: kludgy kludgy... */ signal_emit("command part", 3, data, server, item); if (g_slist_find(channels, chanrec) != NULL) { chanrec->left = TRUE; channel_destroy(chanrec); } server->channels_join(server, joindata, FALSE); g_free(joindata); cmd_params_free(free_arg); }
static void signal_channel_created(CHANNEL_REC *channel, void *automatic) { if (window_item_window(channel) == NULL) { window_item_create((WI_ITEM_REC *) channel, GPOINTER_TO_INT(automatic)); } }
void window_item_destroy(WI_ITEM_REC *item) { WINDOW_REC *window; window = window_item_window(item); window_item_remove(item); item->destroy(item); }
static void sig_statusbar_channel_redraw_window_item(WI_ITEM_REC *item) { WINDOW_REC *window; window = window_item_window(item); if (window->active == item && is_window_visible(window)) statusbar_item_redraw(channel_item); }
static void signal_query_server_changed(QUERY_REC *query) { WINDOW_REC *window; g_return_if_fail(query != NULL); window = window_item_window((WI_ITEM_REC *) query); if (window->active == (WI_ITEM_REC *) query) window_change_server(window, query->server); }
/* SYNTAX: JOIN [-window] [-invite] [-<server tag>] <channels> [<keys>] */ static void cmd_join(const char *data, SERVER_REC *server) { WINDOW_REC *window; CHANNEL_REC *channel; GHashTable *optlist; char *pdata; int invite; int samewindow; void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "join", &optlist, &pdata)) return; invite = g_hash_table_lookup(optlist, "invite") != NULL; samewindow = g_hash_table_lookup(optlist, "window") != NULL; if (!invite && *pdata == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); /* -<server tag> */ server = cmd_options_get_server("join", optlist, server); channel = channel_find(server, pdata); if (channel != NULL) { /* already joined to channel, set it active */ window = window_item_window(channel); if (window != active_win) window_set_active(window); window_item_set_active(active_win, (WI_ITEM_REC *) channel); } else { if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); if (invite) { if (server->last_invite == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_NOT_INVITED); signal_stop(); cmd_params_free(free_arg); return; } pdata = server->last_invite; } if (samewindow) signal_add("channel created", (SIGNAL_FUNC) signal_channel_created_curwin); server->channels_join(server, pdata, FALSE); if (samewindow) signal_remove("channel created", (SIGNAL_FUNC) signal_channel_created_curwin); } cmd_params_free(free_arg); }
static void sig_query_raise(XMPP_SERVER_REC *server, QUERY_REC *query) { WINDOW_REC *window; g_return_if_fail(query != NULL); window = window_item_window(query); if (window != active_win) window_set_active(window); window_item_set_active(active_win, (WI_ITEM_REC *)query); }
void window_item_change_server(WI_ITEM_REC *item, void *server) { WINDOW_REC *window; g_return_if_fail(item != NULL); window = window_item_window(item); item->server = server; signal_emit("window item server changed", 2, window, item); if (window->active == item) window_change_server(window, item->server); }
/* Return TRUE if `item' is the active window item in the window. `item' can be NULL. */ int window_item_is_active(WI_ITEM_REC *item) { WINDOW_REC *window; if (item == NULL) return FALSE; window = window_item_window(item); if (window == NULL) return FALSE; return window->active == item; }
static void sig_history(SERVER_REC *server, const char *msg, const char *nick, const char *target, const char *stamp, gpointer gpointer_type) { void *item; char *text, *freemsg = NULL; int level, type; g_return_if_fail(server != NULL); g_return_if_fail(msg != NULL); g_return_if_fail(nick != NULL); g_return_if_fail(target != NULL); type = GPOINTER_TO_INT(gpointer_type); level = MSGLEVEL_NO_ACT | MSGLEVEL_NOHILIGHT | (type == SEND_TARGET_CHANNEL ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); item = type == SEND_TARGET_CHANNEL ? (void *)channel_find(server, target) : query_find(server, nick); if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis(item, msg); /* MUC */ if (type == SEND_TARGET_CHANNEL) { CHANNEL_REC *chanrec = item; int print_channel; char *nickmode; print_channel = chanrec == NULL || !window_item_is_active((WI_ITEM_REC *)chanrec); if (!print_channel && settings_get_bool("print_active_channel") && window_item_window((WI_ITEM_REC *)chanrec)->items->next != NULL) print_channel = TRUE; nickmode = channel_get_nickmode(chanrec, nick); text = !print_channel ? format_get_text(CORE_MODULE_NAME, NULL, server, target, TXT_PUBMSG, nick, msg, nickmode) : format_get_text(CORE_MODULE_NAME, NULL, server, target, TXT_PUBMSG_CHANNEL, nick, target, msg, nickmode); g_free(nickmode); /* General */ } else text = format_get_text(CORE_MODULE_NAME, NULL, server, target, item == NULL ? TXT_MSG_PRIVATE : TXT_MSG_PRIVATE_QUERY, nick, nick, msg); printformat_module(MODULE_NAME, server, target, level, XMPPTXT_MESSAGE_TIMESTAMP, stamp, text); g_free_not_null(freemsg); g_free(text); }
static void exec_wi_destroy(EXEC_WI_REC *rec) { g_return_if_fail(rec != NULL); if (rec->destroying) return; rec->destroying = TRUE; if (window_item_window((WI_ITEM_REC *) rec) != NULL) window_item_destroy((WI_ITEM_REC *) rec); MODULE_DATA_DEINIT(rec); g_free(rec->name); g_free(rec); }
static void sig_disconnected(SERVER_REC *server) { WINDOW_REC *window; GSList *tmp; g_return_if_fail(IS_SERVER(server)); for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *channel = tmp->data; window = window_item_window((WI_ITEM_REC *) channel); window_bind_add(window, server->tag, channel->name); } }
static void signal_query_destroyed(QUERY_REC *query) { WINDOW_REC *window; g_return_if_fail(IS_QUERY(query)); window = window_item_window((WI_ITEM_REC *) query); if (window != NULL) { window_item_destroy((WI_ITEM_REC *) query); if (window->items == NULL && windows->next != NULL && !query->unwanted && settings_get_bool("autoclose_windows")) window_destroy(window); } }
static void sig_disconnected(SERVER_REC *server) { WINDOW_REC *window; GSList *tmp; g_return_if_fail(IS_SERVER(server)); for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *channel = tmp->data; window = window_item_window((WI_ITEM_REC *) channel); window->waiting_channels = g_slist_append(window->waiting_channels, g_strdup_printf("%s %s", server->tag, channel->name)); } }
static void sig_event_forward(SERVER_REC *server, const char *data, const char *nick) { IRC_CHANNEL_REC *channel; char *params, *from, *to; params = event_get_params(data, 3, NULL, &from, &to); if (from != NULL && to != NULL && server_ischannel(server, from) && server_ischannel(server, to)) { channel = irc_channel_find(server, from); if (channel != NULL && irc_channel_find(server, to) == NULL) { window_bind_add(window_item_window(channel), server->tag, to); } } g_free(params); }
static void signal_query_created(QUERY_REC *query, gpointer automatic) { TEXT_DEST_REC dest; g_return_if_fail(IS_QUERY(query)); if (window_item_window(query) == NULL) { window_item_create((WI_ITEM_REC *) query, GPOINTER_TO_INT(automatic)); } format_create_dest_tag(&dest, query->server, query->server_tag, query->name, MSGLEVEL_CLIENTNOTICE, NULL); printformat_dest(&dest, TXT_QUERY_START, query->name, query->server_tag); }
WINDOW_REC *window_find_closest(void *server, const char *name, int level) { WINDOW_REC *window,*namewindow=NULL; WI_ITEM_REC *item; int i; /* match by name */ item = name == NULL ? NULL : window_item_find(server, name); if (item != NULL) { namewindow = window_item_window(item); if (namewindow != NULL && ((namewindow->level & level) != 0 || !settings_get_bool("window_check_level_first"))) { /* match, but if multiple windows have the same level we could be choosing a bad one here, eg. name=nick1 would get nick2's query instead of generic msgs window. And check for prefixed !channel name --Borys */ if (g_ascii_strcasecmp(name, item->visible_name) == 0 || g_ascii_strcasecmp(name, (char *) window_item_get_target((WI_ITEM_REC *) item)) == 0) return namewindow; } } /* prefer windows without items */ for (i = 0; i < 2; i++) { /* match by level */ if (level != MSGLEVEL_HILIGHT) level &= ~(MSGLEVEL_HILIGHT | MSGLEVEL_NOHILIGHT); window = window_find_level(server, level); if (window != NULL && (i == 1 || window->items == NULL)) return window; /* match by level - ignore server */ window = window_find_level(NULL, level); if (window != NULL && (i == 1 || window->items == NULL)) return window; } /* still return item's window if we didnt find anything */ if (namewindow != NULL) return namewindow; /* fallback to active */ return active_win; }
static void signal_channel_destroyed(CHANNEL_REC *channel) { WINDOW_REC *window; g_return_if_fail(channel != NULL); window = window_item_window((WI_ITEM_REC *) channel); if (window != NULL) { window_item_destroy(window, (WI_ITEM_REC *) channel); if (window->items == NULL && windows->next != NULL && (!channel->joined || channel->left) && settings_get_bool("autoclose_windows")) { window_destroy(window); } } }
void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item) { g_return_if_fail(window != NULL); if (item != NULL && window_item_window(item) != window) { /* move item to different window */ window_item_remove(item); window_item_add(window, item, FALSE); } if (window->active != item) { window->active = item; if (item != NULL && window->active_server != item->server) window_change_server(window, item->server); signal_emit("window item changed", 2, window, item); } }
static int sig_query_autoclose(void) { WINDOW_REC *window; GSList *tmp, *next; time_t now; now = time(NULL); for (tmp = queries; tmp != NULL; tmp = next) { QUERY_REC *rec = tmp->data; next = tmp->next; window = window_item_window((WI_ITEM_REC *) rec); if (window != active_win && rec->data_level < DATA_LEVEL_MSG && now-rec->last_unread_msg > query_auto_close) query_destroy(rec); } return 1; }
static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) { WINDOW_REC *window; WI_ITEM_REC *item; char *params, *target, *msg; int level; g_return_if_fail(data != NULL); params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); /* get window and window item */ level = ischannel(*target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS; item = window_item_find(server, ischannel(*target) ? target : nick); window = item == NULL ? window_find_closest(server, target, GPOINTER_TO_INT(level)) : window_item_window(item); /* check that msg wasn't send to current window and that it didn't get ignored */ if (window != active_win && !ignore_check(server, nick, addr, target, msg, level)) { /* hilight */ if (item != NULL) item->last_color = irc_hilight_last_color(); level = (item != NULL && item->last_color > 0) || !ischannel(*target) || irc_nick_match(server->nick, msg) ? NEWDATA_HILIGHT : NEWDATA_MSG; if (item != NULL && item->new_data < level) { item->new_data = level; signal_emit("window item hilight", 1, item); } else { int oldlevel = window->new_data; if (window->new_data < level) { window->new_data = level; window->last_color = irc_hilight_last_color(); signal_emit("window hilight", 2, window, GINT_TO_POINTER(oldlevel)); } signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); } } g_free(params); }
/* SYNTAX: SETHOST <host> <password> (non-ircops) SETHOST <ident> <host> (ircops) */ static void cmd_sethost(const char *data, IRC_SERVER_REC *server) { GSList *tmp; g_return_if_fail(data != NULL); if (!IS_IRC_SERVER(server) || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); /* Save all the joined channels in server to window binds, since the server will soon /PART + /JOIN us in all channels. */ for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *channel = tmp->data; window_bind_add(window_item_window(channel), server->tag, channel->visible_name); } irc_send_cmdv(server, "SETHOST %s", data); }
static void sig_message_own_public(SERVER_REC *server, char *msg, char *target) { WINDOW_REC *window; CHANNEL_REC *channel; char *nick, *nickmode, *freemsg = NULL, *recoded; gboolean print_channel; g_return_if_fail(server != NULL); g_return_if_fail(msg != NULL); g_return_if_fail(target != NULL); if (!IS_XMPP_SERVER(server)) return; channel = channel_find(server, target); if (channel == NULL || channel->ownnick == NULL) return; nick = channel->ownnick->nick; nickmode = channel_get_nickmode(CHANNEL(channel), nick); window = (channel == NULL) ? NULL : window_item_window((WI_ITEM_REC *)channel); print_channel = (window == NULL || window->active != (WI_ITEM_REC *) channel); if (!print_channel && settings_get_bool("print_active_channel") && window != NULL && g_slist_length(window->items) > 1) print_channel = TRUE; if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *)channel, msg); /* ugly from irssi: recode the sent message back for printing */ recoded = recode_in(SERVER(server), msg, target); if (!print_channel) printformat_module(CORE_MODULE_NAME, server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, TXT_OWN_MSG, nick, recoded, nickmode); else printformat_module(CORE_MODULE_NAME, server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, TXT_OWN_MSG_CHANNEL, nick, target, recoded, nickmode); g_free(recoded); g_free(nickmode); g_free_not_null(freemsg); signal_stop(); /* emit signal for chat-completion */ }