Merged from silc_1_0_branch.
[silc.git] / apps / irssi / src / fe-common / silc / fe-messages.c
1 /*
2
3   fe-messages.c
4
5   Author: Jochen Eisinger <c0ffee@penguin-breeder.org>
6
7   Copyright (C) 2002 Jochen Eisinger
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20
21 #include "module.h"
22 #include "modules.h"
23 #include "signals.h"
24 #include "themes.h"
25 #include "levels.h"
26 #include "misc.h"
27 #include "special-vars.h"
28 #include "settings.h"
29
30 #include "servers.h"
31 #include "channels.h"
32 #include "nicklist.h"
33 #include "ignore.h"
34
35 #include "window-items.h"
36 #include "fe-queries.h"
37 #include "fe-messages.h"
38 #include "hilight-text.h"
39 #include "printtext.h"
40 #include "module-formats.h"
41
42 #define VERIFIED_MSG(v,msg) (v == SILC_MSG_SIGNED_VERIFIED ? \
43                                 msg##_SIGNED : (v == SILC_MSG_SIGNED_UNKNOWN ? \
44                                 msg##_UNKNOWN : msg##_FAILED))
45
46 static void sig_signed_message_public(SERVER_REC * server, const char *msg,
47                                       const char *nick,
48                                       const char *address,
49                                       const char *target,
50                                       int verified)
51 {
52   CHANNEL_REC *chanrec;
53   NICK_REC *nickrec = NULL; /* we cheat here a little to keep the limit of 
54                                6 parameters to a signal handler ... */
55   const char *nickmode, *printnick;
56   int for_me, print_channel, level;
57   char *color, *freemsg = NULL;
58
59   /* NOTE: this may return NULL if some channel is just closed with
60      /WINDOW CLOSE and server still sends the few last messages */
61   chanrec = channel_find(server, target);
62   if (nickrec == NULL && chanrec != NULL)
63     nickrec = nicklist_find(chanrec, nick);
64
65   for_me = !settings_get_bool("hilight_nick_matches") ? FALSE :
66       nick_match_msg(chanrec, msg, server->nick);
67   color = for_me ? NULL :
68       hilight_match_nick(server, target, nick, address, MSGLEVEL_PUBLIC,
69                          msg);
70
71   print_channel = chanrec == NULL ||
72       !window_item_is_active((WI_ITEM_REC *) chanrec);
73   if (!print_channel && settings_get_bool("print_active_channel") &&
74       window_item_window((WI_ITEM_REC *) chanrec)->items->next != NULL)
75     print_channel = TRUE;
76
77   level = MSGLEVEL_PUBLIC;
78   if (for_me || color != NULL)
79     level |= MSGLEVEL_HILIGHT;
80
81   if (settings_get_bool("emphasis"))
82     msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg);
83
84   /* get nick mode & nick what to print the msg with
85      (in case there's multiple identical nicks) */
86   nickmode = channel_get_nickmode(chanrec, nick);
87   printnick = nickrec == NULL ? nick :
88       g_hash_table_lookup(printnicks, nickrec);
89   if (printnick == NULL)
90     printnick = nick;
91
92   if (!print_channel) {
93     /* message to active channel in window */
94     if (color != NULL) {
95       /* highlighted nick */
96       printformat_module("fe-common/silc", server, target,
97                          level, VERIFIED_MSG(verified, SILCTXT_PUBMSG_HILIGHT),
98                          color, printnick, msg, nickmode);
99     } else {
100       printformat_module("fe-common/silc", server, target, level,
101                          for_me ? VERIFIED_MSG(verified, SILCTXT_PUBMSG_ME) :
102                                   VERIFIED_MSG(verified,SILCTXT_PUBMSG),
103                          printnick, msg, nickmode);
104     }
105   } else {
106     /* message to not existing/active channel */
107     if (color != NULL) {
108       /* highlighted nick */
109       printformat_module("fe-common/silc", server, target, level,
110                          VERIFIED_MSG(verified, SILCTXT_PUBMSG_HILIGHT_CHANNEL),
111                          color, printnick, target, msg, nickmode);
112     } else {
113       printformat_module("fe-common/silc", server, target, level,
114                          for_me ? VERIFIED_MSG(verified, SILCTXT_PUBMSG_ME_CHANNEL) :
115                          VERIFIED_MSG(verified, SILCTXT_PUBMSG_CHANNEL),
116                          printnick, target, msg, nickmode);
117     }
118   }
119
120   g_free_not_null(freemsg);
121   g_free_not_null(color);
122 }
123
124 static void sig_signed_message_private(SERVER_REC * server,
125                                        const char *msg, const char *nick,
126                                        const char *address, int verified)
127 {
128   QUERY_REC *query;
129   char *freemsg = NULL;
130
131   query = query_find(server, nick);
132
133   if (settings_get_bool("emphasis"))
134     msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
135
136   printformat_module("fe-common/silc", server, nick, MSGLEVEL_MSGS,
137                      query == NULL ? VERIFIED_MSG(verified, SILCTXT_MSG_PRIVATE) :
138                      VERIFIED_MSG(verified, SILCTXT_MSG_PRIVATE_QUERY), nick, address, msg);
139
140   g_free_not_null(freemsg);
141 }
142
143 static void sig_signed_message_own_public(SERVER_REC * server,
144                                           const char *msg,
145                                           const char *target)
146 {
147   WINDOW_REC *window;
148   CHANNEL_REC *channel;
149   const char *nickmode;
150   char *freemsg = NULL;
151   int print_channel;
152
153   channel = channel_find(server, target);
154   if (channel != NULL)
155     target = channel->visible_name;
156
157   nickmode = channel_get_nickmode(channel, server->nick);
158
159   window = channel == NULL ? NULL :
160       window_item_window((WI_ITEM_REC *) channel);
161
162   print_channel = window == NULL ||
163       window->active != (WI_ITEM_REC *) channel;
164
165   if (!print_channel && settings_get_bool("print_active_channel") &&
166       window != NULL && g_slist_length(window->items) > 1)
167     print_channel = TRUE;
168
169   if (settings_get_bool("emphasis"))
170     msg = freemsg = expand_emphasis((WI_ITEM_REC *) channel, msg);
171
172   if (!print_channel) {
173     printformat_module("fe-common/silc", server, target,
174                        MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
175                        MSGLEVEL_NO_ACT, SILCTXT_OWN_MSG_SIGNED, server->nick, msg,
176                        nickmode);
177   } else {
178     printformat_module("fe-common/silc", server, target,
179                        MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
180                        MSGLEVEL_NO_ACT, SILCTXT_OWN_MSG_CHANNEL_SIGNED,
181                        server->nick, target, msg, nickmode);
182   }
183
184   g_free_not_null(freemsg);
185 }
186
187 static void sig_signed_message_own_private(SERVER_REC * server,
188                                            const char *msg,
189                                            const char *target,
190                                            const char *origtarget)
191 {
192   QUERY_REC *query;
193   char *freemsg = NULL;
194
195   g_return_if_fail(server != NULL);
196   g_return_if_fail(msg != NULL);
197
198   if (target == NULL) {
199     /* this should only happen if some special target failed and
200        we should display some error message. currently the special
201        targets are only ',' and '.'. */
202     g_return_if_fail(strcmp(origtarget, ",") == 0 ||
203                      strcmp(origtarget, ".") == 0);
204
205     printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CLIENTNOTICE,
206                        *origtarget == ',' ? SILCTXT_NO_MSGS_GOT :
207                        SILCTXT_NO_MSGS_SENT);
208     signal_stop();
209     return;
210   }
211
212   query = privmsg_get_query(server, target, TRUE, MSGLEVEL_MSGS);
213
214   if (settings_get_bool("emphasis"))
215     msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
216
217   printformat_module("fe-common/silc", server, target,
218                      MSGLEVEL_MSGS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT,
219                      query == NULL ? SILCTXT_OWN_MSG_PRIVATE_SIGNED :
220                      SILCTXT_OWN_MSG_PRIVATE_QUERY_SIGNED, target, msg,
221                      server->nick);
222
223   g_free_not_null(freemsg);
224 }
225
226 void fe_silc_messages_init(void)
227 {
228   signal_add_last("message signed_public",
229                   (SIGNAL_FUNC) sig_signed_message_public);
230   signal_add_last("message signed_private",
231                   (SIGNAL_FUNC) sig_signed_message_private);
232   signal_add_last("message signed_own_public",
233                   (SIGNAL_FUNC) sig_signed_message_own_public);
234   signal_add_last("message signed_own_private",
235                   (SIGNAL_FUNC) sig_signed_message_own_private);
236 }
237
238 void fe_silc_messages_deinit(void)
239 {
240   signal_remove("message signed_public",
241                 (SIGNAL_FUNC) sig_signed_message_public);
242   signal_remove("message signed_private",
243                 (SIGNAL_FUNC) sig_signed_message_private);
244   signal_remove("message signed_own_public",
245                 (SIGNAL_FUNC) sig_signed_message_own_public);
246   signal_remove("message signed_own_private",
247                 (SIGNAL_FUNC) sig_signed_message_own_private);
248 }