Thu Jun 14 21:15:31 CEST 2007 Jochen Eisinger <coffee@silcnet.org>
[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     (char *)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 }
124
125 static void sig_signed_message_own_public(SERVER_REC * server,
126                                           const char *msg,
127                                           const char *target)
128 {
129   WINDOW_REC *window;
130   CHANNEL_REC *channel;
131   const char *nickmode;
132   char *freemsg = NULL;
133   int print_channel;
134
135   channel = channel_find(server, target);
136   if (channel != NULL)
137     target = channel->visible_name;
138
139   nickmode = channel_get_nickmode(channel, server->nick);
140
141   window = channel == NULL ? NULL :
142       window_item_window((WI_ITEM_REC *) channel);
143
144   print_channel = window == NULL ||
145       window->active != (WI_ITEM_REC *) channel;
146
147   if (!print_channel && settings_get_bool("print_active_channel") &&
148       window != NULL && g_slist_length(window->items) > 1)
149     print_channel = TRUE;
150
151   if (settings_get_bool("emphasis"))
152     msg = freemsg = expand_emphasis((WI_ITEM_REC *) channel, msg);
153
154   if (!print_channel) {
155     printformat_module("fe-common/silc", server, target,
156                        MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
157                        MSGLEVEL_NO_ACT, SILCTXT_OWN_MSG_SIGNED, server->nick, msg,
158                        nickmode);
159   } else {
160     printformat_module("fe-common/silc", server, target,
161                        MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
162                        MSGLEVEL_NO_ACT, SILCTXT_OWN_MSG_CHANNEL_SIGNED,
163                        server->nick, target, msg, nickmode);
164   }
165
166   g_free_not_null(freemsg);
167 }
168
169 static void sig_signed_message_private(SERVER_REC * server,
170                                        const char *msg, const char *nick,
171                                        const char *address, int verified)
172 {
173   QUERY_REC *query;
174   char *freemsg = NULL;
175
176   query = query_find(server, nick);
177
178   if (settings_get_bool("emphasis"))
179     msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
180
181   printformat_module("fe-common/silc", server, nick, MSGLEVEL_MSGS,
182                      query == NULL ? VERIFIED_MSG(verified, SILCTXT_MSG_PRIVATE) :
183                      VERIFIED_MSG(verified, SILCTXT_MSG_PRIVATE_QUERY), nick, address, msg);
184
185   g_free_not_null(freemsg);
186 }
187
188 static void sig_signed_message_own_private(SERVER_REC * server,
189                                            const char *msg,
190                                            const char *target,
191                                            const char *origtarget)
192 {
193   QUERY_REC *query;
194   char *freemsg = NULL;
195
196   g_return_if_fail(server != NULL);
197   g_return_if_fail(msg != NULL);
198
199   if (target == NULL) {
200     /* this should only happen if some special target failed and
201        we should display some error message. currently the special
202        targets are only ',' and '.'. */
203     g_return_if_fail(strcmp(origtarget, ",") == 0 ||
204                      strcmp(origtarget, ".") == 0);
205
206     printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CLIENTNOTICE,
207                        *origtarget == ',' ? SILCTXT_NO_MSGS_GOT :
208                        SILCTXT_NO_MSGS_SENT);
209     signal_stop();
210     return;
211   }
212
213   query = privmsg_get_query(server, target, TRUE, MSGLEVEL_MSGS);
214
215   if (settings_get_bool("emphasis"))
216     msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
217
218   printformat_module("fe-common/silc", server, target,
219                      MSGLEVEL_MSGS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT,
220                      query == NULL ? SILCTXT_OWN_MSG_PRIVATE_SIGNED :
221                      SILCTXT_OWN_MSG_PRIVATE_QUERY_SIGNED, target, msg,
222                      server->nick);
223
224   g_free_not_null(freemsg);
225 }
226
227 static void sig_message_own_action_all(SERVER_REC *server,
228                                         const char *msg, const char *target,
229                                         bool is_channel, bool is_signed)
230 {
231   void *item;
232   char *freemsg = NULL;
233
234   if (is_channel)
235     item = channel_find(server, target);
236   else
237     item = query_find(server, target);
238
239   if (settings_get_bool("emphasis"))
240     msg = freemsg = expand_emphasis(item, msg);
241
242   printformat(server, target,
243               MSGLEVEL_ACTIONS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT |
244               (is_channel ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS),
245               item != NULL ?
246               (is_signed ? SILCTXT_OWN_ACTION_SIGNED : SILCTXT_OWN_ACTION) :
247               (is_signed ? SILCTXT_OWN_ACTION_TARGET_SIGNED :
248                            SILCTXT_OWN_ACTION_TARGET),
249               server->nick, msg, target);
250
251   g_free_not_null(freemsg);
252 }
253
254 static void sig_message_own_action(SERVER_REC *server, const char *msg,
255                                    const char *target)
256 {
257   sig_message_own_action_all(server, msg, target, TRUE, FALSE);
258 }
259
260 static void sig_message_own_private_action(SERVER_REC *server,
261                                            const char *msg, const char *target)
262 {
263   sig_message_own_action_all(server, msg, target, FALSE, FALSE);
264 }
265
266 static void sig_message_own_action_signed(SERVER_REC *server,
267                                           const char *msg, const char *target)
268 {
269   sig_message_own_action_all(server, msg, target, TRUE, TRUE);
270 }
271
272 static void sig_message_own_private_action_signed(SERVER_REC *server,
273                                           const char *msg, const char *target)
274 {
275   sig_message_own_action_all(server, msg, target, FALSE, TRUE);
276 }
277
278 static void sig_message_action_all(SERVER_REC *server, const char *msg,
279                                    const char *nick, const char *address,
280                                    const char *target, int is_channel,
281                                    int verified)
282 {
283   void *item;
284   char *freemsg = NULL;
285   int level;
286
287   level = MSGLEVEL_ACTIONS |
288           (is_channel ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS);
289
290   if (ignore_check(server, nick, address, target, msg, level))
291     return;
292
293   if (is_channel)
294     item = channel_find(server, target);
295   else
296     item = privmsg_get_query(server, nick, FALSE, level);
297
298   if (settings_get_bool("emphasis"))
299     msg = freemsg = expand_emphasis(item, msg);
300
301   if (is_channel) {
302     /* channel action */
303     if (window_item_is_active(item)) {
304       /* message to active channel in window */
305       printformat(server, target, level,
306                   VERIFIED_MSG2(verified, SILCTXT_ACTION_PUBLIC),
307                   nick, target, msg);
308     } else {
309       /* message to not existing/active channel */
310       printformat(server, target, level,
311                   VERIFIED_MSG2(verified, SILCTXT_ACTION_PUBLIC_CHANNEL),
312                   nick, target, msg);
313     }
314   } else {
315     /* private action */
316     printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS,
317                 item == NULL ? VERIFIED_MSG2(verified, SILCTXT_ACTION_PRIVATE) :
318                 VERIFIED_MSG2(verified, SILCTXT_ACTION_PRIVATE_QUERY),
319                 nick, address == NULL ? "" : address, msg);
320   }
321
322   g_free_not_null(freemsg);
323 }
324
325 static void sig_message_action(SERVER_REC *server, const char *msg,
326                                    const char *nick, const char *address,
327                                    const char *target)
328 {
329   sig_message_action_all(server, msg, nick, address, target, TRUE, -1);
330 }
331
332 static void sig_message_private_action(SERVER_REC *server, const char *msg,
333                                    const char *nick, const char *address,
334                                    const char *target)
335 {
336   sig_message_action_all(server, msg, nick, address, target, FALSE, -1);
337 }
338
339 static void sig_message_action_signed(SERVER_REC *server, const char *msg,
340                                    const char *nick, const char *address,
341                                    const char *target, int verified)
342 {
343   sig_message_action_all(server, msg, nick, address, target, TRUE, verified);
344 }
345
346 static void sig_message_private_action_signed(SERVER_REC *server,
347                                    const char *msg, const char *nick,
348                                    const char *address, const char *target,
349                                    int verified)
350 {
351   sig_message_action_all(server, msg, nick, address, target, FALSE, verified);
352 }
353
354 static void sig_message_own_notice_all(SERVER_REC *server,
355                                         const char *msg, const char *target,
356                                         bool is_signed)
357 {
358   printformat(server, target,
359               MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT,
360               (is_signed ? SILCTXT_OWN_NOTICE_SIGNED : SILCTXT_OWN_NOTICE),
361               target, msg);
362 }
363
364 static void sig_message_own_notice(SERVER_REC *server, const char *msg,
365                                    const char *target)
366 {
367   sig_message_own_notice_all(server, msg, target, FALSE);
368 }
369
370 static void sig_message_own_notice_signed(SERVER_REC *server,
371                                           const char *msg, const char *target)
372 {
373   sig_message_own_notice_all(server, msg, target, TRUE);
374 }
375
376 static void sig_message_notice_all(SERVER_REC *server, const char *msg,
377                                    const char *nick, const char *address,
378                                    const char *target, int is_channel,
379                                    int verified)
380 {
381   if (ignore_check(server, nick, address, target, msg, MSGLEVEL_NOTICES))
382     return;
383
384   if (is_channel) {
385     /* channel notice */
386       printformat(server, target, MSGLEVEL_NOTICES,
387                   VERIFIED_MSG2(verified, SILCTXT_NOTICE_PUBLIC),
388                   nick, target, msg);
389   } else {
390     /* private notice */
391     printformat(server, nick, MSGLEVEL_NOTICES,
392                 VERIFIED_MSG2(verified, SILCTXT_NOTICE_PRIVATE),
393                 nick, address == NULL ? "" : address, msg);
394   }
395
396 }
397
398 static void sig_message_notice(SERVER_REC *server, const char *msg,
399                                    const char *nick, const char *address,
400                                    const char *target)
401 {
402   sig_message_notice_all(server, msg, nick, address, target, TRUE, -1);
403 }
404
405 static void sig_message_private_notice(SERVER_REC *server, const char *msg,
406                                    const char *nick, const char *address,
407                                    const char *target)
408 {
409   sig_message_notice_all(server, msg, nick, address, target, FALSE, -1);
410 }
411
412 static void sig_message_notice_signed(SERVER_REC *server, const char *msg,
413                                    const char *nick, const char *address,
414                                    const char *target, int verified)
415 {
416   sig_message_notice_all(server, msg, nick, address, target, TRUE, verified);
417 }
418
419 static void sig_message_private_notice_signed(SERVER_REC *server,
420                                    const char *msg, const char *nick,
421                                    const char *address, const char *target,
422                                    int verified)
423 {
424   sig_message_notice_all(server, msg, nick, address, target, FALSE, verified);
425 }
426
427 void fe_silc_messages_init(void)
428 {
429   signal_add_last("message signed_public",
430                   (SIGNAL_FUNC) sig_signed_message_public);
431   signal_add_last("message signed_own_public",
432                   (SIGNAL_FUNC) sig_signed_message_own_public);
433   signal_add_last("message signed_private",
434                   (SIGNAL_FUNC) sig_signed_message_private);
435   signal_add_last("message signed_own_private",
436                   (SIGNAL_FUNC) sig_signed_message_own_private);
437
438   signal_add_last("message silc own_action",
439                   (SIGNAL_FUNC) sig_message_own_action);
440   signal_add_last("message silc action",
441                   (SIGNAL_FUNC) sig_message_action);
442   signal_add_last("message silc signed_own_action",
443                   (SIGNAL_FUNC) sig_message_own_action_signed);
444   signal_add_last("message silc signed_action",
445                   (SIGNAL_FUNC) sig_message_action_signed);
446   signal_add_last("message silc own_private_action",
447                   (SIGNAL_FUNC) sig_message_own_private_action);
448   signal_add_last("message silc private_action",
449                   (SIGNAL_FUNC) sig_message_private_action);
450   signal_add_last("message silc signed_own_private_action",
451                   (SIGNAL_FUNC) sig_message_own_private_action_signed);
452   signal_add_last("message silc signed_private_action",
453                   (SIGNAL_FUNC) sig_message_private_action_signed);
454
455   signal_add_last("message silc own_notice",
456                   (SIGNAL_FUNC) sig_message_own_notice);
457   signal_add_last("message silc notice",
458                   (SIGNAL_FUNC) sig_message_notice);
459   signal_add_last("message silc signed_own_notice",
460                   (SIGNAL_FUNC) sig_message_own_notice_signed);
461   signal_add_last("message silc signed_notice",
462                   (SIGNAL_FUNC) sig_message_notice_signed);
463   signal_add_last("message silc own_private_notice",
464                   (SIGNAL_FUNC) sig_message_own_notice);
465   signal_add_last("message silc private_notice",
466                   (SIGNAL_FUNC) sig_message_private_notice);
467   signal_add_last("message silc signed_own_private_notice",
468                   (SIGNAL_FUNC) sig_message_own_notice_signed);
469   signal_add_last("message silc signed_private_notice",
470                   (SIGNAL_FUNC) sig_message_private_notice_signed);
471 }
472
473 void fe_silc_messages_deinit(void)
474 {
475   signal_remove("message signed_public",
476                 (SIGNAL_FUNC) sig_signed_message_public);
477   signal_remove("message signed_own_public",
478                 (SIGNAL_FUNC) sig_signed_message_own_public);
479   signal_remove("message signed_private",
480                 (SIGNAL_FUNC) sig_signed_message_private);
481   signal_remove("message signed_own_private",
482                 (SIGNAL_FUNC) sig_signed_message_own_private);
483
484   signal_remove("message silc own_action",
485                 (SIGNAL_FUNC) sig_message_own_action);
486   signal_remove("message silc action",
487                 (SIGNAL_FUNC) sig_message_action);
488   signal_remove("message silc signed_own_action",
489                 (SIGNAL_FUNC) sig_message_own_action_signed);
490   signal_remove("message silc signed_action",
491                 (SIGNAL_FUNC) sig_message_action_signed);
492   signal_remove("message silc own_private_action",
493                 (SIGNAL_FUNC) sig_message_own_private_action);
494   signal_remove("message silc private_action",
495                 (SIGNAL_FUNC) sig_message_private_action);
496   signal_remove("message silc signed_own_private_action",
497                 (SIGNAL_FUNC) sig_message_own_private_action_signed);
498   signal_remove("message silc signed_private_action",
499                 (SIGNAL_FUNC) sig_message_private_action_signed);
500
501   signal_remove("message silc own_notice",
502                 (SIGNAL_FUNC) sig_message_own_notice);
503   signal_remove("message silc notice",
504                 (SIGNAL_FUNC) sig_message_notice);
505   signal_remove("message silc signed_own_notice",
506                 (SIGNAL_FUNC) sig_message_own_notice_signed);
507   signal_remove("message silc signed_notice",
508                 (SIGNAL_FUNC) sig_message_notice_signed);
509   signal_remove("message silc own_private_notice",
510                 (SIGNAL_FUNC) sig_message_own_notice);
511   signal_remove("message silc private_notice",
512                 (SIGNAL_FUNC) sig_message_private_notice);
513   signal_remove("message silc signed_own_private_notice",
514                 (SIGNAL_FUNC) sig_message_own_notice_signed);
515   signal_remove("message silc signed_private_notice",
516                 (SIGNAL_FUNC) sig_message_private_notice_signed);
517 }