diff options
Diffstat (limited to 'Swiften/ScreenSharing/IncomingScreenSharing.cpp')
-rw-r--r-- | Swiften/ScreenSharing/IncomingScreenSharing.cpp | 62 |
1 files changed, 58 insertions, 4 deletions
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); + } +} + } |