summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp12
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h6
-rw-r--r--Swift/Controllers/MainController.cpp15
-rw-r--r--Swift/Controllers/MainController.h2
-rw-r--r--Swift/Controllers/Roster/ContactRosterItem.h1
-rw-r--r--Swift/Controllers/Roster/RosterController.cpp16
-rw-r--r--Swift/Controllers/Roster/RosterController.h4
-rw-r--r--Swift/Controllers/SConscript3
-rw-r--r--Swift/Controllers/ScreenSharing/DesktopScreenGrabber.h18
-rw-r--r--Swift/Controllers/ScreenSharing/ScreenSharingController.cpp93
-rw-r--r--Swift/Controllers/ScreenSharing/ScreenSharingController.h51
-rw-r--r--Swift/Controllers/UIEvents/ShareScreenUIEvent.h24
-rw-r--r--Swift/Controllers/UIInterfaces/RemoteScreenWindow.h24
-rw-r--r--Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h21
-rw-r--r--Swift/Controllers/UIInterfaces/UIFactory.h5
-rw-r--r--Swift/QtUI/QtUIFactory.cpp8
-rw-r--r--Swift/QtUI/QtUIFactory.h1
-rw-r--r--Swift/QtUI/Roster/QtRosterWidget.cpp8
-rw-r--r--Swift/QtUI/SConscript5
-rw-r--r--Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp40
-rw-r--r--Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h19
-rw-r--r--Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp34
-rw-r--r--Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h31
-rw-r--r--Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp54
-rw-r--r--Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h34
25 files changed, 518 insertions, 11 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 1e0e9c2..48ea006 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -43,6 +43,8 @@
#include <Swift/Controllers/SettingConstants.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swift/Controllers/WhiteboardManager.h>
+#include <Swift/Controllers/ScreenSharing/ScreenSharingController.h>
+#include <Swiften/ScreenSharing/IncomingScreenSharing.h>
namespace Swift {
@@ -70,6 +72,7 @@ ChatsManager::ChatsManager(
MUCSearchWindowFactory* mucSearchWindowFactory,
ProfileSettingsProvider* profileSettings,
FileTransferOverview* ftOverview,
+ ScreenSharingController* ssController,
XMPPRoster* roster,
bool eagleMode,
SettingsProvider* settings,
@@ -82,6 +85,7 @@ ChatsManager::ChatsManager(
entityCapsProvider_(entityCapsProvider),
mucManager(mucManager),
ftOverview_(ftOverview),
+ ssController_(ssController),
roster_(roster),
eagleMode_(eagleMode),
settings_(settings),
@@ -112,6 +116,7 @@ ChatsManager::ChatsManager(
mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_);
mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1));
ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1));
+ ssController->onNewIncomingScreenSharing.connect(boost::bind(&ChatsManager::handleNewIncomingScreenSharing, this, _1));
whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2));
whiteboardManager_->onRequestAccepted.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardAccepted));
whiteboardManager_->onSessionTerminate.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardTerminated));
@@ -664,6 +669,13 @@ void ChatsManager::handleNewFileTransferController(FileTransferController* ftc)
chatController->activateChatWindow();
}
+void ChatsManager::handleNewIncomingScreenSharing(boost::shared_ptr<IncomingScreenSharing> iss)
+{
+ ChatController* chatController = getChatControllerOrCreate(iss->getSender());
+// chatController->handleNewFileTransferController(ftc);
+ chatController->activateChatWindow();
+}
+
void ChatsManager::handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf) {
ChatController* chatController = getChatControllerOrCreate(contact);
chatController->handleWhiteboardSessionRequest(senderIsSelf);
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 5b8b785..31006b0 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -50,10 +50,12 @@ namespace Swift {
class SettingsProvider;
class WhiteboardManager;
class HistoryController;
+ class ScreenSharingController;
+ class IncomingScreenSharing;
class ChatsManager {
public:
- ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager);
+ ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, ScreenSharingController* ssController, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager);
virtual ~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setOnline(bool enabled);
@@ -75,6 +77,7 @@ namespace Swift {
void handleBookmarksReady();
void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC);
void handleNewFileTransferController(FileTransferController*);
+ void handleNewIncomingScreenSharing(boost::shared_ptr<IncomingScreenSharing> iss);
void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf);
void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state);
void appendRecent(const ChatListWindow::Chat& chat);
@@ -130,6 +133,7 @@ namespace Swift {
std::list<ChatListWindow::Chat> recentChats_;
ProfileSettingsProvider* profileSettings_;
FileTransferOverview* ftOverview_;
+ ScreenSharingController* ssController_;
XMPPRoster* roster_;
bool eagleMode_;
bool userWantsReceipts_;
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 581ff31..17dab36 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -78,6 +78,7 @@
#include <Swiften/Client/ClientXMLTracer.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swiften/Client/StanzaChannel.h>
+#include "Swift/Controllers/ScreenSharing/ScreenSharingController.h"
namespace Swift {
@@ -109,7 +110,8 @@ MainController::MainController(
idleDetector_(idleDetector),
loginWindow_(NULL) ,
useDelayForLatency_(useDelayForLatency),
- ftOverview_(NULL) {
+ ftOverview_(NULL),
+ ssController_(NULL) {
storages_ = NULL;
certificateStorage_ = NULL;
statusTracker_ = NULL;
@@ -237,6 +239,8 @@ void MainController::resetClient() {
#endif
delete ftOverview_;
ftOverview_ = NULL;
+ delete ssController_;
+ ssController_ = NULL;
delete rosterController_;
rosterController_ = NULL;
delete eventNotifier_;
@@ -302,7 +306,8 @@ void MainController::handleConnected() {
client_->getFileTransferManager()->startListeningOnPort(randomPort);
ftOverview_ = new FileTransferOverview(client_->getFileTransferManager());
fileTransferListController_->setFileTransferOverview(ftOverview_);
- rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_);
+ ssController_ = new ScreenSharingController(client_->getScreenSharingManager(), uiFactory_, networkFactories_->getTimerFactory());
+ rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, ssController_);
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this));
@@ -320,7 +325,7 @@ void MainController::handleConnected() {
historyViewController_ = new HistoryViewController(jid_, uiEventStream_, historyController_, client_->getNickResolver(), client_->getAvatarManager(), client_->getPresenceOracle(), uiFactory_);
chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_);
#else
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_);
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, ssController_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_);
#endif
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
@@ -340,6 +345,10 @@ void MainController::handleConnected() {
discoInfo.addFeature(DiscoInfo::JingleFTFeature);
discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature);
discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature);
+ // Screen sharing
+ discoInfo.addFeature(DiscoInfo::JingleRTPFeature);
+ discoInfo.addFeature(DiscoInfo::JingleTransportRawUDPFeature);
+ discoInfo.addFeature(DiscoInfo::JingleScreenSharingFeature);
#endif
#ifdef SWIFT_EXPERIMENTAL_WB
discoInfo.addFeature(DiscoInfo::WhiteboardFeature);
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 2e5bd05..ad8fef2 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -71,6 +71,7 @@ namespace Swift {
class AdHocCommandWindowFactory;
class FileTransferOverview;
class WhiteboardManager;
+ class ScreenSharingController;
class MainController {
public:
@@ -176,5 +177,6 @@ namespace Swift {
static const int SecondsToWaitBeforeForceQuitting;
FileTransferOverview* ftOverview_;
WhiteboardManager* whiteboardManager_;
+ ScreenSharingController* ssController_;
};
}
diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h
index 8389a44..d156b1f 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.h
+++ b/Swift/Controllers/Roster/ContactRosterItem.h
@@ -26,6 +26,7 @@ class ContactRosterItem : public RosterItem {
enum Feature {
FileTransferFeature,
WhiteboardFeature,
+ ScreenSharingFeature,
};
public:
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index ec52993..40fd957 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -36,6 +36,7 @@
#include "Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h"
#include "Swift/Controllers/UIEvents/RenameGroupUIEvent.h"
#include "Swift/Controllers/UIEvents/SendFileUIEvent.h"
+#include "Swift/Controllers/UIEvents/ShareScreenUIEvent.h"
#include <Swiften/FileTransfer/FileTransferManager.h>
#include <Swiften/Client/NickManager.h>
#include <Swift/Controllers/Intl.h>
@@ -44,14 +45,15 @@
#include <Swiften/Disco/EntityCapsManager.h>
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swift/Controllers/SettingConstants.h>
+#include "Swift/Controllers/ScreenSharing/ScreenSharingController.h"
namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview)
- : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview) {
+RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview, ScreenSharingController *ssController)
+ : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), ssController_(ssController) {
assert(fileTransferOverview);
iqRouter_ = iqRouter;
presenceOracle_ = presenceOracle;
@@ -238,6 +240,10 @@ void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
//TODO add send file dialog to ChatView of receipient jid
ftOverview_->sendFile(sendFileEvent->getJID(), sendFileEvent->getFilename());
}
+ else if (boost::shared_ptr<ShareScreenUIEvent> shareScreenEvent = boost::dynamic_pointer_cast<ShareScreenUIEvent>(event)) {
+ std::cout << "Create sharing: " << ssController_->createOugoingScreenSharing(shareScreenEvent->jid);
+ std::cout << std::endl;
+ }
}
void RosterController::setContactGroups(const JID& jid, const std::vector<std::string>& groups) {
@@ -324,6 +330,12 @@ void RosterController::handleOnCapsChanged(const JID& jid) {
if (info->hasFeature(DiscoInfo::WhiteboardFeature)) {
features.insert(ContactRosterItem::WhiteboardFeature);
}
+ if (info->hasFeature(DiscoInfo::JingleFeature)
+ && info->hasFeature(DiscoInfo::JingleRTPFeature)
+ && info->hasFeature(DiscoInfo::JingleTransportRawUDPFeature)
+ && info->hasFeature(DiscoInfo::JingleScreenSharingFeature)) {
+ features.insert(ContactRosterItem::ScreenSharingFeature);
+ }
roster_->setAvailableFeatures(jid, features);
}
}
diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h
index 5e40124..2fb642d 100644
--- a/Swift/Controllers/Roster/RosterController.h
+++ b/Swift/Controllers/Roster/RosterController.h
@@ -39,10 +39,11 @@ namespace Swift {
class NickManager;
class EntityCapsProvider;
class FileTransferManager;
+ class ScreenSharingController;
class RosterController {
public:
- RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview);
+ RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ScreenSharingController* ssController);
~RosterController();
void showRosterWindow();
MainWindow* getWindow() {return mainWindow_;};
@@ -94,6 +95,7 @@ namespace Swift {
UIEventStream* uiEventStream_;
EntityCapsProvider* entityCapsManager_;
FileTransferOverview* ftOverview_;
+ ScreenSharingController* ssController_;
boost::bsignals::scoped_connection changeStatusConnection_;
boost::bsignals::scoped_connection signOutConnection_;
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 7cd017b..2dba9a9 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -74,7 +74,8 @@ if env["SCONS_STAGE"] == "build" :
"XMPPURIController.cpp",
"ChatMessageSummarizer.cpp",
"SettingConstants.cpp",
- "WhiteboardManager.cpp"
+ "WhiteboardManager.cpp",
+ "ScreenSharing/ScreenSharingController.cpp",
])
env.Append(UNITTEST_SOURCES = [
diff --git a/Swift/Controllers/ScreenSharing/DesktopScreenGrabber.h b/Swift/Controllers/ScreenSharing/DesktopScreenGrabber.h
new file mode 100644
index 0000000..4fac6fe
--- /dev/null
+++ b/Swift/Controllers/ScreenSharing/DesktopScreenGrabber.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+ class Image;
+
+ class DesktopScreenGrabber {
+ public:
+ virtual ~DesktopScreenGrabber() {}
+
+ virtual Image grab() const = 0;
+ };
+}
diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp b/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp
new file mode 100644
index 0000000..fd3357d
--- /dev/null
+++ b/Swift/Controllers/ScreenSharing/ScreenSharingController.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "ScreenSharingController.h"
+
+#include <Swiften/ScreenSharing/ScreenSharingManager.h>
+#include <Swiften/ScreenSharing/IncomingScreenSharing.h>
+#include <Swiften/ScreenSharing/OutgoingScreenSharing.h>
+#include <Swiften/ScreenSharing/Image.h>
+#include <Swiften/Network/TimerFactory.h>
+#include <Swiften/Network/Timer.h>
+#include "Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h"
+#include "Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h"
+#include "Swift/Controllers/UIInterfaces/RemoteScreenWindow.h"
+
+#include <boost/bind.hpp>
+
+namespace Swift {
+
+ScreenSharingController::ScreenSharingController(ScreenSharingManager *screenSharingManager, RemoteScreenWindowFactory* remoteScreenViewerFactory, TimerFactory* timerFactory)
+ : screenSharingManager(screenSharingManager), remoteScreenWindowFactory(remoteScreenViewerFactory), remoteScreenWindow(0),
+ grabTimer(timerFactory->createTimer(500)), screenGrabber(new QtDesktopScreenGrabber)
+{
+ screenSharingManager->onIncomingScreenSharing.connect(boost::bind(&ScreenSharingController::handleIncomingScreenSharing, this, _1));
+ grabTimer->onTick.connect(boost::bind(&ScreenSharingController::handleGrabTimerTick, this));
+}
+
+ScreenSharingController::~ScreenSharingController()
+{
+ grabTimer->onTick.disconnect(boost::bind(&ScreenSharingController::handleGrabTimerTick, this));
+ delete remoteScreenWindow;
+}
+
+boost::shared_ptr<OutgoingScreenSharing> ScreenSharingController::createOugoingScreenSharing(const JID& to)
+{
+ if (!oss) {
+ oss = screenSharingManager->createOutgoingScreenSharing(to);
+ if (oss) {
+ oss->onReady.connect(boost::bind(&ScreenSharingController::handleOssReady, this));
+ oss->onFinished.connect(boost::bind(&ScreenSharingController::handleOutgoingFinished, this));
+ const Image& image = screenGrabber->grab();
+ oss->start(image.width, image.height);
+ }
+ return oss;
+ }
+ return boost::shared_ptr<OutgoingScreenSharing>();
+}
+
+void ScreenSharingController::handleIncomingScreenSharing(boost::shared_ptr<IncomingScreenSharing> incomingScreenSharing)
+{
+ if (iss) {
+ incomingScreenSharing->cancel();
+ } else {
+ iss = incomingScreenSharing;
+ iss->accept();
+ iss->onFinished.connect(boost::bind(&ScreenSharingController::handleIncomingFinished, this));
+ remoteScreenWindow = remoteScreenWindowFactory->createRemoteScreenViewer(iss);
+// onNewIncomingScreenSharing(iss);
+ }
+}
+
+void ScreenSharingController::handleGrabTimerTick()
+{
+ if (oss) {
+ grabTimer->start();
+ oss->addImage(screenGrabber->grab());
+ }
+}
+
+void ScreenSharingController::handleOssReady()
+{
+ handleGrabTimerTick();
+}
+
+void ScreenSharingController::handleIncomingFinished()
+{
+ iss->onFinished.disconnect(boost::bind(&ScreenSharingController::handleIncomingFinished, this));
+ iss.reset();
+ delete remoteScreenWindow;
+ remoteScreenWindow = 0;
+}
+
+void ScreenSharingController::handleOutgoingFinished()
+{
+ oss->onReady.disconnect(boost::bind(&ScreenSharingController::handleOssReady, this));
+ oss->onFinished.disconnect(boost::bind(&ScreenSharingController::handleOutgoingFinished, this));
+ oss.reset();
+}
+
+}
diff --git a/Swift/Controllers/ScreenSharing/ScreenSharingController.h b/Swift/Controllers/ScreenSharing/ScreenSharingController.h
new file mode 100644
index 0000000..6bae132
--- /dev/null
+++ b/Swift/Controllers/ScreenSharing/ScreenSharingController.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class ScreenSharingManager;
+ class IncomingScreenSharing;
+ class OutgoingScreenSharing;
+ class Timer;
+ class TimerFactory;
+ class DesktopScreenGrabber;
+ class RemoteScreenWindowFactory;
+ class RemoteScreenWindow;
+ class JID;
+
+ class ScreenSharingController {
+ public:
+ ScreenSharingController(ScreenSharingManager* screenSharingManager, RemoteScreenWindowFactory* remoteScreenWindowFactory, TimerFactory* timerFactory);
+ ~ScreenSharingController();
+
+ boost::shared_ptr<OutgoingScreenSharing> createOugoingScreenSharing(const JID& to);
+
+ public:
+ boost::signal<void (boost::shared_ptr<IncomingScreenSharing>)> onNewIncomingScreenSharing;
+
+ private:
+ void handleIncomingScreenSharing(boost::shared_ptr<IncomingScreenSharing> incomingScreenSharing);
+ void handleGrabTimerTick();
+ void handleOssReady();
+ void handleIncomingFinished();
+ void handleOutgoingFinished();
+
+ private:
+ ScreenSharingManager* screenSharingManager;
+ RemoteScreenWindowFactory* remoteScreenWindowFactory;
+
+ RemoteScreenWindow* remoteScreenWindow;
+ boost::shared_ptr<Timer> grabTimer;
+ DesktopScreenGrabber* screenGrabber;
+ boost::shared_ptr<IncomingScreenSharing> iss;
+ boost::shared_ptr<OutgoingScreenSharing> oss;
+ };
+}
diff --git a/Swift/Controllers/UIEvents/ShareScreenUIEvent.h b/Swift/Controllers/UIEvents/ShareScreenUIEvent.h
new file mode 100644
index 0000000..de2b670
--- /dev/null
+++ b/Swift/Controllers/UIEvents/ShareScreenUIEvent.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class ShareScreenUIEvent : public UIEvent {
+ public:
+ typedef boost::shared_ptr<SendFileUIEvent> ref;
+
+ ShareScreenUIEvent(const JID& jid) : jid(jid) {}
+
+ public:
+ JID jid;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h b/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h
new file mode 100644
index 0000000..c31ca91
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/RemoteScreenWindow.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class IncomingScreenSharing;
+ class Image;
+
+ class RemoteScreenWindow {
+ public:
+ RemoteScreenWindow(boost::shared_ptr<IncomingScreenSharing> incScreenSharing)
+ : iss(incScreenSharing) {}
+ virtual ~RemoteScreenWindow() {}
+
+ protected:
+ boost::shared_ptr<IncomingScreenSharing> iss;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h b/Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h
new file mode 100644
index 0000000..7c78777
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include "Swift/Controllers/UIInterfaces/RemoteScreenWindow.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class IncomingScreenSharing;
+ class RemoteScreenWindowFactory {
+ public:
+ virtual ~RemoteScreenWindowFactory() {}
+
+ virtual RemoteScreenWindow* createRemoteScreenViewer(boost::shared_ptr<IncomingScreenSharing> iss) = 0;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h
index 6b4efd8..e0e5425 100644
--- a/Swift/Controllers/UIInterfaces/UIFactory.h
+++ b/Swift/Controllers/UIInterfaces/UIFactory.h
@@ -21,12 +21,12 @@
#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h>
#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/RemoteScreenWindowFactory.h>
namespace Swift {
class UIFactory :
public ChatListWindowFactory,
public ChatWindowFactory,
- public HistoryWindowFactory,
public EventWindowFactory,
public LoginWindowFactory,
public MainWindowFactory,
@@ -38,7 +38,8 @@ namespace Swift {
public ContactEditWindowFactory,
public AdHocCommandWindowFactory,
public FileTransferListWidgetFactory,
- public WhiteboardWindowFactory {
+ public WhiteboardWindowFactory,
+ public RemoteScreenWindowFactory {
public:
virtual ~UIFactory() {}
};
diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp
index a154fb0..ba9cbc9 100644
--- a/Swift/QtUI/QtUIFactory.cpp
+++ b/Swift/QtUI/QtUIFactory.cpp
@@ -26,6 +26,7 @@
#include "QtAdHocCommandWindow.h"
#include "QtFileTransferListWidget.h"
#include "Whiteboard/QtWhiteboardWindow.h"
+#include <Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h>
#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <QtHistoryWindow.h>
@@ -77,6 +78,13 @@ FileTransferListWidget* QtUIFactory::createFileTransferListWidget() {
return widget;
}
+RemoteScreenWindow* QtUIFactory::createRemoteScreenViewer(boost::shared_ptr<IncomingScreenSharing> iss)
+{
+ QtRemoteScreenWindow* rsv = new QtRemoteScreenWindow(iss);
+ rsv->show();
+ return rsv;
+}
+
MainWindow* QtUIFactory::createMainWindow(UIEventStream* eventStream) {
lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), emoticonsExist_);
return lastMainWindow;
diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h
index 30f0101..8d4be81 100644
--- a/Swift/QtUI/QtUIFactory.h
+++ b/Swift/QtUI/QtUIFactory.h
@@ -46,6 +46,7 @@ namespace Swift {
virtual ContactEditWindow* createContactEditWindow();
virtual FileTransferListWidget* createFileTransferListWidget();
virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession);
+ virtual RemoteScreenWindow* createRemoteScreenViewer(boost::shared_ptr<IncomingScreenSharing> iss);
virtual void createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command);
private slots:
diff --git a/Swift/QtUI/Roster/QtRosterWidget.cpp b/Swift/QtUI/Roster/QtRosterWidget.cpp
index 1cf073b..0e75057 100644
--- a/Swift/QtUI/Roster/QtRosterWidget.cpp
+++ b/Swift/QtUI/Roster/QtRosterWidget.cpp
@@ -16,6 +16,7 @@
#include "Swift/Controllers/UIEvents/RenameGroupUIEvent.h"
#include "Swift/Controllers/UIEvents/SendFileUIEvent.h"
#include "Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h"
+#include "Swift/Controllers/UIEvents/ShareScreenUIEvent.h"
#include "QtContactEditWindow.h"
#include "Swift/Controllers/Roster/ContactRosterItem.h"
#include "Swift/Controllers/Roster/GroupRosterItem.h"
@@ -62,6 +63,10 @@ void QtRosterWidget::contextMenuEvent(QContextMenuEvent* event) {
if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
sendFile = contextMenu.addAction(tr("Send File"));
}
+ QAction* shareScreen = NULL;
+ if (contact->supportsFeature(ContactRosterItem::ScreenSharingFeature)) {
+ shareScreen = contextMenu.addAction(tr("Share my screen"));
+ }
#endif
#ifdef SWIFT_EXPERIMENTAL_WB
QAction* startWhiteboardChat = NULL;
@@ -85,6 +90,9 @@ void QtRosterWidget::contextMenuEvent(QContextMenuEvent* event) {
eventStream_->send(boost::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(fileName)));
}
}
+ else if (shareScreen && result == shareScreen) {
+ eventStream_->send(boost::make_shared<ShareScreenUIEvent>(contact->getJID()));
+ }
#endif
#ifdef SWIFT_EXPERIMENTAL_WB
else if (startWhiteboardChat && result == startWhiteboardChat) {
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index c940d49..9d8f42b 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -161,7 +161,10 @@ sources = [
"QtChatWindowJSBridge.cpp",
"QtMUCConfigurationWindow.cpp",
"QtAffiliationEditor.cpp",
- "QtUISettingConstants.cpp"
+ "QtUISettingConstants.cpp",
+ "ScreenSharing/RemoteScreenViewerWidget.cpp",
+ "ScreenSharing/QtRemoteScreenWindow.cpp",
+ "ScreenSharing/QtDesktopScreenGrabber.cpp",
]
myenv["SWIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift")
diff --git a/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp b/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp
new file mode 100644
index 0000000..a5eeafd
--- /dev/null
+++ b/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtDesktopScreenGrabber.h"
+
+#include <QImage>
+#include <QPixmap>
+#include <QApplication>
+#include <QDesktopWidget>
+
+#include <Swiften/ScreenSharing/Image.h>
+
+/*#include <QImage>
+#include <QLabel>*/
+
+namespace Swift {
+
+QtDesktopScreenGrabber::QtDesktopScreenGrabber()
+{
+ /*Image img = grab();
+ QImage qImg(img.data.data(), img.width, img.height, QImage::Format_RGB888);
+ QLabel *label = new QLabel;
+ label->setPixmap(QPixmap::fromImage(qImg));
+ label->show();*/
+}
+
+QtDesktopScreenGrabber::~QtDesktopScreenGrabber()
+{
+}
+
+Image QtDesktopScreenGrabber::grab() const
+{
+ QImage qImg = QPixmap::grabWindow(QApplication::desktop()->winId()).toImage().convertToFormat(QImage::Format_RGB888);
+ return Image(qImg.width(), qImg.height(), qImg.constBits());
+}
+
+}
diff --git a/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h b/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h
new file mode 100644
index 0000000..55a7842
--- /dev/null
+++ b/Swift/QtUI/ScreenSharing/QtDesktopScreenGrabber.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include "Swift/Controllers/ScreenSharing/DesktopScreenGrabber.h"
+
+namespace Swift {
+ class QtDesktopScreenGrabber : public DesktopScreenGrabber {
+ public:
+ QtDesktopScreenGrabber();
+ virtual ~QtDesktopScreenGrabber();
+
+ virtual Image grab() const;
+ };
+}
diff --git a/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp
new file mode 100644
index 0000000..e6cd291
--- /dev/null
+++ b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtRemoteScreenWindow.h"
+#include "RemoteScreenViewerWidget.h"
+
+#include <QToolBar>
+
+#include <Swiften/ScreenSharing/IncomingScreenSharing.h>
+
+namespace Swift {
+
+QtRemoteScreenWindow::QtRemoteScreenWindow(boost::shared_ptr<IncomingScreenSharing> incScreenSharing, QWidget *parent)
+ : QMainWindow(parent), RemoteScreenWindow(incScreenSharing)
+{
+ setCentralWidget(new RemoteScreenViewerWidget(iss));
+
+ controlToolBar = addToolBar(tr("Control"));
+ closeAction = controlToolBar->addAction(QIcon::fromTheme("window-close"), tr("&Terminate session"), this, SLOT(handleCloseTriggered()));
+}
+
+QtRemoteScreenWindow::~QtRemoteScreenWindow()
+{
+}
+
+void QtRemoteScreenWindow::handleCloseTriggered()
+{
+ iss->stop();
+}
+
+}
diff --git a/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h
new file mode 100644
index 0000000..00ac803
--- /dev/null
+++ b/Swift/QtUI/ScreenSharing/QtRemoteScreenWindow.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include "Swift/Controllers/UIInterfaces/RemoteScreenWindow.h"
+
+#include <QMainWindow>
+
+class QToolBar;
+
+namespace Swift {
+
+ class QtRemoteScreenWindow : public QMainWindow, public RemoteScreenWindow {
+ Q_OBJECT
+
+ public:
+ QtRemoteScreenWindow(boost::shared_ptr<IncomingScreenSharing> incScreenSharing, QWidget *parent = 0);
+ virtual ~QtRemoteScreenWindow();
+
+ private slots:
+ void handleCloseTriggered();
+
+ private:
+ QAction* closeAction;
+ QToolBar* controlToolBar;
+ };
+}
diff --git a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp
new file mode 100644
index 0000000..f601f1b
--- /dev/null
+++ b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "RemoteScreenViewerWidget.h"
+
+#include <QResizeEvent>
+#include <QPainter>
+
+#include <boost/bind.hpp>
+
+#include <Swiften/ScreenSharing/IncomingScreenSharing.h>
+#include <Swiften/ScreenSharing/Image.h>
+
+
+namespace Swift {
+
+RemoteScreenViewerWidget::RemoteScreenViewerWidget(boost::shared_ptr<IncomingScreenSharing> incScreenSharing, QWidget *parent) :
+ QWidget(parent), iss(incScreenSharing)
+{
+ iss->onNewImageReceived.connect(boost::bind(&RemoteScreenViewerWidget::handleNewImageReceived, this, _1));
+}
+
+RemoteScreenViewerWidget::~RemoteScreenViewerWidget()
+{
+ iss->onNewImageReceived.disconnect(boost::bind(&RemoteScreenViewerWidget::handleNewImageReceived, this, _1));
+}
+
+void RemoteScreenViewerWidget::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ if (!pixmap.isNull()) {
+ painter.translate(geometry().center());
+ painter.drawPixmap(-pixmap.rect().center(), pixmap);
+ }
+}
+
+void RemoteScreenViewerWidget::resizeEvent(QResizeEvent *event)
+{
+ if (!pixmap.isNull())
+ pixmap = pixmap.scaled(event->size(), Qt::KeepAspectRatio);
+ QWidget::resizeEvent(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);
+ update();
+}
+
+}
diff --git a/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h
new file mode 100644
index 0000000..622bd26
--- /dev/null
+++ b/Swift/QtUI/ScreenSharing/RemoteScreenViewerWidget.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class IncomingScreenSharing;
+ class Image;
+
+ class RemoteScreenViewerWidget : public QWidget {
+ Q_OBJECT
+ public:
+ RemoteScreenViewerWidget(boost::shared_ptr<IncomingScreenSharing> incScreenSharing, QWidget *parent = 0);
+ ~RemoteScreenViewerWidget();
+
+ protected:
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *event);
+
+ private:
+ void handleNewImageReceived(const Image& image);
+
+ private:
+ boost::shared_ptr<IncomingScreenSharing> iss;
+ QPixmap pixmap;
+ };
+}