Mercurial > ~mikael > mcabber > hg
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); |