Merged silc_1_0_branch to trunk.
[silc.git] / apps / irssi / src / fe-common / silc / fe-silc-messages.c
1 /*
2
3   fe-silc-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 #define VERIFIED_MSG2(v,msg) (v >= 0 ? VERIFIED_MSG(v,msg) : msg)
47
48 static void sig_signed_message_public(SERVER_REC * server, const char *msg,
49                                       const char *nick,
50                                       const char *address,
51                                       const char *target,
52                                       int verified)
53 {
54   CHANNEL_REC *chanrec;
55   NICK_REC *nickrec = NULL; /* we cheat here a little to keep the limit of 
56                                6 parameters to a signal handler ... */
57   const char *nickmode, *printnick;
58   int for_me, print_channel, level;
59   char *color, *freemsg = NULL;
60
61   /* NOTE: this may return NULL if some channel is just closed with
62      /WINDOW CLOSE and server still sends the few last messages */
63   chanrec = channel_find(server, target);
64   if (nickrec == NULL && chanrec != NULL)
65     nickrec = nicklist_find(chanrec, nick);
66
67   for_me = !settings_get_bool("hilight_nick_matches") ? FALSE :
68       nick_match_msg(chanrec, msg, server->nick);
69   color = for_me ? NULL :
70       hilight_match_nick(server, target, nick, address, MSGLEVEL_PUBLIC,
71                          msg);
72
73   print_channel = chanrec == NULL ||
74       !window_item_is_active((WI_ITEM_REC *) chanrec);
75   if (!print_channel && settings_get_bool("print_active_channel") &&
76       window_item_window((WI_ITEM_REC *) chanrec)->items->next != NULL)
77     print_channel = TRUE;
78
79   level = MSGLEVEL_PUBLIC;
80   if (for_me || color != NULL)
81     level |= MSGLEVEL_HILIGHT;
82
83   if (settings_get_bool("emphasis"))
84     msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg);
85
86   /* get nick mode & nick what to print the msg with
87      (in case there's multiple identical nicks) */
88   nickmode = channel_get_nickmode(chanrec, nick);
89   printnick = nickrec == NULL ? nick :
90       g_hash_table_lookup(printnicks, nickrec);
91   if (printnick == NULL)
92     printnick = nick;
93
94   if (!print_channel) {
95     /* message to active channel in window */
96     if (color != NULL) {
97       /* highlighted nick */
98       printformat_module("fe-common/silc", server, target,
99                          level, VERIFIED_MSG(verified, SILCTXT_PUBMSG_HILIGHT),
100                          color, printnick, msg, nickmode);
101     } else {
102       printformat_module("fe-common/silc", server, target, level,
103                          for_me ? VERIFIED_MSG(verified, SILCTXT_PUBMSG_ME) :
104                                   VERIFIED_MSG(verified,SILCTXT_PUBMSG),
105                          printnick, msg, nickmode);
106     }
107   } else {
108     /* message to not existing/active channel */
109     if (color != NULL) {
110       /* highlighted nick */
111       printformat_module("fe-common/silc", server, target, level,
112                          VERIFIED_MSG(verified, SILCTXT_PUBMSG_HILIGHT_CHANNEL),
113                          color, printnick, target, msg, nickmode);
114     } else {
115       printformat_module("fe-common/silc", server, target, level,
116                          for_me ? VERIFIED_MSG(verified, SILCTXT_PUBMSG_ME_CHANNEL) :
117                          VERIFIED_MSG(verified, SILCTXT_PUBMSG_CHANNEL),
118                          printnick, target, msg, nickmode);
119     }
120   }
121
122   g_free_not_null(freemsg);
123   g_free_not_null(color);
124 }
125
126 static void sig_signed_message_own_public(SERVER_REC * server,
127                                           const char *msg,
128                                           const char *target)
129 {
130   WINDOW_REC *window;
131   CHANNEL_REC *channel;
132   const char *nickmode;
133   char *freemsg = NULL;
134   int print_channel;
135
136   channel = channel_find(server, target);
137   if (channel != NULL)
138     target = channel->visible_name;
139
140   nickmode = channel_get_nickmode(channel, server->nick);
141
142   window = channel == NULL ? NULL :
143       window_item_window((WI_ITEM_REC *) channel);
144
145   print_channel = window == NULL ||
146       window->active != (WI_ITEM_REC *) channel;
147
148   if (!print_channel && settings_get_bool("print_active_channel") &&
149       window != NULL && g_slist_length(window->items) > 1)
150     print_channel = TRUE;
151
152   if (settings_get_bool("emphasis"))
153     msg = freemsg = expand_emphasis((WI_ITEM_REC *) channel, msg);
154
155   if (!print_channel) {
156     printformat_module("fe-common/silc", server, target,
157                        MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
158                        MSGLEVEL_NO_ACT, SILCTXT_OWN_MSG_SIGNED, server->nick, msg,
159                        nickmode);
160   } else {
161     printformat_module("fe-common/silc", server, target,
162                        MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
163                        MSGLEVEL_NO_ACT, SILCTXT_OWN_MSG_CHANNEL_SIGNED,
164                        server->nick, target, msg, nickmode);
165   }
166
167   g_free_not_null(freemsg);
168 }
169
170 static void sig_signed_message_private(SERVER_REC * server,
171                                        const char *msg, const char *nick,
172                                        const char *address, int verified)
173 {
174   QUERY_REC *query;
175   char *freemsg = NULL;
176
177   query = query_find(server, nick);
178
179   if (settings_get_bool("emphasis"))
180     msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
181
182   printformat_module("fe-common/silc", server, nick, MSGLEVEL_MSGS,
183                      query == NULL ? VERIFIED_MSG(verified, SILCTXT_MSG_PRIVATE) :
184                      VERIFIED_MSG(verified, SILCTXT_MSG_PRIVATE_QUERY), nick, address, msg);
185
186   g_free_not_null(freemsg);
187 }
188
189 static void sig_signed_message_own_private(SERVER_REC * server,
190                                            const char *msg,
191                                            const char *target,
192                                            const char *origtarget)
193 {
194   QUERY_REC *query;
195   char *freemsg = NULL;
196
197   g_return_if_fail(server != NULL);
198   g_return_if_fail(msg != NULL);
199
200   if (target == NULL) {
201     /* this should only happen if some special target failed and
202        we should display some error message. currently the special
203        targets are only ',' and '.'. */
204     g_return_if_fail(strcmp(origtarget, ",") == 0 ||
205                      strcmp(origtarget, ".") == 0);
206
207     printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CLIENTNOTICE,
208                        *origtarget == ',' ? SILCTXT_NO_MSGS_GOT :
209                        SILCTXT_NO_MSGS_SENT);
210     signal_stop();
211     return;
212   }
213
214   query = privmsg_get_query(server, target, TRUE, MSGLEVEL_MSGS);
215
216   if (settings_get_bool("emphasis"))
217     msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
218
219   printformat_module("fe-common/silc", server, target,
220                      MSGLEVEL_MSGS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT,
221                      query == NULL ? SILCTXT_OWN_MSG_PRIVATE_SIGNED :
222                      SILCTXT_OWN_MSG_PRIVATE_QUERY_SIGNED, target, msg,
223                      server->nick);
224
225   g_free_not_null(freemsg);
226 }
227
228 static void sig_message_own_action_all(SERVER_REC *server, 
229                                         const char *msg, const char *target,
230                                         bool is_channel, bool is_signed)
231 {
232   void *item;
233   char *freemsg = NULL;
234
235   if (is_channel)
236     item = channel_find(server, target);
237   else
238     item = query_find(server, target);
239
240   if (settings_get_bool("emphasis"))
241     msg = freemsg = expand_emphasis(item, msg);
242
243   printformat(server, target,
244               MSGLEVEL_ACTIONS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT |
245               (is_channel ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS),
246               item != NULL ? 
247               (is_signed ? SILCTXT_OWN_ACTION_SIGNED : SILCTXT_OWN_ACTION) :
248               (is_signed ? SILCTXT_OWN_ACTION_TARGET_SIGNED :
249                            SILCTXT_OWN_ACTION_TARGET),
250               server->nick, msg, target);
251
252   g_free_not_null(freemsg);
253 }
254
255 static void sig_message_own_action(SERVER_REC *server, const char *msg,
256                                    const char *target)
257 {
258   sig_message_own_action_all(server, msg, target, TRUE, FALSE);
259 }
260
261 static void sig_message_own_private_action(SERVER_REC *server,
262                                            const char *msg, const char *target)
263 {
264   sig_message_own_action_all(server, msg, target, FALSE, FALSE);
265 }
266
267 static void sig_message_own_action_signed(SERVER_REC *server,
268                                           const char *msg, const char *target)
269 {
270   sig_message_own_action_all(server, msg, target, TRUE, TRUE);
271 }
272
273 static void sig_message_own_private_action_signed(SERVER_REC *server,
274                                           const char *msg, const char *target)
275 {
276   sig_message_own_action_all(server, msg, target, FALSE, TRUE);
277 }
278
279 static void sig_message_action_all(SERVER_REC *server, const char *msg,
280                                    const char *nick, const char *address,
281                                    const char *target, int is_channel,
282                                    int verified)
283 {
284   void *item;
285   char *freemsg = NULL;
286   int level;
287
288   level = MSGLEVEL_ACTIONS |
289           (is_channel ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS);
290
291   if (ignore_check(server, nick, address, target, msg, level))
292     return;
293
294   if (is_channel)
295     item = channel_find(server, target);
296   else
297     item = privmsg_get_query(server, nick, FALSE, level);
298
299   if (settings_get_bool("emphasis"))
300     msg = freemsg = expand_emphasis(item, msg);
301
302   if (is_channel) {
303     /* channel action */ 
304     if (window_item_is_active(item)) {
305       /* message to active channel in window */
306       printformat(server, target, level,
307                   VERIFIED_MSG2(verified, SILCTXT_ACTION_PUBLIC), 
308                   nick, target, msg);
309     } else {
310       /* message to not existing/active channel */
311       printformat(server, target, level,
312                   VERIFIED_MSG2(verified, SILCTXT_ACTION_PUBLIC_CHANNEL),
313                   nick, target, msg);
314     }
315   } else {
316     /* private action */
317     printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS,
318                 item == NULL ? VERIFIED_MSG2(verified, SILCTXT_ACTION_PRIVATE) :
319                 VERIFIED_MSG2(verified, SILCTXT_ACTION_PRIVATE_QUERY),
320                 nick, address == NULL ? "" : address, msg);
321   }
322
323   g_free_not_null(freemsg);
324 }
325
326 static void sig_message_action(SERVER_REC *server, const char *msg,
327                                    const char *nick, const char *address,
328                                    const char *target)
329 {
330   sig_message_action_all(server, msg, nick, address, target, TRUE, -1);
331 }
332
333 static void sig_message_private_action(SERVER_REC *server, const char *msg,
334                                    const char *nick, const char *address,
335                                    const char *target)
336 {
337   sig_message_action_all(server, msg, nick, address, target, FALSE, -1);
338 }
339
340 static void sig_message_action_signed(SERVER_REC *server, const char *msg,
341                                    const char *nick, const char *address,
342                                    const char *target, int verified)
343 {
344   sig_message_action_all(server, msg, nick, address, target, TRUE, verified);
345 }
346
347 static void sig_message_private_action_signed(SERVER_REC *server,
348                                    const char *msg, const char *nick,
349                                    const char *address, const char *target,
350                                    int verified)
351 {
352   sig_message_action_all(server, msg, nick, address, target, FALSE, verified);
353 }
354
355 static void sig_message_own_notice_all(SERVER_REC *server, 
356                                         const char *msg, const char *target,
357                                         bool is_signed)
358 {
359   printformat(server, target,
360               MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT,
361               (is_signed ? SILCTXT_OWN_NOTICE_SIGNED : SILCTXT_OWN_NOTICE),
362               target, msg);
363 }
364
365 static void sig_message_own_notice(SERVER_REC *server, const char *msg,
366                                    const char *target)
367 {
368   sig_message_own_notice_all(server, msg, target, FALSE);
369 }
370
371 static void sig_message_own_notice_signed(SERVER_REC *server,
372                                           const char *msg, const char *target)
373 {
374   sig_message_own_notice_all(server, msg, target, TRUE);
375 }
376
377 static void sig_message_notice_all(SERVER_REC *server, const char *msg,
378                                    const char *nick, const char *address,
379                                    const char *target, int is_channel,
380                                    int verified)
381 {
382   if (ignore_check(server, nick, address, target, msg, MSGLEVEL_NOTICES))
383     return;
384
385   if (is_channel) {
386     /* channel notice */ 
387       printformat(server, target, MSGLEVEL_NOTICES,
388                   VERIFIED_MSG2(verified, SILCTXT_NOTICE_PUBLIC), 
389                   nick, target, msg);
390   } else {
391     /* private notice */
392     printformat(server, nick, MSGLEVEL_NOTICES,
393                 VERIFIED_MSG2(verified, SILCTXT_NOTICE_PRIVATE),
394                 nick, address == NULL ? "" : address, msg);
395   }
396
397 }
398
399 static void sig_message_notice(SERVER_REC *server, const char *msg,
400                                    const char *nick, const char *address,
401                                    const char *target)
402 {
403   sig_message_notice_all(server, msg, nick, address, target, TRUE, -1);
404 }
405
406 static void sig_message_private_notice(SERVER_REC *server, const char *msg,
407                                    const char *nick, const char *address,
408                                    const char *target)
409 {
410   sig_message_notice_all(server, msg, nick, address, target, FALSE, -1);
411 }
412
413 static void sig_message_notice_signed(SERVER_REC *server, const char *msg,
414                                    const char *nick, const char *address,
415                                    const char *target, int verified)
416 {
417   sig_message_notice_all(server, msg, nick, address, target, TRUE, verified);
418 }
419
420 static void sig_message_private_notice_signed(SERVER_REC *server,
421                                    const char *msg, const char *nick,
422                                    const char *address, const char *target,
423                                    int verified)
424 {
425   sig_message_notice_all(server, msg, nick, address, target, FALSE, verified);
426 }
427
428 void fe_silc_messages_init(void)
429 {
430   signal_add_last("message signed_public",
431                   (SIGNAL_FUNC) sig_signed_message_public);
432   signal_add_last("message signed_own_public",
433                   (SIGNAL_FUNC) sig_signed_message_own_public);
434   signal_add_last("message signed_private",
435                   (SIGNAL_FUNC) sig_signed_message_private);
436   signal_add_last("message signed_own_private",
437                   (SIGNAL_FUNC) sig_signed_message_own_private);
438
439   signal_add_last("message silc own_action",
440                   (SIGNAL_FUNC) sig_message_own_action);
441   signal_add_last("message silc action",
442                   (SIGNAL_FUNC) sig_message_action);
443   signal_add_last("message silc signed_own_action",
444                   (SIGNAL_FUNC) sig_message_own_action_signed);
445   signal_add_last("message silc signed_action",
446                   (SIGNAL_FUNC) sig_message_action_signed);
447   signal_add_last("message silc own_private_action",
448                   (SIGNAL_FUNC) sig_message_own_private_action);
449   signal_add_last("message silc private_action",
450                   (SIGNAL_FUNC) sig_message_private_action);
451   signal_add_last("message silc signed_own_private_action",
452                   (SIGNAL_FUNC) sig_message_own_private_action_signed);
453   signal_add_last("message silc signed_private_action",
454                   (SIGNAL_FUNC) sig_message_private_action_signed);
455
456   signal_add_last("message silc own_notice",
457                   (SIGNAL_FUNC) sig_message_own_notice);
458   signal_add_last("message silc notice",
459                   (SIGNAL_FUNC) sig_message_notice);
460   signal_add_last("message silc signed_own_notice",
461                   (SIGNAL_FUNC) sig_message_own_notice_signed);
462   signal_add_last("message silc signed_notice",
463                   (SIGNAL_FUNC) sig_message_notice_signed);
464   signal_add_last("message silc own_private_notice",
465                   (SIGNAL_FUNC) sig_message_own_notice);
466   signal_add_last("message silc private_notice",
467                   (SIGNAL_FUNC) sig_message_private_notice);
468   signal_add_last("message silc signed_own_private_notice",
469                   (SIGNAL_FUNC) sig_message_own_notice_signed);
470   signal_add_last("message silc signed_private_notice",
471                   (SIGNAL_FUNC) sig_message_private_notice_signed);
472 }
473
474 void fe_silc_messages_deinit(void)
475 {
476   signal_remove("message signed_public",
477                 (SIGNAL_FUNC) sig_signed_message_public);
478   signal_remove("message signed_own_public",
479                 (SIGNAL_FUNC) sig_signed_message_own_public);
480   signal_remove("message signed_private",
481                 (SIGNAL_FUNC) sig_signed_message_private);
482   signal_remove("message signed_own_private",
483                 (SIGNAL_FUNC) sig_signed_message_own_private);
484
485   signal_remove("message silc own_action",
486                 (SIGNAL_FUNC) sig_message_own_action);
487   signal_remove("message silc action",
488                 (SIGNAL_FUNC) sig_message_action);
489   signal_remove("message silc signed_own_action",
490                 (SIGNAL_FUNC) sig_message_own_action_signed);
491   signal_remove("message silc signed_action",
492                 (SIGNAL_FUNC) sig_message_action_signed);
493   signal_remove("message silc own_private_action",
494                 (SIGNAL_FUNC) sig_message_own_private_action);
495   signal_remove("message silc private_action",
496                 (SIGNAL_FUNC) sig_message_private_action);
497   signal_remove("message silc signed_own_private_action",
498                 (SIGNAL_FUNC) sig_message_own_private_action_signed);
499   signal_remove("message silc signed_private_action",
500                 (SIGNAL_FUNC) sig_message_private_action_signed);
501
502   signal_remove("message silc own_notice",
503                 (SIGNAL_FUNC) sig_message_own_notice);
504   signal_remove("message silc notice",
505                 (SIGNAL_FUNC) sig_message_notice);
506   signal_remove("message silc signed_own_notice",
507                 (SIGNAL_FUNC) sig_message_own_notice_signed);
508   signal_remove("message silc signed_notice",
509                 (SIGNAL_FUNC) sig_message_notice_signed);
510   signal_remove("message silc own_private_notice",
511                 (SIGNAL_FUNC) sig_message_own_notice);
512   signal_remove("message silc private_notice",
513                 (SIGNAL_FUNC) sig_message_private_notice);
514   signal_remove("message silc signed_own_private_notice",
515                 (SIGNAL_FUNC) sig_message_own_notice_signed);
516   signal_remove("message silc signed_private_notice",
517                 (SIGNAL_FUNC) sig_message_private_notice_signed);
518 }