comparison mcabber/mcabber/xmpp_muc.c @ 1685:1342df44c814

Improved events interface * User can pass additional arguments to event handler * MUC invitation reject now can be supplied a reason
author Myhailo Danylenko <isbear@ukrpost.net>
date Tue, 02 Feb 2010 22:44:18 +0100
parents 95df4ea512c8
children fc67e1c7a5d4
comparison
equal deleted inserted replaced
1684:95df4ea512c8 1685:1342df44c814
22 22
23 #include <string.h> 23 #include <string.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 25
26 #include "xmpp_helper.h" 26 #include "xmpp_helper.h"
27 #include "xmpp_muc.h"
27 #include "events.h" 28 #include "events.h"
28 #include "hooks.h" 29 #include "hooks.h"
29 #include "screen.h" 30 #include "screen.h"
30 #include "hbuf.h" 31 #include "hbuf.h"
31 #include "roster.h" 32 #include "roster.h"
35 #include "histolog.h" 36 #include "histolog.h"
36 37
37 extern enum imstatus mystatus; 38 extern enum imstatus mystatus;
38 extern gchar *mystatusmsg; 39 extern gchar *mystatusmsg;
39 40
40 static void decline_invitation(event_muc_invitation *invitation, char *reason) 41 static void decline_invitation(event_muc_invitation *invitation, const char *reason)
41 { 42 {
42 // cut and paste from xmpp_room_invite 43 // cut and paste from xmpp_room_invite
43 LmMessage *m; 44 LmMessage *m;
44 LmMessageNode *x, *y; 45 LmMessageNode *x, *y;
45 46
60 61
61 lm_connection_send(lconnection, m, NULL); 62 lm_connection_send(lconnection, m, NULL);
62 lm_message_unref(m); 63 lm_message_unref(m);
63 } 64 }
64 65
65 static int evscallback_invitation(eviqs *evp, guint evcontext) 66 void destroy_event_muc_invitation(event_muc_invitation *invitation)
66 { 67 {
67 event_muc_invitation *invitation = evp->data; 68 g_free(invitation->to);
69 g_free(invitation->from);
70 g_free(invitation->passwd);
71 g_free(invitation->reason);
72 g_free(invitation);
73 }
74
75 // invitation event handler
76 // TODO: if event is accepted, check if other events to the same room exist and
77 // destroy them? (need invitation registry list for that)
78 static gboolean evscallback_invitation(guint evcontext, const char *arg, gpointer userdata)
79 {
80 event_muc_invitation *invitation = userdata;
68 81
69 // Sanity check 82 // Sanity check
70 if (!invitation) { 83 if (G_UNLIKELY(!invitation)) {
71 // Shouldn't happen. 84 // Shouldn't happen.
72 scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback."); 85 scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
73 return 0; 86 return FALSE;
74 } 87 }
75 88
76 if (evcontext == EVS_CONTEXT_TIMEOUT) { 89 if (evcontext == EVS_CONTEXT_TIMEOUT) {
77 scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.", evp->id); 90 scr_LogPrint(LPRINT_LOGNORM, "Invitation event %s timed out, cancelled.", invitation->to);
78 goto evscallback_invitation_free; 91 return FALSE;
79 } 92 }
80 if (evcontext == EVS_CONTEXT_CANCEL) { 93 if (evcontext == EVS_CONTEXT_CANCEL) {
81 scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id); 94 scr_LogPrint(LPRINT_LOGNORM, "Invitation event %s cancelled.", invitation->to);
82 goto evscallback_invitation_free; 95 return FALSE;
83 } 96 }
84 if (!(evcontext & EVS_CONTEXT_USER)) 97 if (!(evcontext == EVS_CONTEXT_ACCEPT || evcontext == EVS_CONTEXT_REJECT))
85 goto evscallback_invitation_free; 98 return FALSE;
86 // Ok, let's work now. 99
87 // evcontext: 0, 1 == reject, accept 100 // Ok, let's work now
88 101 if (evcontext == EVS_CONTEXT_ACCEPT) {
89 if (evcontext & ~EVS_CONTEXT_USER) {
90 char *nickname = default_muc_nickname(invitation->to); 102 char *nickname = default_muc_nickname(invitation->to);
91 xmpp_room_join(invitation->to, nickname, invitation->passwd); 103 xmpp_room_join(invitation->to, nickname, invitation->passwd);
92 g_free(nickname); 104 g_free(nickname);
93 } else { 105 } else {
94 scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to); 106 scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to);
95 decline_invitation(invitation, NULL); 107 decline_invitation(invitation, arg);
96 } 108 }
97 109
98 evscallback_invitation_free: 110 return FALSE;
99 g_free(invitation->to);
100 g_free(invitation->from);
101 g_free(invitation->passwd);
102 g_free(invitation->reason);
103 g_free(invitation);
104 evp->data = NULL;
105 return 0;
106 } 111 }
107 112
108 // Join a MUC room 113 // Join a MUC room
109 void xmpp_room_join(const char *room, const char *nickname, const char *passwd) 114 void xmpp_room_join(const char *room, const char *nickname, const char *passwd)
110 { 115 {
640 645
641 // got_invite(from, to, reason, passwd) 646 // got_invite(from, to, reason, passwd)
642 // This function should be called when receiving an invitation from user 647 // This function should be called when receiving an invitation from user
643 // "from", to enter the room "to". Optional reason and room password can 648 // "from", to enter the room "to". Optional reason and room password can
644 // be provided. 649 // be provided.
650 // TODO: check for duplicate invites (need an existing invitation registry
651 // for that).
645 static void got_invite(const char* from, const char *to, const char* reason, 652 static void got_invite(const char* from, const char *to, const char* reason,
646 const char* passwd) 653 const char* passwd)
647 { 654 {
648 eviqs *evn;
649 event_muc_invitation *invitation;
650 GString *sbuf; 655 GString *sbuf;
651 char *barejid; 656 char *barejid;
652 GSList *room_elt; 657 GSList *room_elt;
653 658
654 sbuf = g_string_new(""); 659 sbuf = g_string_new("");
663 668
664 barejid = jidtodisp(from); 669 barejid = jidtodisp(from);
665 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); 670 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
666 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); 671 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
667 672
668 evn = evs_new(EVS_TYPE_INVITATION, EVS_MAX_TIMEOUT); 673 {
669 if (evn) { 674 const char *id;
670 evn->callback = &evscallback_invitation; 675 char *desc = g_strdup_printf("<%s> invites you to %s", from, to);
676 event_muc_invitation *invitation;
677
671 invitation = g_new(event_muc_invitation, 1); 678 invitation = g_new(event_muc_invitation, 1);
672 invitation->to = g_strdup(to); 679 invitation->to = g_strdup(to);
673 invitation->from = g_strdup(from); 680 invitation->from = g_strdup(from);
674 invitation->passwd = g_strdup(passwd); 681 invitation->passwd = g_strdup(passwd);
675 invitation->reason = g_strdup(reason); 682 invitation->reason = g_strdup(reason);
676 evn->data = invitation; 683
677 evn->desc = g_strdup_printf("<%s> invites you to %s ", from, to); 684 id = evs_new(desc, NULL, 0, evscallback_invitation, invitation,
678 g_string_printf(sbuf, "Please use /event %s accept|reject", evn->id); 685 (GDestroyNotify)destroy_event_muc_invitation);
679 } else { 686 g_free(desc);
680 g_string_printf(sbuf, "Unable to create a new event!"); 687 if (id)
688 g_string_printf(sbuf, "Please use /event %s accept|reject", id);
689 else
690 g_string_printf(sbuf, "Unable to create a new event!");
681 } 691 }
682 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); 692 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
683 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); 693 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
684 g_string_free(sbuf, TRUE); 694 g_string_free(sbuf, TRUE);
685 g_free(barejid); 695 g_free(barejid);