summaryrefslogtreecommitdiffstats
path: root/src/jabber_whiteboard/message-processors.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jabber_whiteboard/message-processors.cpp')
-rw-r--r--src/jabber_whiteboard/message-processors.cpp330
1 files changed, 330 insertions, 0 deletions
diff --git a/src/jabber_whiteboard/message-processors.cpp b/src/jabber_whiteboard/message-processors.cpp
new file mode 100644
index 000000000..bd24f7ad8
--- /dev/null
+++ b/src/jabber_whiteboard/message-processors.cpp
@@ -0,0 +1,330 @@
+/**
+ * Whiteboard session manager
+ * Jabber received message processors
+ *
+ * Authors:
+ * David Yip <yipdw@rose-hulman.edu>
+ *
+ * Copyright (c) 2005 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+extern "C" {
+#include <loudmouth/loudmouth.h>
+}
+
+#include <glibmm/i18n.h>
+
+#include "xml/session.h"
+#include "xml/document.h"
+
+#include "desktop-handles.h"
+#include "document.h"
+#include "message-stack.h"
+
+#include "jabber_whiteboard/undo-stack-observer.h"
+#include "jabber_whiteboard/session-manager.h"
+#include "jabber_whiteboard/message-node.h"
+#include "jabber_whiteboard/message-queue.h"
+#include "jabber_whiteboard/message-processors.h"
+#include "jabber_whiteboard/typedefs.h"
+
+namespace Inkscape {
+
+namespace Whiteboard {
+
+// Message processors are here!
+
+// TODO: Remove unnecessary status checks from processors --
+// we do all of that in MessageHandler::_hasValidReceiveContext
+
+// *********************************************************************
+// ChangeHandler begin
+// *********************************************************************
+
+/**
+ * MessageProcessor for document change and event commit messages.
+ */
+struct ChangeHandler : public MessageProcessor {
+public:
+ ~ChangeHandler()
+ {
+
+ }
+
+ ChangeHandler(SessionManager* sm) : MessageProcessor(sm)
+ {
+
+ }
+
+ LmHandlerResult
+ operator()(MessageType mode, JabberMessage& p)
+ {
+ MessageNode* msgNode;
+ bool chatroom = this->_sm->session_data->status[IN_CHATROOM];
+
+ ReceiveMessageQueue* rmq = this->_sm->session_data->receive_queues[p.sender];
+
+ if (rmq != NULL) {
+ switch (mode) {
+ case CHANGE_REPEATABLE:
+ case CHANGE_NOT_REPEATABLE:
+ case DOCUMENT_BEGIN:
+ msgNode = new MessageNode(p.sequence, p.sender, "", p.body, mode, false, chatroom);
+ rmq->insert(msgNode);
+ Inkscape::GC::release(msgNode);
+ break;
+ case DOCUMENT_END:
+ this->_sm->session_data->recipients_committed_queue.push_back(p.sender);
+ msgNode = new MessageNode(p.sequence, p.sender, "", p.body, mode, false, chatroom);
+ rmq->insert(msgNode);
+ Inkscape::GC::release(msgNode);
+ break;
+ case CHANGE_COMMIT:
+ this->_sm->session_data->recipients_committed_queue.push_back(p.sender);
+ msgNode = new MessageNode(p.sequence, p.sender, "", p.body, CHANGE_COMMIT, false, chatroom);
+ rmq->insert(msgNode);
+ Inkscape::GC::release(msgNode);
+ break;
+ case DUMMY_CHANGE:
+ default:
+ break;
+ }
+ } else {
+ g_warning("Received message from unknown sender %s", p.sender.c_str());
+ }
+
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+ }
+};
+// *********************************************************************
+// ChangeHandler end
+// *********************************************************************
+
+
+// *********************************************************************
+// ConnectRequestHandler begin
+// *********************************************************************
+/**
+ * MessageProcessor for connection request messages.
+ */
+struct ConnectRequestHandler : public MessageProcessor {
+public:
+ ~ConnectRequestHandler()
+ {
+
+ }
+
+ ConnectRequestHandler(SessionManager* sm) : MessageProcessor(sm)
+ {
+
+ }
+
+ LmHandlerResult
+ operator()(MessageType mode, JabberMessage& m)
+ {
+ std::bitset< NUM_FLAGS >& status = this->_sm->session_data->status;
+ switch(mode) {
+ case CONNECT_REQUEST_USER:
+ this->_sm->receiveConnectRequest(m.sender.c_str());
+ break;
+ case CONNECT_REQUEST_RESPONSE_USER:
+ if (m.sequence == 0) {
+ this->_sm->receiveConnectRequestResponse(DECLINE_INVITATION, m.sender);
+ } else { // FIXME: this has got to be buggy...
+ this->_sm->setRecipient(m.sender.c_str());
+ this->_sm->receiveConnectRequestResponse(ACCEPT_INVITATION, m.sender);
+ }
+ break;
+ case Inkscape::Whiteboard::CONNECTED_SIGNAL:
+ if (!status[IN_CHATROOM] && !status[CONNECTING_TO_CHAT] && !status[SYNCHRONIZING_WITH_CHAT] && !status[WAITING_TO_SYNC_TO_CHAT]) {
+ this->_sm->userConnectedToWhiteboard(m.sender.c_str());
+ this->_sm->setRecipient(m.sender.c_str());
+ } else {
+ SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::INFORMATION_MESSAGE, _("<b>%s</b> has joined the chatroom."), m.sender.c_str());
+ }
+ break;
+ default:
+ break;
+ }
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+ }
+};
+// *********************************************************************
+// ConnectRequestHandler end
+// *********************************************************************
+
+
+
+
+// *********************************************************************
+// ConnectErrorHandler begin
+// *********************************************************************
+/**
+ * MessageProcessor for connection error messages.
+ */
+struct ConnectErrorHandler : public MessageProcessor {
+public:
+ ~ConnectErrorHandler()
+ {
+
+ }
+
+ ConnectErrorHandler(SessionManager* sm) : MessageProcessor(sm)
+ {
+
+ }
+
+ LmHandlerResult
+ operator()(MessageType mode, JabberMessage& m)
+ {
+ switch(mode) {
+ case CONNECT_REQUEST_REFUSED_BY_PEER:
+ if (this->_sm->session_data->status[WAITING_FOR_INVITE_RESPONSE]) {
+ this->_sm->receiveConnectRequestResponse(DECLINE_INVITATION, m.sender);
+ }
+ break;
+ case Inkscape::Whiteboard::ALREADY_IN_SESSION:
+ if (this->_sm->session_data->status[WAITING_FOR_INVITE_RESPONSE]) {
+ this->_sm->receiveConnectRequestResponse(PEER_ALREADY_IN_SESSION, m.sender);
+ }
+ break;
+ case Inkscape::Whiteboard::DISCONNECTED_FROM_USER_SIGNAL:
+ if (!this->_sm->session_data->status[IN_CHATROOM]) {
+ this->_sm->closeSession();
+ this->_sm->userDisconnectedFromWhiteboard(m.sender.c_str());
+ }
+ break;
+ default:
+ break;
+ }
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+ }
+};
+// *********************************************************************
+// ConnectErrorHandler end
+// *********************************************************************
+
+
+
+
+// *********************************************************************
+// ChatSynchronizeHandler begin
+// *********************************************************************
+/**
+ * MessageProcessor for messages specific to chatroom synchronization.
+ */
+struct ChatSynchronizeHandler : public MessageProcessor {
+public:
+ ~ChatSynchronizeHandler()
+ {
+
+ }
+
+ ChatSynchronizeHandler(SessionManager* sm) : MessageProcessor(sm)
+ {
+
+ }
+
+ LmHandlerResult
+ operator()(MessageType mode, JabberMessage& m)
+ {
+ switch(mode) {
+ case CONNECT_REQUEST_RESPONSE_CHAT:
+ this->_sm->receiveConnectRequestResponseChat(m.sender.c_str());
+ break;
+ case CHATROOM_SYNCHRONIZE_REQUEST:
+ if (this->_sm->session_data->status[IN_CHATROOM] && this->_sm->session_data->status[IN_WHITEBOARD]) {
+ // Send response. Everyone in the chatroom will do this,
+ // but the client will accept only one response.
+ // The response is sent privately to the client
+ // <http://www.jabber.org/jeps/jep-0045.html#privatemessage>
+ this->_sm->sendMessage(CHATROOM_SYNCHRONIZE_RESPONSE, this->_sm->session_data->sequence_number, "", m.sender.c_str(), false);
+ }
+ break;
+ case CHATROOM_SYNCHRONIZE_RESPONSE:
+ if (m.sequence != 0) {
+ // Set sequence number
+ this->_sm->session_data->sequence_number = m.sequence;
+
+ // Set status flags
+ this->_sm->session_data->status.set(WAITING_TO_SYNC_TO_CHAT, 0);
+ this->_sm->session_data->status.set(SYNCHRONIZING_WITH_CHAT, 1);
+
+ // Send document synchronization request
+ this->_sm->clearDocument();
+ this->_sm->setupInkscapeInterface();
+ this->_sm->sendMessage(CONNECT_REQUEST_RESPONSE_CHAT, m.sequence, "", m.sender.c_str(), false);
+ } else {
+ this->_sm->sendMessage(CHATROOM_SYNCHRONIZE_REQUEST, 0, "", this->_sm->session_data->recipient, true);
+ }
+ break;
+ default:
+ break;
+ }
+ return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+ }
+};
+// *********************************************************************
+// ChatSynchronizeHandler end
+// *********************************************************************
+
+
+
+
+// *********************************************************************
+// Initializer
+// *********************************************************************
+void
+initialize_received_message_processors(SessionManager* sm, MessageProcessorMap& mpm)
+{
+ MessageProcessor* ch = new ChangeHandler(sm);
+ MessageProcessor* crh = new ConnectRequestHandler(sm);
+ MessageProcessor* ceh = new ConnectErrorHandler(sm);
+ MessageProcessor* csh = new ChatSynchronizeHandler(sm);
+
+ mpm[CHANGE_REPEATABLE] = ch;
+ mpm[CHANGE_NOT_REPEATABLE] = ch;
+ mpm[DUMMY_CHANGE] = ch;
+ mpm[CHANGE_COMMIT] = ch;
+ mpm[DOCUMENT_BEGIN] = ch;
+ mpm[DOCUMENT_END] = ch;
+
+ mpm[CONNECT_REQUEST_USER] = crh;
+ mpm[CONNECT_REQUEST_RESPONSE_USER] = crh;
+ mpm[CONNECTED_SIGNAL] = crh;
+
+ mpm[CONNECT_REQUEST_REFUSED_BY_PEER] = ceh;
+ mpm[ALREADY_IN_SESSION] = ceh;
+ mpm[DISCONNECTED_FROM_USER_SIGNAL] = ceh;
+
+ mpm[CONNECT_REQUEST_RESPONSE_CHAT] = csh;
+ mpm[CHATROOM_SYNCHRONIZE_REQUEST] = csh;
+ mpm[CHATROOM_SYNCHRONIZE_RESPONSE] = csh;
+}
+
+/*
+ * This function is provided solely for convenience and style. You can, of course,
+ * delete every MessageProcessor in the map with your own loop.
+ */
+void
+destroy_received_message_processors(MessageProcessorMap& mpm)
+{
+ mpm.clear();
+}
+
+}
+
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :