summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordknn <yoann.blein@free.fr>2012-08-10 18:04:56 (GMT)
committerdknn <yoann.blein@free.fr>2012-09-22 09:32:38 (GMT)
commit955c4589ca254814ae7ec6ed911e0a62febc5da1 (patch)
tree1d3ba8ecc732f8239462f7428e758224f3d38b94
parent577fffec4a1da6909740a392cf76617bdcbe5570 (diff)
downloadswift-contrib-955c4589ca254814ae7ec6ed911e0a62febc5da1.zip
swift-contrib-955c4589ca254814ae7ec6ed911e0a62febc5da1.tar.bz2
Capture and send user UI events
-rw-r--r--Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp86
-rw-r--r--Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h8
-rw-r--r--Swiften/Base/FloatCompare.h28
-rw-r--r--Swiften/Elements/InputEventPayload.cpp36
-rw-r--r--Swiften/Elements/InputEventPayload.h62
-rw-r--r--Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp2
-rw-r--r--Swiften/Parser/PayloadParsers/InputEventParser.cpp81
-rw-r--r--Swiften/Parser/PayloadParsers/InputEventParser.h26
-rw-r--r--Swiften/Parser/PayloadParsers/JingleParserFactory.h2
-rw-r--r--Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.cpp8
-rw-r--r--Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.h45
-rw-r--r--Swiften/Parser/SConscript1
-rw-r--r--Swiften/SConscript2
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharing.cpp62
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharing.h19
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharingManager.cpp7
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharingManager.h6
-rw-r--r--Swiften/ScreenSharing/InputEventResponder.cpp30
-rw-r--r--Swiften/ScreenSharing/InputEventResponder.h29
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharing.cpp9
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharing.h7
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp6
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharingManager.h2
-rw-r--r--Swiften/ScreenSharing/SConscript1
-rw-r--r--Swiften/ScreenSharing/ScreenSharingManager.h4
-rw-r--r--Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp28
-rw-r--r--Swiften/ScreenSharing/ScreenSharingManagerImpl.h11
-rw-r--r--Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp2
-rw-r--r--Swiften/Serializer/PayloadSerializers/InputEventSerializer.cpp85
-rw-r--r--Swiften/Serializer/PayloadSerializers/InputEventSerializer.h23
-rw-r--r--Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.cpp5
-rw-r--r--Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.h12
32 files changed, 659 insertions, 76 deletions
diff --git a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp
index 899f335..91a515f 100644
--- a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp
+++ b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp
@@ -20,6 +20,8 @@ namespace Swift {
RemoteScreenViewerWidget::RemoteScreenViewerWidget(boost::shared_ptr<IncomingScreenSharing> incScreenSharing, QWidget *parent) :
QWidget(parent), iss(incScreenSharing)
{
+ setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
iss->onNewImageReceived.connect(boost::bind(&RemoteScreenViewerWidget::handleNewImageReceived, this, _1));
}
@@ -28,7 +30,7 @@ RemoteScreenViewerWidget::~RemoteScreenViewerWidget()
iss->onNewImageReceived.disconnect(boost::bind(&RemoteScreenViewerWidget::handleNewImageReceived, this, _1));
}
-void RemoteScreenViewerWidget::paintEvent(QPaintEvent* event)
+void RemoteScreenViewerWidget::paintEvent(QPaintEvent*)
{
if (!pixmap.isNull()) {
QPainter painter(this);
@@ -37,18 +39,94 @@ void RemoteScreenViewerWidget::paintEvent(QPaintEvent* event)
}
}
-void RemoteScreenViewerWidget::resizeEvent(QResizeEvent *event)
+void RemoteScreenViewerWidget::resizeEvent(QResizeEvent* event)
{
if (!pixmap.isNull()) {
- pixmap = pixmap.scaled(event->size(), Qt::KeepAspectRatio);
+ pixmap = pixmap.scaled(event->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
QWidget::resizeEvent(event);
}
+void RemoteScreenViewerWidget::keyPressEvent(QKeyEvent* event)
+{
+ InputEventPayload::Event ev(InputEventPayload::Event::KeyPress, event->key());
+ iss->sendInputEvent(ev);
+ QWidget::keyPressEvent(event);
+}
+
+void RemoteScreenViewerWidget::keyReleaseEvent(QKeyEvent* event)
+{
+ InputEventPayload::Event ev(InputEventPayload::Event::KeyRelease, event->key());
+ iss->sendInputEvent(ev);
+ QWidget::keyReleaseEvent(event);
+}
+
+void RemoteScreenViewerWidget::mouseMoveEvent(QMouseEvent* event)
+{
+ float x = static_cast<float>(event->x()) / pixmap.width();
+ float y = static_cast<float>(event->y()) / pixmap.height();
+ InputEventPayload::Event ev(InputEventPayload::Event::MouseMove, x, y);
+ iss->sendInputEvent(ev);
+ QWidget::mouseMoveEvent(event);
+}
+
+void RemoteScreenViewerWidget::mousePressEvent(QMouseEvent* event)
+{
+ int btnId = 0;
+ switch (event->button()) {
+ case Qt::LeftButton:
+ btnId = 3;
+ break;
+ case Qt::MidButton:
+ btnId = 2;
+ break;
+ case Qt::RightButton:
+ btnId = 1;
+ break;
+ default:
+ break;
+ }
+ if (btnId) {
+ InputEventPayload::Event ev(InputEventPayload::Event::MousePress, btnId);
+ iss->sendInputEvent(ev);
+ }
+ QWidget::mousePressEvent(event);
+}
+
+void RemoteScreenViewerWidget::mouseReleaseEvent(QMouseEvent* event)
+{
+ int btnId = 0;
+ switch (event->button()) {
+ case Qt::LeftButton:
+ btnId = 3;
+ break;
+ case Qt::MidButton:
+ btnId = 2;
+ break;
+ case Qt::RightButton:
+ btnId = 1;
+ break;
+ default:
+ break;
+ }
+ if (btnId) {
+ InputEventPayload::Event ev(InputEventPayload::Event::MouseRelease, btnId);
+ iss->sendInputEvent(ev);
+ }
+ QWidget::mouseReleaseEvent(event);
+}
+
+void RemoteScreenViewerWidget::wheelEvent(QWheelEvent* event)
+{
+ InputEventPayload::Event ev(InputEventPayload::Event::MouseWheel, event->delta());
+ iss->sendInputEvent(ev);
+ QWidget::wheelEvent(event);
+}
+
void RemoteScreenViewerWidget::handleNewImageReceived(const Image& image)
{
QImage qImg(image.data.data(), image.width, image.height, QImage::Format_RGB888);
- pixmap = QPixmap::fromImage(qImg).scaled(size(), Qt::KeepAspectRatio);
+ pixmap = QPixmap::fromImage(qImg).scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
update();
}
diff --git a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h
index b0a377e..2738e98 100644
--- a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h
+++ b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h
@@ -21,8 +21,14 @@ namespace Swift {
~RemoteScreenViewerWidget();
protected:
- void paintEvent(QPaintEvent* event);
+ void paintEvent(QPaintEvent*);
void resizeEvent(QResizeEvent* event);
+ void keyPressEvent(QKeyEvent* event);
+ void keyReleaseEvent(QKeyEvent* event);
+ void mouseMoveEvent(QMouseEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
+ void wheelEvent(QWheelEvent* event);
private:
void handleNewImageReceived(const Image& image);
diff --git a/Swiften/Base/FloatCompare.h b/Swiften/Base/FloatCompare.h
new file mode 100644
index 0000000..152ffff
--- /dev/null
+++ b/Swiften/Base/FloatCompare.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <cmath>
+#include <limits>
+
+namespace Swift {
+ bool approximatelyEqual(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
+ return std::fabs(a - b) <= ( (std::fabs(a) < std::fabs(b) ? std::fabs(b) : std::fabs(a)) * epsilon);
+ }
+
+ bool essentiallyEqual(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
+ return std::fabs(a - b) <= ( (std::fabs(a) > std::fabs(b) ? std::fabs(b) : std::fabs(a)) * epsilon);
+ }
+
+ bool definitelyGreaterThan(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
+ return (a - b) > ( (std::fabs(a) < std::fabs(b) ? std::fabs(b) : std::fabs(a)) * epsilon);
+ }
+
+ bool definitelyLessThan(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
+ return (b - a) > ( (std::fabs(a) < std::fabs(b) ? std::fabs(b) : std::fabs(a)) * epsilon);
+ }
+}
diff --git a/Swiften/Elements/InputEventPayload.cpp b/Swiften/Elements/InputEventPayload.cpp
new file mode 100644
index 0000000..411d2cd
--- /dev/null
+++ b/Swiften/Elements/InputEventPayload.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Elements/InputEventPayload.h>
+
+namespace Swift {
+
+InputEventPayload::InputEventPayload()
+ : action_(InputEventPayload::Notify)
+{
+}
+
+void InputEventPayload::addEvent(const InputEventPayload::Event& event)
+{
+ events_.push_back(event);
+}
+
+const std::vector<InputEventPayload::Event>& InputEventPayload::getEvents() const
+{
+ return events_;
+}
+
+void InputEventPayload::setAction(InputEventPayload::Action action)
+{
+ action_ = action;
+}
+
+InputEventPayload::Action InputEventPayload::getAction() const
+{
+ return action_;
+}
+
+}
diff --git a/Swiften/Elements/InputEventPayload.h b/Swiften/Elements/InputEventPayload.h
new file mode 100644
index 0000000..1ccdec8
--- /dev/null
+++ b/Swiften/Elements/InputEventPayload.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Payload.h>
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace Swift {
+ class InputEventPayload : public Payload {
+ public:
+ typedef boost::shared_ptr<InputEventPayload> ref;
+
+ enum Action {
+ Notify,
+ Unknown,
+ };
+
+ struct Event {
+ enum EventType {
+ MouseMove,
+ MouseWheel,
+ MousePress,
+ MouseRelease,
+ KeyType,
+ KeyPress,
+ KeyRelease,
+ Unknown,
+ };
+
+ Event(EventType eventType = Unknown)
+ : type(eventType), integerArg(0), realArg1(0), realArg2(0) {}
+ Event(EventType eventType, int integerArg)
+ : type(eventType), integerArg(integerArg), realArg1(0), realArg2(0) {}
+ Event(EventType eventType, float realArg1, float realArg2)
+ : type(eventType), integerArg(0), realArg1(realArg1), realArg2(realArg2) {}
+
+ EventType type;
+ int integerArg;
+ float realArg1;
+ float realArg2;
+ };
+
+ public:
+ InputEventPayload();
+
+ void addEvent(const Event& event);
+ const std::vector<Event>& getEvents() const;
+
+ void setAction(Action action);
+ Action getAction() const;
+
+ private:
+ Action action_;
+ std::vector<Event> events_;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
index 167f5c1..ec05ef6 100644
--- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
+++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
@@ -70,6 +70,7 @@
#include <Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h>
#include <Swiften/Parser/PayloadParsers/JingleRTPDescriptionParserFactory.h>
#include <Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.h>
+#include <Swiften/Parser/PayloadParsers/InputEventParser.h>
using namespace boost;
@@ -134,6 +135,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
factories_.push_back(boost::make_shared<JingleRTPDescriptionParserFactory>(this));
factories_.push_back(boost::make_shared<GenericPayloadParserFactory<RTPPayloadTypeParser> >("payload-type"));
factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleRawUDPTransportPayloadParser> >("transport", "urn:xmpp:jingle:transports:raw-udp:1"));
+ factories_.push_back(boost::make_shared<GenericPayloadParserFactory<InputEventParser> >("inputevt", "http://sip-comunicator.org/protocol/inputevt"));
foreach(shared_ptr<PayloadParserFactory> factory, factories_) {
addFactory(factory.get());
diff --git a/Swiften/Parser/PayloadParsers/InputEventParser.cpp b/Swiften/Parser/PayloadParsers/InputEventParser.cpp
new file mode 100644
index 0000000..44d9849
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/InputEventParser.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Parser/PayloadParsers/InputEventParser.h>
+
+#include <boost/optional.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace Swift {
+
+void InputEventParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (level == 0) {
+ // <inputevt> tag
+ InputEventPayload::ref payload = getPayloadInternal();
+ payload->setAction(actionFromString(attributes.getAttributeValue("action").get_value_or("")));
+ } else if (level == 1) {
+ // <remote-control> tag
+ } else if (level == 2) {
+ InputEventPayload::Event event(eventTypeFromString(element));
+ switch (event.type) {
+ case InputEventPayload::Event::MouseMove:
+ try {
+ event.realArg1 = boost::lexical_cast<float>(attributes.getAttributeValue("x").get_value_or("0"));
+ event.realArg2 = boost::lexical_cast<float>(attributes.getAttributeValue("y").get_value_or("0"));
+ } catch (boost::bad_lexical_cast &) {}
+ break;
+ case InputEventPayload::Event::MouseWheel:
+ case InputEventPayload::Event::MousePress:
+ case InputEventPayload::Event::MouseRelease:
+ case InputEventPayload::Event::KeyType:
+ case InputEventPayload::Event::KeyPress:
+ case InputEventPayload::Event::KeyRelease:
+ try {
+ event.integerArg = boost::lexical_cast<int>(attributes.getEntries().front().getValue());
+ } catch (boost::bad_lexical_cast &) {}
+ default:
+ break;
+ }
+ }
+ ++level;
+}
+
+void InputEventParser::handleEndElement(const std::string&, const std::string&) {
+ --level;
+}
+
+void InputEventParser::handleCharacterData(const std::string&){
+
+}
+
+InputEventPayload::Action InputEventParser::actionFromString(const std::string& action)
+{
+ if (action == "notify")
+ return InputEventPayload::Notify;
+
+ return InputEventPayload::Unknown;
+}
+
+InputEventPayload::Event::EventType InputEventParser::eventTypeFromString(const std::string& eventType) {
+ if (eventType == "mouse-move")
+ return InputEventPayload::Event::MouseMove;
+ else if (eventType == "mouse-wheel")
+ return InputEventPayload::Event::MouseWheel;
+ else if (eventType == "mouse-press")
+ return InputEventPayload::Event::MousePress;
+ else if (eventType == "mouse-release")
+ return InputEventPayload::Event::MouseRelease;
+ else if (eventType == "key-type")
+ return InputEventPayload::Event::KeyType;
+ else if (eventType == "key-press")
+ return InputEventPayload::Event::KeyPress;
+ else if (eventType == "key-release")
+ return InputEventPayload::Event::KeyRelease;
+
+ return InputEventPayload::Event::Unknown;
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/InputEventParser.h b/Swiften/Parser/PayloadParsers/InputEventParser.h
new file mode 100644
index 0000000..a131254
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/InputEventParser.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/InputEventPayload.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+ class InputEventParser : public GenericPayloadParser<InputEventPayload> {
+ public:
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string&, const std::string&);
+ virtual void handleCharacterData(const std::string&);
+
+ private:
+ static InputEventPayload::Action actionFromString(const std::string& action);
+ static InputEventPayload::Event::EventType eventTypeFromString(const std::string& eventType);
+
+ private:
+ int level;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleParserFactory.h b/Swiften/Parser/PayloadParsers/JingleParserFactory.h
index fa25aeb..9feade7 100644
--- a/Swiften/Parser/PayloadParsers/JingleParserFactory.h
+++ b/Swiften/Parser/PayloadParsers/JingleParserFactory.h
@@ -31,5 +31,3 @@ namespace Swift {
};
}
-
-
diff --git a/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.cpp b/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.cpp
index 7429b39..68893c7 100644
--- a/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.cpp
+++ b/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.cpp
@@ -4,7 +4,7 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "JingleRTPDescriptionParser.h"
+#include <Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.h>
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
#include <Swiften/Parser/PayloadParserFactory.h>
@@ -23,7 +23,7 @@ void JingleRTPDescriptionParser::handleStartElement(const std::string& element,
const std::string& media = attributes.getAttributeValue("media").get_value_or("");
getPayloadInternal()->setMedia(mediaTypeFromString(media));
}
-
+
if (level == 1) {
if (element == "bandwidth") {
parsingBandwidth = true;
@@ -66,8 +66,8 @@ void JingleRTPDescriptionParser::handleCharacterData(const std::string& data) {
bandwidthValue += data;
}
}
-
-JingleRTPDescription::MediaType JingleRTPDescriptionParser::mediaTypeFromString(const std::string& media) const {
+
+JingleRTPDescription::MediaType JingleRTPDescriptionParser::mediaTypeFromString(const std::string& media) {
if (media == "audio") {
return JingleRTPDescription::Audio;
} else if (media == "video") {
diff --git a/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.h b/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.h
index d250754..6ffad45 100644
--- a/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.h
+++ b/Swiften/Parser/PayloadParsers/JingleRTPDescriptionParser.h
@@ -11,28 +11,25 @@
#include <Swiften/Parser/PayloadParser.h>
namespace Swift {
-
-class PayloadParserFactoryCollection;
-
-class JingleRTPDescriptionParser : public GenericPayloadParser<JingleRTPDescription> {
- public:
- JingleRTPDescriptionParser(PayloadParserFactoryCollection* factories);
-
- virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
- virtual void handleEndElement(const std::string& element, const std::string& ns);
- virtual void handleCharacterData(const std::string& data);
-
- private:
- JingleRTPDescription::MediaType mediaTypeFromString(const std::string& media) const;
-
- private:
- PayloadParserFactoryCollection* factories;
- int level;
- //CurrentParseElement currentElement;
- boost::shared_ptr<PayloadParser> currentPayloadParser;
- bool parsingBandwidth;
- std::string bandwidthType;
- std::string bandwidthValue;
-};
-
+ class PayloadParserFactoryCollection;
+
+ class JingleRTPDescriptionParser : public GenericPayloadParser<JingleRTPDescription> {
+ public:
+ JingleRTPDescriptionParser(PayloadParserFactoryCollection* factories);
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string& ns);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ static JingleRTPDescription::MediaType mediaTypeFromString(const std::string& media);
+
+ private:
+ PayloadParserFactoryCollection* factories;
+ int level;
+ boost::shared_ptr<PayloadParser> currentPayloadParser;
+ bool parsingBandwidth;
+ std::string bandwidthType;
+ std::string bandwidthValue;
+ };
}
diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript
index 43d50f0..c3b6980 100644
--- a/Swiften/Parser/SConscript
+++ b/Swiften/Parser/SConscript
@@ -76,6 +76,7 @@ sources = [
"PayloadParsers/RTPPayloadTypeParser.cpp",
"PayloadParsers/JingleRTPDescriptionParser.cpp",
"PayloadParsers/JingleRawUDPTransportPayloadParser.cpp",
+ "PayloadParsers/InputEventParser.cpp",
"PlatformXMLParserFactory.cpp",
"PresenceParser.cpp",
"SerializingParser.cpp",
diff --git a/Swiften/SConscript b/Swiften/SConscript
index b8ca1d9..d19334f 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -131,6 +131,7 @@ if env["SCONS_STAGE"] == "build" :
"Elements/StreamResumed.cpp",
"Elements/VCard.cpp",
"Elements/MUCOccupant.cpp",
+ "Elements/InputEventPayload.cpp",
"Entity/Entity.cpp",
"Entity/PayloadPersister.cpp",
"MUC/MUC.cpp",
@@ -207,6 +208,7 @@ if env["SCONS_STAGE"] == "build" :
"Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp",
"Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.cpp",
"Serializer/PayloadSerializers/JingleRawUDPTransportPayloadSerializer.cpp",
+ "Serializer/PayloadSerializers/InputEventSerializer.cpp",
"Serializer/PresenceSerializer.cpp",
"Serializer/StanzaSerializer.cpp",
"Serializer/StreamErrorSerializer.cpp",
diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.cpp b/Swiften/ScreenSharing/IncomingScreenSharing.cpp
index 15574c4..fbd4b16 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharing.cpp
+++ b/Swiften/ScreenSharing/IncomingScreenSharing.cpp
@@ -11,24 +11,33 @@
#include <Swiften/Elements/JingleRTPDescription.h>
#include <Swiften/Network/UDPSocketFactory.h>
#include <Swiften/Network/UDPSocket.h>
+#include <Swiften/Network/TimerFactory.h>
+#include <Swiften/Network/Timer.h>
#include <Swiften/ScreenSharing/RTPSessionImpl.h>
#include <Swiften/ScreenSharing/VP8Decoder.h>
#include <Swiften/ScreenSharing/VP8RTPParser.h>
+#include <Swiften/Queries/Request.h>
+#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Base/FloatCompare.h>
#include <boost/bind.hpp>
namespace Swift {
IncomingScreenSharing::IncomingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory,
- boost::shared_ptr<JingleContentPayload> content)
+ TimerFactory* timerFactory, IQRouter* iqRouter, boost::shared_ptr<JingleContentPayload> content)
: ScreenSharing(session, udpSocketFactory),
- initialContent(content), parser(0), decoder(0)
+ initialContent(content), parser(0), decoder(0), lastMouveMoveEvent(InputEventPayload::Event::MouseMove),
+ inputEventPayload(boost::make_shared<InputEventPayload>()), eventSendingTimer(timerFactory->createTimer(500)),
+ iqRouter(iqRouter)
{
onStateChange(ScreenSharing::WaitingForAccept);
+ eventSendingTimer->onTick.connect(boost::bind(&IncomingScreenSharing::handleEventSendingTimerTick, this));
}
IncomingScreenSharing::~IncomingScreenSharing()
{
+ eventSendingTimer->onTick.disconnect(boost::bind(&IncomingScreenSharing::handleEventSendingTimerTick, this));
delete rtpSession;
delete parser;
delete decoder;
@@ -73,7 +82,7 @@ void IncomingScreenSharing::accept()
decoder = new VP8Decoder;
parser = new VP8RTPParser(decoder);
rtpSession->onIncomingPacket.connect(boost::bind(&VP8RTPParser::newPayloadReceived, parser, _1, _2, _3));
- decoder->onNewImageDecoded.connect(boost::bind(&IncomingScreenSharing::hangleNewImageDecoded, this, _1));
+ decoder->onNewImageDecoded.connect(boost::bind(&IncomingScreenSharing::handleNewImageDecoded, this, _1));
}
onStateChange(ScreenSharing::Connecting);
@@ -84,15 +93,60 @@ const JID &IncomingScreenSharing::getSender() const
return jingleSession->getInitiator();
}
+void IncomingScreenSharing::sendInputEvent(const InputEventPayload::Event& event)
+{
+ if (event.type == InputEventPayload::Event::Unknown)
+ return;
+
+ if (inputEventPayload->getEvents().empty()) {
+ eventSendingTimer->start();
+ }
+ if (event.type == InputEventPayload::Event::MouseMove) {
+ lastMouveMoveEvent.realArg1 = event.realArg1;
+ lastMouveMoveEvent.realArg2 = event.realArg2;
+ } else {
+ addLastMouseMoveIfDifferent();
+ inputEventPayload->addEvent(event);
+ }
+}
+
JingleContentID IncomingScreenSharing::getContentID() const
{
return JingleContentID(initialContent->getName(), initialContent->getCreator());
}
-void IncomingScreenSharing::hangleNewImageDecoded(const Image& image)
+void IncomingScreenSharing::handleNewImageDecoded(const Image& image)
{
onStateChange(ScreenSharing::Receiving);
onNewImageReceived(image);
}
+void IncomingScreenSharing::handleEventSendingTimerTick()
+{
+ addLastMouseMoveIfDifferent();
+ boost::shared_ptr< GenericRequest<InputEventPayload> > request
+ = boost::make_shared< GenericRequest<InputEventPayload> >(IQ::Set, getSender(), inputEventPayload, iqRouter);
+ request->send();
+ // Prepare for a new payload
+ inputEventPayload.reset(new InputEventPayload);
+}
+
+void IncomingScreenSharing::addLastMouseMoveIfDifferent()
+{
+ const std::vector<InputEventPayload::Event>& events = inputEventPayload->getEvents();
+ std::vector<InputEventPayload::Event>::const_reverse_iterator last;
+ std::vector<InputEventPayload::Event>::const_reverse_iterator it;
+ for (it = events.rbegin(); it != events.rend(); ++it) {
+ if (it->type == InputEventPayload::Event::MouseMove) {
+ last = it;
+ break;
+ }
+ }
+ if (it == events.rend()
+ || !approximatelyEqual(it->realArg1, lastMouveMoveEvent.realArg1)
+ || !approximatelyEqual(it->realArg2, lastMouveMoveEvent.realArg2)) {
+ inputEventPayload->addEvent(lastMouveMoveEvent);
+ }
+}
+
}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.h b/Swiften/ScreenSharing/IncomingScreenSharing.h
index cc25a9f..c46a6f8 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharing.h
+++ b/Swiften/ScreenSharing/IncomingScreenSharing.h
@@ -11,11 +11,17 @@
#include <Swiften/Elements/RTPPayloadType.h>
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Elements/InputEventPayload.h>
+
+
namespace Swift {
class JingleContentPayload;
class VP8RTPParser;
class VideoDecoder;
class Image;
+ class TimerFactory;
+ class Timer;
+ class IQRouter;
class IncomingScreenSharing : public ScreenSharing {
public:
@@ -23,26 +29,33 @@ namespace Swift {
public:
IncomingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory,
- boost::shared_ptr<JingleContentPayload> content);
+ TimerFactory* timerFactory, IQRouter* iqRouter, boost::shared_ptr<JingleContentPayload> content);
virtual ~IncomingScreenSharing();
virtual void cancel();
-
void accept();
const JID& getSender() const;
+ void sendInputEvent(const InputEventPayload::Event& event);
+
public:
boost::signal<void (const Image&)> onNewImageReceived;
private:
JingleContentID getContentID() const;
- void hangleNewImageDecoded(const Image& image);
+ void handleNewImageDecoded(const Image& image);
+ void handleEventSendingTimerTick();
+ void addLastMouseMoveIfDifferent();
private:
boost::shared_ptr<JingleContentPayload> initialContent;
RTPPayloadType payloadTypeUsed;
VP8RTPParser* parser;
VideoDecoder* decoder;
+ InputEventPayload::Event lastMouveMoveEvent;
+ InputEventPayload::ref inputEventPayload;
+ boost::shared_ptr<Timer> eventSendingTimer;
+ IQRouter* iqRouter;
};
}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp b/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
index 321ab4c..8557f40 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
+++ b/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
@@ -15,8 +15,9 @@
namespace Swift {
-IncomingScreenSharingManager::IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router, UDPSocketFactory* udpSocketFactory)
- : jingleSessionManager(jingleSessionManager), router(router), udpSocketFactory(udpSocketFactory)
+IncomingScreenSharingManager::IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* iqRouter,
+ UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory)
+ : jingleSessionManager(jingleSessionManager), iqRouter(iqRouter), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)
{
jingleSessionManager->addIncomingSessionHandler(this);
}
@@ -36,7 +37,7 @@ bool IncomingScreenSharingManager::handleIncomingJingleSession(Swift::JingleSess
// Check description
// Create IncomingScreenSharing
- onIncomingScreenSharing(boost::make_shared<IncomingScreenSharing>(session, udpSocketFactory, content));
+ onIncomingScreenSharing(boost::make_shared<IncomingScreenSharing>(session, udpSocketFactory, timerFactory, iqRouter, content));
return true;
}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharingManager.h b/Swiften/ScreenSharing/IncomingScreenSharingManager.h
index 3563a87..586cb0b 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharingManager.h
+++ b/Swiften/ScreenSharing/IncomingScreenSharingManager.h
@@ -13,10 +13,11 @@ namespace Swift {
class IQRouter;
class JingleSessionManager;
class UDPSocketFactory;
+ class TimerFactory;
class IncomingScreenSharingManager : public IncomingJingleSessionHandler {
public:
- IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router, UDPSocketFactory* udpSocketFactory);
+ IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* iqRouter, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
virtual ~IncomingScreenSharingManager();
public:
@@ -27,7 +28,8 @@ namespace Swift {
private:
JingleSessionManager* jingleSessionManager;
- IQRouter* router;
+ IQRouter* iqRouter;
UDPSocketFactory *udpSocketFactory;
+ TimerFactory* timerFactory;
};
}
diff --git a/Swiften/ScreenSharing/InputEventResponder.cpp b/Swiften/ScreenSharing/InputEventResponder.cpp
new file mode 100644
index 0000000..ce9a541
--- /dev/null
+++ b/Swiften/ScreenSharing/InputEventResponder.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/InputEventResponder.h>
+#include <Swiften/ScreenSharing/ScreenSharingManager.h>
+
+namespace Swift {
+
+InputEventResponder::InputEventResponder(ScreenSharingManager* ssManager, IQRouter* router)
+ : SetResponder<InputEventPayload>(router), ssManager(ssManager)
+{
+}
+
+InputEventResponder::~InputEventResponder()
+{
+}
+
+bool InputEventResponder::handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<InputEventPayload> payload)
+{
+ if (payload->getAction() == InputEventPayload::Notify) {
+ sendResponse(from, id, boost::shared_ptr<InputEventPayload>());
+ ssManager->handleInputEvent(from, payload);
+ }
+ return true;
+}
+
+}
diff --git a/Swiften/ScreenSharing/InputEventResponder.h b/Swiften/ScreenSharing/InputEventResponder.h
new file mode 100644
index 0000000..6d1acd3
--- /dev/null
+++ b/Swiften/ScreenSharing/InputEventResponder.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Queries/SetResponder.h>
+#include <Swiften/Elements/InputEventPayload.h>
+
+namespace Swift {
+ class IQRouter;
+ class JingleSessionManager;
+ class ScreenSharingManager;
+
+ class InputEventResponder : public SetResponder<InputEventPayload> {
+ public:
+ InputEventResponder(ScreenSharingManager* ssManager, IQRouter* router);
+ virtual ~InputEventResponder();
+
+ private:
+ virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<InputEventPayload> payload);
+
+ private:
+ ScreenSharingManager* ssManager;
+ IQRouter* router;
+ };
+}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
index 7cea50e..363b23c 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
+++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
@@ -23,9 +23,9 @@
namespace Swift {
-OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory)
+OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, const JID &toJID)
: ScreenSharing(session, udpSocketFactory),
- timerFactory(timerFactory), contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)),
+ timerFactory(timerFactory), recipient(toJID), contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)),
canceled(false), sessionAccepted(false), socketConnected(false), encoder(0), packetizer(0)
{
jingleSession->onSessionAcceptReceived.connect(boost::bind(&OutgoingScreenSharing::handleSessionAcceptReceived, this, _1, _2, _3));
@@ -76,6 +76,11 @@ void OutgoingScreenSharing::addImage(const Image &image)
encoder->encodeImage(image);
}
+const JID& OutgoingScreenSharing::getRecipient() const
+{
+ return recipient;
+}
+
void OutgoingScreenSharing::handleSocketConnected()
{
if (canceled)
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.h b/Swiften/ScreenSharing/OutgoingScreenSharing.h
index cacc715..245d038 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharing.h
+++ b/Swiften/ScreenSharing/OutgoingScreenSharing.h
@@ -22,13 +22,14 @@ namespace Swift {
class VideoEncoder;
class VP8RTPPacketizer;
class Image;
+ class InputEventPayload;
class OutgoingScreenSharing : public ScreenSharing {
public:
typedef boost::shared_ptr<OutgoingScreenSharing> ref;
public:
- OutgoingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
+ OutgoingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, const JID& recipient);
virtual ~OutgoingScreenSharing();
virtual void cancel();
@@ -36,8 +37,11 @@ namespace Swift {
void start(unsigned int width, unsigned int height);
void addImage(const Image& image);
+ const JID& getRecipient() const;
+
public:
boost::signal<void ()> onReady;
+ boost::signal<void (boost::shared_ptr<InputEventPayload>)> onNewInputEvent;
private:
void handleSocketConnected();
@@ -48,6 +52,7 @@ namespace Swift {
private:
TimerFactory* timerFactory;
+ JID recipient;
JingleContentID contentID;
bool canceled;
bool sessionAccepted;
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp b/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
index aaa2198..872fd19 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
+++ b/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
@@ -19,13 +19,13 @@ OutgoingScreenSharingManager::OutgoingScreenSharingManager(JingleSessionManager*
{
}
-boost::shared_ptr<OutgoingScreenSharing> OutgoingScreenSharingManager::createOutgoingScreenSharing(const JID& from, const JID& to)
+boost::shared_ptr<OutgoingScreenSharing> OutgoingScreenSharingManager::createOutgoingScreenSharing(const JID& from, const JID& recipient)
{
- JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, to, idGenerator.generateID(), iqRouter);
+ JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, recipient, idGenerator.generateID(), iqRouter);
assert(jingleSession);
jsManager->registerOutgoingSession(from, jingleSession);
- return boost::make_shared<OutgoingScreenSharing>(jingleSession, udpSocketFactory, timerFactory);
+ return boost::make_shared<OutgoingScreenSharing>(jingleSession, udpSocketFactory, timerFactory, recipient);
}
}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharingManager.h b/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
index de21d5a..56888ba 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
+++ b/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
@@ -22,7 +22,7 @@ namespace Swift {
OutgoingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router,
UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
- boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& from, const JID& to);
+ boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& from, const JID& recipient);
private:
IDGenerator idGenerator;
diff --git a/Swiften/ScreenSharing/SConscript b/Swiften/ScreenSharing/SConscript
index 1eeb443..aefe45b 100644
--- a/Swiften/ScreenSharing/SConscript
+++ b/Swiften/ScreenSharing/SConscript
@@ -9,6 +9,7 @@ sources = [
"IncomingScreenSharingManager.cpp",
"ScreenSharingManagerImpl.cpp",
"VP8RTPParser.cpp",
+ "InputEventResponder.cpp",
]
objects = swiften_env.SwiftenObject(sources)
diff --git a/Swiften/ScreenSharing/ScreenSharingManager.h b/Swiften/ScreenSharing/ScreenSharingManager.h
index a527402..6a97146 100644
--- a/Swiften/ScreenSharing/ScreenSharingManager.h
+++ b/Swiften/ScreenSharing/ScreenSharingManager.h
@@ -14,6 +14,7 @@ namespace Swift {
class IncomingScreenSharing;
class OutgoingScreenSharing;
class JID;
+ class InputEventPayload;
class ScreenSharingManager {
public:
@@ -21,6 +22,9 @@ namespace Swift {
virtual boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& to) = 0;
+ virtual void handleInputEvent(const JID& from, boost::shared_ptr<InputEventPayload> payload) = 0;
+
+ public:
boost::signal<void (boost::shared_ptr<IncomingScreenSharing>)> onIncomingScreenSharing;
};
}
diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
index b0e337a..c20d2c7 100644
--- a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
+++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
@@ -12,22 +12,33 @@
#include <Swiften/Presence/PresenceOracle.h>
#include <Swiften/ScreenSharing/IncomingScreenSharingManager.h>
#include <Swiften/ScreenSharing/OutgoingScreenSharingManager.h>
+#include <Swiften/ScreenSharing/OutgoingScreenSharing.h>
+#include <Swiften/ScreenSharing/InputEventResponder.h>
+
+#include <boost/foreach.hpp>
namespace Swift {
ScreenSharingManagerImpl::ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager *jingleSessionManager, IQRouter *iqRouter,
UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, PresenceOracle* presenceOrable,
EntityCapsProvider* capsProvider)
- : ownJID(ownFullJID)/*, jingleSM(jingleSessionManager), iqRouter(iqRouter), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)*/, capsProvider(capsProvider), presenceOracle(presenceOrable)
+ : ownJID(ownFullJID), capsProvider(capsProvider), presenceOracle(presenceOrable)
{
- incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory);
+ incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);
outgoingSSManager = new OutgoingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);
+ responder = new InputEventResponder(this, iqRouter);
+ responder->start();
+
incomingSSManager->onIncomingScreenSharing.connect(onIncomingScreenSharing);
}
ScreenSharingManagerImpl::~ScreenSharingManagerImpl()
{
+ responder->stop();
+ delete responder;
+ delete incomingSSManager;
+ delete outgoingSSManager;
}
boost::shared_ptr<OutgoingScreenSharing> ScreenSharingManagerImpl::createOutgoingScreenSharing(const JID &to)
@@ -43,7 +54,18 @@ boost::shared_ptr<OutgoingScreenSharing> ScreenSharingManagerImpl::createOutgoin
}
}
- return outgoingSSManager->createOutgoingScreenSharing(ownJID, recipient);
+ OutgoingScreenSharing::ref oss = outgoingSSManager->createOutgoingScreenSharing(ownJID, recipient);
+ outgoingSharings.push_back(oss);
+ return oss;
+}
+
+void ScreenSharingManagerImpl::handleInputEvent(const JID& from, boost::shared_ptr<InputEventPayload> payload)
+{
+ foreach (OutgoingScreenSharing::ref oss, outgoingSharings) {
+ if (oss->getRecipient() == from) {
+ oss->onNewInputEvent(payload);
+ }
+ }
}
boost::optional<JID> ScreenSharingManagerImpl::highestPriorityJIDSupportingScreenSharing(const JID& bareJID) {
diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
index 8e8ea78..8f73f87 100644
--- a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
+++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
@@ -18,6 +18,8 @@ namespace Swift {
class TimerFactory;
class PresenceOracle;
class EntityCapsProvider;
+ class InputEventResponder;
+ class InputEventPayload;
class ScreenSharingManagerImpl : public ScreenSharingManager {
public:
@@ -28,19 +30,18 @@ namespace Swift {
virtual boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& to);
+ virtual void handleInputEvent(const JID& from, boost::shared_ptr<InputEventPayload> payload);
+
private:
boost::optional<JID> highestPriorityJIDSupportingScreenSharing(const JID &bareJID);
private:
IncomingScreenSharingManager* incomingSSManager;
OutgoingScreenSharingManager* outgoingSSManager;
-
+ InputEventResponder* responder;
JID ownJID;
+ std::vector< boost::shared_ptr<OutgoingScreenSharing> > outgoingSharings;
-// JingleSessionManager* jingleSM;
-// IQRouter* iqRouter;
-// BoostUDPSocketFactory* udpSocketFactory;
-// TimerFactory* timerFactory;
EntityCapsProvider* capsProvider;
PresenceOracle* presenceOracle;
};
diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
index 3a423d1..081284b 100644
--- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
+++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
@@ -64,6 +64,7 @@
#include <Swiften/Serializer/PayloadSerializers/DeliveryReceiptSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/DeliveryReceiptRequestSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.h>
+#include <Swiften/Serializer/PayloadSerializers/InputEventSerializer.h>
namespace Swift {
@@ -124,6 +125,7 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() {
serializers_.push_back(new DeliveryReceiptSerializer());
serializers_.push_back(new DeliveryReceiptRequestSerializer());
serializers_.push_back(new JingleRTPDescriptionSerializer());
+ serializers_.push_back(new InputEventSerializer());
foreach(PayloadSerializer* serializer, serializers_) {
addSerializer(serializer);
diff --git a/Swiften/Serializer/PayloadSerializers/InputEventSerializer.cpp b/Swiften/Serializer/PayloadSerializers/InputEventSerializer.cpp
new file mode 100644
index 0000000..5692308
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/InputEventSerializer.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Serializer/PayloadSerializers/InputEventSerializer.h>
+
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Serializer/XML/XMLElement.h>
+
+namespace Swift {
+
+std::string InputEventSerializer::serializePayload(boost::shared_ptr<InputEventPayload> payload) const {
+ XMLElement inputevt("inputevt", "http://sip-comunicator.org/protocol/inputevt");
+ inputevt.setAttribute("action", actionToString(payload->getAction()));
+
+ XMLElement::ref remoteControlNode = boost::make_shared<XMLElement>("remote-control", "http://sip-communicator.org/protocol/inputevt");
+ foreach (InputEventPayload::Event event, payload->getEvents()) {
+ XMLElement::ref eventNode = boost::make_shared<XMLElement>(eventTypeToString(event.type));
+ switch (event.type) {
+ case InputEventPayload::Event::MouseMove:
+ eventNode->setAttribute("x", boost::lexical_cast<std::string>(event.realArg1));
+ eventNode->setAttribute("y", boost::lexical_cast<std::string>(event.realArg2));
+ break;
+ case InputEventPayload::Event::MouseWheel:
+ eventNode->setAttribute("notch", boost::lexical_cast<std::string>(event.integerArg));
+ break;
+ case InputEventPayload::Event::MousePress:
+ case InputEventPayload::Event::MouseRelease:
+ eventNode->setAttribute("btns", boost::lexical_cast<std::string>(event.integerArg));
+ break;
+ case InputEventPayload::Event::KeyType:
+ eventNode->setAttribute("keychar", boost::lexical_cast<std::string>(event.integerArg));
+ break;
+ case InputEventPayload::Event::KeyPress:
+ case InputEventPayload::Event::KeyRelease:
+ eventNode->setAttribute("keycode", boost::lexical_cast<std::string>(event.integerArg));
+ break;
+ default:
+ break;
+ }
+ remoteControlNode->addNode(eventNode);
+ }
+
+ inputevt.addNode(remoteControlNode);
+ return inputevt.serialize();
+}
+
+std::string InputEventSerializer::actionToString(InputEventPayload::Action action) {
+ switch (action) {
+ case InputEventPayload::Notify:
+ return "notify";
+ default:
+ std::cerr << "Serializing unknown action." << std::endl;
+ }
+ return "";
+}
+
+std::string InputEventSerializer::eventTypeToString(InputEventPayload::Event::EventType eventType) {
+ switch (eventType) {
+ case InputEventPayload::Event::MouseMove:
+ return "mouse-move";
+ case InputEventPayload::Event::MousePress:
+ return "mouse-press";
+ case InputEventPayload::Event::MouseRelease:
+ return "mouse-release";
+ case InputEventPayload::Event::MouseWheel:
+ return "mouse-wheel";
+ case InputEventPayload::Event::KeyPress:
+ return "key-press";
+ case InputEventPayload::Event::KeyRelease:
+ return "key-release";
+ case InputEventPayload::Event::KeyType:
+ return "key-type";
+ default:
+ std::cerr << "Serializing unknown event type." << std::endl;
+ }
+ return "";
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/InputEventSerializer.h b/Swiften/Serializer/PayloadSerializers/InputEventSerializer.h
new file mode 100644
index 0000000..d7bdc11
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/InputEventSerializer.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Serializer/GenericPayloadSerializer.h>
+#include <Swiften/Elements/InputEventPayload.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class InputEventSerializer : public GenericPayloadSerializer<InputEventPayload> {
+ public:
+ virtual std::string serializePayload(boost::shared_ptr<InputEventPayload>) const;
+
+ private:
+ static std::string actionToString(InputEventPayload::Action action);
+ static std::string eventTypeToString(InputEventPayload::Event::EventType eventType);
+ };
+}
diff --git a/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.cpp
index c0dfba1..34bc75c 100644
--- a/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.cpp
@@ -19,9 +19,6 @@
namespace Swift {
-JingleRTPDescriptionSerializer::JingleRTPDescriptionSerializer() {
-}
-
std::string JingleRTPDescriptionSerializer::serializePayload(boost::shared_ptr<JingleRTPDescription> payload) const {
XMLElement description("description", "urn:xmpp:jingle:apps:rtp:1");
description.setAttribute("media", mediaTypeToString(payload->getMedia()));
@@ -48,7 +45,7 @@ std::string JingleRTPDescriptionSerializer::serializePayload(boost::shared_ptr<J
return description.serialize();
}
-std::string JingleRTPDescriptionSerializer::mediaTypeToString(JingleRTPDescription::MediaType mediaType) const {
+std::string JingleRTPDescriptionSerializer::mediaTypeToString(JingleRTPDescription::MediaType mediaType) {
switch (mediaType) {
case JingleRTPDescription::Audio:
return "audio";
diff --git a/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.h
index 3d23d85..1911b69 100644
--- a/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/JingleRTPDescriptionSerializer.h
@@ -4,25 +4,17 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-
#pragma once
#include <Swiften/Serializer/GenericPayloadSerializer.h>
#include <Swiften/Elements/JingleRTPDescription.h>
-
-
namespace Swift {
- class PayloadSerializerCollection;
- class XMLElement;
-
class JingleRTPDescriptionSerializer : public GenericPayloadSerializer<JingleRTPDescription> {
public:
- JingleRTPDescriptionSerializer();
-
- virtual std::string serializePayload(boost::shared_ptr<JingleRTPDescription>) const;
+ virtual std::string serializePayload(boost::shared_ptr<JingleRTPDescription>) const;
private:
- std::string mediaTypeToString(JingleRTPDescription::MediaType mediaType) const;
+ static std::string mediaTypeToString(JingleRTPDescription::MediaType mediaType);
};
}