summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorAndrzej J.R. Hunt <andrzej@ahunt.org>2012-08-10 17:20:16 +0200
committerAndrzej J.R. Hunt <andrzej@ahunt.org>2012-08-10 17:21:27 +0200
commit2a248dc15ff314a630b19536c32c6ce6fd4959d1 (patch)
tree9145f5031dd8ba4a08bf19a12d3153f30d1915b3 /sd
parent0c0d24589f167f5f77f3d955ebfa3fc807ad38c4 (diff)
Refactored remote communication to allow for pairing.
Change-Id: Ia31e33fca6dca47faa1fad1a5879c3902df05835
Diffstat (limited to 'sd')
-rw-r--r--sd/Library_sd.mk1
-rw-r--r--sd/source/ui/dlg/RemoteDialog.cxx6
-rw-r--r--sd/source/ui/inc/RemoteServer.hxx42
-rw-r--r--sd/source/ui/remotecontrol/Communicator.cxx128
-rw-r--r--sd/source/ui/remotecontrol/Communicator.hxx62
-rw-r--r--sd/source/ui/remotecontrol/Listener.cxx13
-rw-r--r--sd/source/ui/remotecontrol/Listener.hxx6
-rw-r--r--sd/source/ui/remotecontrol/Server.cxx173
8 files changed, 304 insertions, 127 deletions
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 1fb99e02ca51..92db929a067a 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -327,6 +327,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
sd/source/ui/presenter/PresenterPreviewCache \
sd/source/ui/presenter/PresenterTextView \
sd/source/ui/presenter/SlideRenderer \
+ sd/source/ui/remotecontrol/Communicator \
sd/source/ui/remotecontrol/DiscoveryService \
sd/source/ui/remotecontrol/ImagePreparer \
sd/source/ui/remotecontrol/Server \
diff --git a/sd/source/ui/dlg/RemoteDialog.cxx b/sd/source/ui/dlg/RemoteDialog.cxx
index 85d5ad2c91e5..465febc5fba9 100644
--- a/sd/source/ui/dlg/RemoteDialog.cxx
+++ b/sd/source/ui/dlg/RemoteDialog.cxx
@@ -26,12 +26,12 @@ RemoteDialog::RemoteDialog( Window *pWindow ) :
{
FreeResource();
- vector<ClientInfo> aClients( RemoteServer::getClients() );
+ vector<ClientInfo*> aClients( RemoteServer::getClients() );
- for ( vector<ClientInfo>::const_iterator aIt( aClients.begin() );
+ for ( vector<ClientInfo*>::const_iterator aIt( aClients.begin() );
aIt < aClients.end(); aIt++ )
{
- mClientBox.addEntry( *aIt );
+ mClientBox.addEntry( **aIt );
}
mButtonConnect.SetClickHdl( LINK( this, RemoteDialog, HandleConnectButton ) );
diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx
index d3e202ba7fae..a77f5aba873c 100644
--- a/sd/source/ui/inc/RemoteServer.hxx
+++ b/sd/source/ui/inc/RemoteServer.hxx
@@ -16,6 +16,7 @@
#include <sys/types.h>
#include <vector>
+#include <osl/mutex.hxx>
#include <osl/socket.hxx>
#include <rtl/ref.hxx>
#include <salhelper/thread.hxx>
@@ -36,10 +37,7 @@ namespace css = ::com::sun::star;
namespace sd
{
-
- class Transmitter;
- class Listener;
- class ImagePreparer;
+ class Communicator;
struct ClientInfo
{
@@ -47,33 +45,53 @@ namespace sd
rtl::OUString mAddress;
enum PROTOCOL { NETWORK = 1, BLUETOOTH };
- ClientInfo( OUString rName, OUString rAddress) :
+ ClientInfo( const rtl::OUString rName, const rtl::OUString rAddress ) :
mName( rName ),
mAddress( rAddress ) {}
};
+ struct ClientInfoInternal:
+ ClientInfo
+ {
+ osl::StreamSocket mStreamSocket;
+ rtl::OUString mPin;
+
+ ClientInfoInternal( const rtl::OUString rName,
+ const rtl::OUString rAddress,
+ osl::StreamSocket &rSocket, rtl::OUString rPin ):
+ ClientInfo( rName, rAddress ),
+ mStreamSocket( rSocket ),
+ mPin( rPin ) {}
+ };
+
class RemoteServer : public salhelper::Thread
{
public:
+ // Internal setup
static void setup();
+
+ // For slideshowimpl to inform us.
static void presentationStarted( const css::uno::Reference<
css::presentation::XSlideShowController > &rController );
static void presentationStopped();
- void informListenerDestroyed();
- SD_DLLPUBLIC static std::vector<ClientInfo> getClients();
+ // For the control dialog
+ SD_DLLPUBLIC static std::vector<ClientInfo*> getClients();
SD_DLLPUBLIC static void connectClient( ClientInfo aClient, rtl::OString aPin );
+
+ // For the communicator
+ static void removeCommunicator( Communicator* pCommunicator );
private:
RemoteServer();
~RemoteServer();
static RemoteServer *spServer;
osl::AcceptorSocket mSocket;
- osl::StreamSocket mStreamSocket;
- void pairClient();
- void listenThread();
+
+ ::osl::Mutex mDataMutex;
+ ::std::vector<Communicator*> mCommunicators;
+ ::std::vector<ClientInfoInternal*> mAvailableClients;
+
void execute();
- static Transmitter *pTransmitter;
- static rtl::Reference<Listener> mListener;
};
}
diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx
new file mode 100644
index 000000000000..d4775f9264bf
--- /dev/null
+++ b/sd/source/ui/remotecontrol/Communicator.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#include <algorithm>
+#include <vector>
+
+#include <comphelper/processfactory.hxx>
+
+#include "Communicator.hxx"
+#include "ImagePreparer.hxx"
+#include "Listener.hxx"
+#include "Receiver.hxx"
+#include "RemoteServer.hxx"
+
+using namespace sd;
+using namespace std;
+using namespace com::sun::star;
+using namespace osl;
+
+Communicator::Communicator( StreamSocket &aSocket ):
+ Thread( "CommunicatorThread" ),
+ mSocket( aSocket ),
+ pTransmitter( 0 ),
+ mListener( 0 )
+{
+}
+
+Communicator::~Communicator()
+{
+}
+
+// Run as a thread
+void Communicator::execute()
+{
+ pTransmitter = new Transmitter( mSocket );
+ pTransmitter->launch();
+ Receiver aReceiver( pTransmitter );
+ try {
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager(
+ ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XFramesSupplier > xFramesSupplier( xServiceManager->createInstance(
+ "com.sun.star.frame.Desktop" ) , uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XFrame > xFrame ( xFramesSupplier->getActiveFrame(), uno::UNO_QUERY_THROW );
+ uno::Reference<presentation::XPresentationSupplier> xPS ( xFrame->getController()->getModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<presentation::XPresentation2> xPresentation(
+ xPS->getPresentation(), uno::UNO_QUERY_THROW);
+ if ( xPresentation->isRunning() )
+ {
+ presentationStarted( xPresentation->getController() );
+ }
+ }
+ catch (uno::RuntimeException &)
+ {
+ }
+
+ sal_uInt64 aRet, aRead;
+ vector<char> aBuffer;
+ vector<OString> aCommand;
+ aRead = 0;
+ while ( true )
+ {
+ aBuffer.resize( aRead + 100 );
+ aRet = mSocket.recv( &aBuffer[aRead], 100 );
+ if ( aRet == 0 )
+ {
+ break; // I.e. transmission finished.
+ }
+ aRead += aRet;
+ vector<char>::iterator aIt;
+ while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' ))
+ != aBuffer.end() )
+ {
+ sal_uInt64 aLocation = aIt - aBuffer.begin();
+
+ aCommand.push_back( OString( &(*aBuffer.begin()), aLocation ) );
+ if ( aIt == aBuffer.begin() )
+ {
+ aReceiver.parseCommand( aCommand );
+ aCommand.clear();
+ }
+ aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line
+ aRead -= (aLocation + 1);
+ }
+ }
+ // TODO: deal with transmision errors gracefully.
+ disposeListener();
+
+ pTransmitter->notifyFinished();
+ pTransmitter->join();
+ pTransmitter = NULL;
+
+ RemoteServer::removeCommunicator( this );
+}
+
+void Communicator::informListenerDestroyed()
+{
+ mListener.clear();
+}
+
+void Communicator::presentationStarted( const css::uno::Reference<
+ css::presentation::XSlideShowController > &rController )
+{
+ if ( pTransmitter )
+ {
+ mListener = rtl::Reference<Listener>( new Listener( this, pTransmitter ) );
+ mListener->init( rController );
+ }
+}
+
+void Communicator::disposeListener()
+{
+ if ( mListener.is() )
+ {
+ mListener->disposing();
+ mListener = NULL;
+ }
+}
+
+Transmitter* Communicator::getTransmitter()
+{
+ return pTransmitter;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/remotecontrol/Communicator.hxx b/sd/source/ui/remotecontrol/Communicator.hxx
new file mode 100644
index 000000000000..089fffa7b3dd
--- /dev/null
+++ b/sd/source/ui/remotecontrol/Communicator.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef _SD_IMPRESSREMOTE_COMMUNICATOR_HXX
+#define _SD_IMPRESSREMOTE_COMMUNICATOR_HXX
+
+// SERVER
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <vector>
+
+#include <osl/socket.hxx>
+#include <rtl/ref.hxx>
+#include <salhelper/thread.hxx>
+
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+
+#define CHARSET RTL_TEXTENCODING_UTF8
+namespace css = ::com::sun::star;
+
+namespace sd
+{
+
+ class Transmitter;
+ class Listener;
+ class ImagePreparer;
+
+ /** Class used for communication with one single client, dealing with all
+ * tasks specific to this client.
+ *
+ * Needs to be created, then started using launch(), disposes itself.
+ */
+ class Communicator : public salhelper::Thread
+ {
+ public:
+ Communicator( osl::StreamSocket &aSocket );
+ ~Communicator();
+
+ Transmitter* getTransmitter();
+ void presentationStarted( const css::uno::Reference<
+ css::presentation::XSlideShowController > &rController );
+ void informListenerDestroyed();
+ void disposeListener();
+
+ private:
+ void execute();
+ osl::StreamSocket mSocket;
+
+ Transmitter *pTransmitter;
+ rtl::Reference<Listener> mListener;
+ };
+}
+
+#endif // _SD_IMPRESSREMOTE_COMMUNICATOR_HXX
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/remotecontrol/Listener.cxx b/sd/source/ui/remotecontrol/Listener.cxx
index e326ea56c585..5044169606c6 100644
--- a/sd/source/ui/remotecontrol/Listener.cxx
+++ b/sd/source/ui/remotecontrol/Listener.cxx
@@ -22,9 +22,10 @@ using rtl::OString;
using rtl::OStringBuffer;
-Listener::Listener( const ::rtl::Reference<RemoteServer>& rServer, sd::Transmitter *aTransmitter )
- : ::cppu::WeakComponentImplHelper1< XSlideShowListener >( m_aMutex ),
- mServer( rServer ),
+Listener::Listener( const ::rtl::Reference<Communicator>& rCommunicator,
+ sd::Transmitter *aTransmitter ):
+ ::cppu::WeakComponentImplHelper1< XSlideShowListener >( m_aMutex ),
+ mCommunicator( rCommunicator ),
pTransmitter( NULL ),
mPreparer()
{
@@ -43,11 +44,11 @@ void Listener::init( const css::uno::Reference< css::presentation::XSlideShowCon
aController->addSlideShowListener( this );
sal_Int32 aSlides = aController->getSlideCount();
- sal_Int32 aCurrentSlide = aController->getCurrentSlideIndex();
+ sal_Int32 aCurrentSlide = aController->getCurrentSlideIndex();
OStringBuffer aBuffer;
aBuffer.append( "slideshow_started\n" )
.append( OString::valueOf( aSlides ) ).append("\n")
- .append( OString::valueOf( aCurrentSlide ) ).append( "\n\n" );
+ .append( OString::valueOf( aCurrentSlide ) ).append( "\n\n" );
pTransmitter->addMessage( aBuffer.makeStringAndClear(),
Transmitter::PRIORITY_HIGH );
@@ -146,7 +147,7 @@ void SAL_CALL Listener::disposing (void)
mController->removeSlideShowListener( this );
mController = NULL;
}
- mServer->informListenerDestroyed();
+ mCommunicator->informListenerDestroyed();
}
void SAL_CALL Listener::disposing (
diff --git a/sd/source/ui/remotecontrol/Listener.hxx b/sd/source/ui/remotecontrol/Listener.hxx
index 1a1226db82f9..3eb7f10ae7d6 100644
--- a/sd/source/ui/remotecontrol/Listener.hxx
+++ b/sd/source/ui/remotecontrol/Listener.hxx
@@ -19,7 +19,7 @@
#include <osl/socket.hxx>
#include <rtl/ref.hxx>
-#include "RemoteServer.hxx"
+#include "Communicator.hxx"
#include "Transmitter.hxx"
#include "ImagePreparer.hxx"
@@ -35,7 +35,7 @@ class Listener
public ::cppu::WeakComponentImplHelper1< css::presentation::XSlideShowListener >
{
public:
- Listener( const ::rtl::Reference<RemoteServer>& rServer, sd::Transmitter *aTransmitter );
+ Listener( const ::rtl::Reference<Communicator>& rServer, sd::Transmitter *aTransmitter );
~Listener();
void init( const css::uno::Reference< css::presentation::XSlideShowController >& aController );
@@ -65,7 +65,7 @@ public:
throw (com::sun::star::uno::RuntimeException);
private:
- rtl::Reference<RemoteServer> mServer;
+ rtl::Reference<Communicator> mCommunicator;
sd::Transmitter *pTransmitter;
css::uno::Reference< css::presentation::XSlideShowController > mController;
rtl::Reference<sd::ImagePreparer> mPreparer;
diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx
index 61284ffd6c8a..eb4adc13dc9f 100644
--- a/sd/source/ui/remotecontrol/Server.cxx
+++ b/sd/source/ui/remotecontrol/Server.cxx
@@ -25,9 +25,27 @@ using namespace std;
using namespace sd;
using namespace ::com::sun::star;
using rtl::OString;
-
-RemoteServer::RemoteServer()
-: Thread( "RemoteServerThread" ), mSocket()
+using namespace ::osl;
+
+// struct ClientInfoInternal:
+// ClientInfo
+// {
+// osl::StreamSocket mStreamSocket;
+// rtl::OUString mPin;
+// ClientInfoInternal( const rtl::OUString rName,
+// const rtl::OUString rAddress,
+// osl::StreamSocket &rSocket, rtl::OUString rPin ):
+// ClientInfo( rName, rAddress ),
+// mStreamSocket( rSocket ),
+// mPin( rPin ) {}
+// };
+
+RemoteServer::RemoteServer() :
+ Thread( "RemoteServerThread" ),
+ mSocket(),
+ mDataMutex(),
+ mCommunicators(),
+ mAvailableClients()
{
}
@@ -35,75 +53,6 @@ RemoteServer::~RemoteServer()
{
}
-// Run as a thread
-void RemoteServer::listenThread()
-{
- pTransmitter = new Transmitter( mStreamSocket );
- pTransmitter->launch();
- Receiver aReceiver( pTransmitter );
- try {
- uno::Reference< lang::XMultiServiceFactory > xServiceManager(
- ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
- uno::Reference< frame::XFramesSupplier > xFramesSupplier( xServiceManager->createInstance(
- "com.sun.star.frame.Desktop" ) , uno::UNO_QUERY_THROW );
- uno::Reference< frame::XFrame > xFrame ( xFramesSupplier->getActiveFrame(), uno::UNO_QUERY_THROW );
- uno::Reference<presentation::XPresentationSupplier> xPS ( xFrame->getController()->getModel(), uno::UNO_QUERY_THROW);
- uno::Reference<presentation::XPresentation2> xPresentation(
- xPS->getPresentation(), uno::UNO_QUERY_THROW);
- if ( xPresentation->isRunning() )
- {
- presentationStarted( xPresentation->getController() );
- }
- }
- catch (uno::RuntimeException &)
- {
- }
-
- sal_uInt64 aRet, aRead;
- vector<char> aBuffer;
- vector<OString> aCommand;
- aRead = 0;
- while ( true )
- {
- aBuffer.resize( aRead + 100 );
- aRet = mStreamSocket.recv( &aBuffer[aRead], 100 );
- if ( aRet == 0 )
- {
- break; // I.e. transmission finished.
- }
- aRead += aRet;
- vector<char>::iterator aIt;
- while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' ))
- != aBuffer.end() )
- {
- sal_uInt64 aLocation = aIt - aBuffer.begin();
-
- aCommand.push_back( OString( &(*aBuffer.begin()), aLocation ) );
- if ( aIt == aBuffer.begin() )
- {
- aReceiver.parseCommand( aCommand );
- aCommand.clear();
- }
- aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line
- aRead -= (aLocation + 1);
- }
- }
- // TODO: deal with transmision errors gracefully.
- presentationStopped();
-
- pTransmitter->notifyFinished();
- pTransmitter->join();
- pTransmitter = NULL;
- fprintf( stderr, "Finished listening\n" );
-}
-
-void RemoteServer::pairClient()
-{
- // Pairing: client sends PIN, server asks user, replies with accepted/rejected.
- // We have to wait here until the user opens the dialog via the menu,
- // typs in the pin etc.
-}
-
void RemoteServer::execute()
{
osl::SocketAddr aAddr( "0", PORT );
@@ -118,60 +67,78 @@ void RemoteServer::execute()
}
while ( true )
{
- fprintf( stderr, "Awaiting a connection.\n" );
- if ( mSocket.acceptConnection( mStreamSocket ) == osl_Socket_Error ) {
- // Socket closed or other problem
- return;
+ StreamSocket aSocket;
+ if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error ) {
+ MutexGuard aGuard( mDataMutex );
+ // FIXME: read one line in, parse the data.
+ mAvailableClients.push_back( new ClientInfoInternal( "A name",
+ "An address", aSocket, "0000" ) );
}
- fprintf( stderr, "Accepted a connection!\n" );
- listenThread();
}
}
-void RemoteServer::informListenerDestroyed()
+RemoteServer *sd::RemoteServer::spServer = NULL;
+
+void RemoteServer::setup()
{
- mListener.clear();
+ if (spServer)
+ return;
+
+ spServer = new RemoteServer();
+ spServer->launch();
}
+
void RemoteServer::presentationStarted( const css::uno::Reference<
- css::presentation::XSlideShowController > &rController )
+ css::presentation::XSlideShowController > &rController )
{
- if ( pTransmitter )
+ if ( !spServer )
+ return;
+ MutexGuard aGuard( spServer->mDataMutex );
+ for ( vector<Communicator*>::const_iterator aIt = spServer->mCommunicators.begin();
+ aIt < spServer->mCommunicators.end(); aIt++ )
{
- mListener = rtl::Reference<Listener>( new Listener( spServer, pTransmitter ) );
- mListener->init( rController );
+ (*aIt)->presentationStarted( rController );
}
}
-
void RemoteServer::presentationStopped()
{
- if ( mListener.is() )
+ if ( !spServer )
+ return;
+ MutexGuard aGuard( spServer->mDataMutex );
+ for ( vector<Communicator*>::const_iterator aIt = spServer->mCommunicators.begin();
+ aIt < spServer->mCommunicators.end(); aIt++ )
{
- mListener->disposing();
- mListener = NULL;
+ (*aIt)->disposeListener();
}
}
-RemoteServer *sd::RemoteServer::spServer = NULL;
-Transmitter *sd::RemoteServer::pTransmitter = NULL;
-rtl::Reference<Listener> sd::RemoteServer::mListener = NULL;
-
-void RemoteServer::setup()
+void RemoteServer::removeCommunicator( Communicator* mCommunicator )
{
- if (spServer)
- return;
-
- spServer = new RemoteServer();
- spServer->launch();
+ if ( !spServer )
+ return;
+ MutexGuard aGuard( spServer->mDataMutex );
+ for ( vector<Communicator*>::iterator aIt = spServer->mCommunicators.begin();
+ aIt < spServer->mCommunicators.end(); aIt++ )
+ {
+ if ( mCommunicator == *aIt )
+ {
+ spServer->mCommunicators.erase( aIt );
+ break;
+ }
+ }
}
-std::vector<ClientInfo> RemoteServer::getClients()
+std::vector<ClientInfo*> RemoteServer::getClients()
{
- std::vector<ClientInfo> aV;
- aV.push_back( ClientInfo( "A phone", "akaakaskj" ) );
- aV.push_back( ClientInfo( "B phone", "iiiiiii" ) );
- return aV;
+ if ( !spServer )
+ std::vector<ClientInfo*>();
+ MutexGuard aGuard( spServer->mDataMutex );
+ std::vector<ClientInfo*> aClients;
+ aClients.assign( spServer->mAvailableClients.begin(),
+ spServer->mAvailableClients.end() );
+ return aClients;
}
void RemoteServer::connectClient( ClientInfo aClient, rtl::OString aPin )