moved onError() method to IScreenReceiver from IPrimaryScreenReceiver.

also implemented onError in CClient which previously did not have
any way to handle display disconnection.
This commit is contained in:
crs 2002-07-16 16:52:26 +00:00
parent 0bfe12d6ab
commit 7c391a0f35
26 changed files with 114 additions and 98 deletions

View File

@ -27,6 +27,7 @@ CClient::CClient(const CString& clientName) :
m_screen(NULL),
m_server(NULL),
m_camp(false),
m_session(NULL),
m_active(false),
m_rejected(true)
{
@ -64,6 +65,13 @@ CClient::wasRejected() const
return m_rejected;
}
void
CClient::onError()
{
// close down session but don't wait too long
deleteSession(3.0);
}
void
CClient::onInfoChanged(const CClientInfo& info)
{
@ -144,28 +152,31 @@ CClient::run()
log((CLOG_NOTE "starting client \"%s\"", m_name.c_str()));
// start server interactions
thread = new CThread(new TMethodJob<CClient>(
{
CLock lock(&m_mutex);
m_session = new CThread(new TMethodJob<CClient>(
this, &CClient::runSession));
}
// handle events
m_screen->run();
// clean up
deleteSession(thread);
deleteSession();
log((CLOG_NOTE "stopping client \"%s\"", m_name.c_str()));
}
catch (XBase& e) {
log((CLOG_ERR "client error: %s", e.what()));
// clean up
deleteSession(thread);
deleteSession();
log((CLOG_NOTE "stopping client \"%s\"", m_name.c_str()));
CLock lock(&m_mutex);
m_rejected = false;
}
catch (XThread&) {
// clean up
deleteSession(thread);
deleteSession();
log((CLOG_NOTE "stopping client \"%s\"", m_name.c_str()));
throw;
}
@ -173,7 +184,7 @@ CClient::run()
log((CLOG_DEBUG "unknown client error"));
// clean up
deleteSession(thread);
deleteSession();
log((CLOG_NOTE "stopping client \"%s\"", m_name.c_str()));
throw;
}
@ -424,11 +435,20 @@ CClient::runSession(void*)
}
void
CClient::deleteSession(CThread* thread)
CClient::deleteSession(double timeout)
{
// get session thread object
CThread* thread;
{
CLock lock(&m_mutex);
thread = m_session;
m_session = NULL;
}
// shut it down
if (thread != NULL) {
thread->cancel();
thread->wait();
thread->wait(timeout);
delete thread;
}
}

View File

@ -39,6 +39,7 @@ public:
bool wasRejected() const;
// IScreenReceiver overrides
virtual void onError();
virtual void onInfoChanged(const CClientInfo&);
virtual bool onGrabClipboard(ClipboardID);
virtual void onClipboardChanged(ClipboardID, const CString&);
@ -47,7 +48,6 @@ public:
virtual bool open();
virtual void run();
virtual void close();
// FIXME -- can we avoid passing everything here?
virtual void enter(SInt32 xAbs, SInt32 yAbs,
UInt32 seqNum, KeyModifierMask mask,
bool forScreensaver);
@ -80,7 +80,7 @@ private:
// handle server messaging
void runSession(void*);
void deleteSession(CThread*);
void deleteSession(double timeout = -1.0);
void runServer();
CServerProxy* handshakeServer(IDataSocket*);
@ -91,6 +91,7 @@ private:
IScreenReceiver* m_server;
CNetworkAddress m_serverAddress;
bool m_camp;
CThread* m_session;
bool m_active;
bool m_rejected;
bool m_ownClipboard[kClipboardEnd];

View File

@ -206,12 +206,6 @@ CMSWindowsSecondaryScreen::getScreen() const
return m_screen;
}
void
CMSWindowsSecondaryScreen::onError()
{
// ignore
}
void
CMSWindowsSecondaryScreen::onScreensaver(bool)
{

View File

@ -33,7 +33,6 @@ public:
virtual IScreen* getScreen() const;
// IMSWindowsScreenEventHandler overrides
virtual void onError();
virtual void onScreensaver(bool activated);
virtual bool onPreDispatch(const CEvent* event);
virtual bool onEvent(CEvent* event);

View File

@ -18,13 +18,6 @@ CSecondaryScreen::~CSecondaryScreen()
// do nothing
}
bool
CSecondaryScreen::isActive() const
{
CLock lock(&m_mutex);
return m_active;
}
void
CSecondaryScreen::run()
{
@ -85,7 +78,10 @@ CSecondaryScreen::open()
}
// hide the cursor
m_active = true;
{
CLock lock(&m_mutex);
m_active = true;
}
leave();
}
@ -175,6 +171,13 @@ CSecondaryScreen::screensaver(bool activate)
getScreen()->screensaver(activate);
}
bool
CSecondaryScreen::isActive() const
{
CLock lock(&m_mutex);
return m_active;
}
void
CSecondaryScreen::getClipboard(ClipboardID id,
IClipboard* clipboard) const

View File

@ -221,6 +221,12 @@ CServerProxy::getOutputStream() const
return m_output;
}
void
CServerProxy::onError()
{
// ignore
}
void
CServerProxy::onInfoChanged(const CClientInfo& info)
{

View File

@ -34,6 +34,7 @@ public:
IOutputStream* getOutputStream() const;
// IScreenReceiver overrides
virtual void onError();
virtual void onInfoChanged(const CClientInfo&);
virtual bool onGrabClipboard(ClipboardID);
virtual void onClipboardChanged(ClipboardID, const CString& data);

View File

@ -145,13 +145,6 @@ CXWindowsSecondaryScreen::getScreen() const
return m_screen;
}
void
CXWindowsSecondaryScreen::onError()
{
// ignore
// FIXME -- forward this? to whom?
}
void
CXWindowsSecondaryScreen::onScreensaver(bool)
{
@ -273,16 +266,18 @@ CXWindowsSecondaryScreen::createWindow()
void
CXWindowsSecondaryScreen::destroyWindow()
{
CDisplayLock display(m_screen);
if (display != NULL) {
// release keys that are still pressed
releaseKeys(display);
{
CDisplayLock display(m_screen);
if (display != NULL) {
// release keys that are still pressed
releaseKeys(display);
// no longer impervious to server grabs
XTestGrabControl(display, False);
// no longer impervious to server grabs
XTestGrabControl(display, False);
// update
XSync(display, False);
// update
XSync(display, False);
}
}
// destroy window

View File

@ -31,7 +31,6 @@ public:
virtual IScreen* getScreen() const;
// IScreenEventHandler overrides
virtual void onError();
virtual void onScreensaver(bool activated);
virtual bool onPreDispatch(const CEvent* event);
virtual bool onEvent(CEvent* event);

View File

@ -656,7 +656,7 @@ CXWindowsScreen::ioErrorHandler(Display*)
// so we set it to NULL), and exit.
log((CLOG_WARN "X display has unexpectedly disconnected"));
s_screen->m_display = NULL;
s_screen->m_eventHandler->onError();
s_screen->m_receiver->onError();
log((CLOG_CRIT "quiting due to X display disconnection"));
exit(17);
}

View File

@ -16,7 +16,6 @@ public:
virtual void preDestroyWindow(HWND) = 0;
// IScreenEventHandler overrides
virtual void onError() = 0;
virtual void onScreensaver(bool activated) = 0;
virtual bool onPreDispatch(const CEvent* event) = 0;
virtual bool onEvent(CEvent* event) = 0;

View File

@ -145,12 +145,6 @@ CMSWindowsPrimaryScreen::getScreen() const
return m_screen;
}
void
CMSWindowsPrimaryScreen::onError()
{
// ignore
}
void
CMSWindowsPrimaryScreen::onScreensaver(bool activated)
{

View File

@ -27,7 +27,6 @@ public:
virtual IScreen* getScreen() const;
// IMSWindowsScreenEventHandler overrides
virtual void onError();
virtual void onScreensaver(bool activated);
virtual bool onPreDispatch(const CEvent* event);
virtual bool onEvent(CEvent* event);

View File

@ -69,6 +69,13 @@ CPrimaryClient::getToggleMask() const
return m_screen->getToggleMask();
}
void
CPrimaryClient::onError()
{
// forward to server
m_server->onError();
}
void
CPrimaryClient::onInfoChanged(const CClientInfo& info)
{
@ -79,9 +86,7 @@ CPrimaryClient::onInfoChanged(const CClientInfo& info)
bool
CPrimaryClient::onGrabClipboard(ClipboardID id)
{
bool result = m_server->onGrabClipboard(getName(), id, m_seqNum);
m_clipboardOwner[id] = result;
return result;
return m_server->onGrabClipboard(getName(), id, m_seqNum);
}
void
@ -93,9 +98,8 @@ CPrimaryClient::onClipboardChanged(ClipboardID id, const CString& data)
bool
CPrimaryClient::open()
{
// all clipboards are clean and owned by us
// all clipboards are clean
for (UInt32 i = 0; i < kClipboardEnd; ++i) {
m_clipboardOwner[i] = true;
m_clipboardDirty[i] = false;
}
@ -159,7 +163,6 @@ CPrimaryClient::grabClipboard(ClipboardID id)
m_screen->grabClipboard(id);
// clipboard is dirty (because someone else owns it now)
m_clipboardOwner[id] = false;
m_clipboardDirty[id] = true;
}

View File

@ -35,6 +35,7 @@ public:
KeyModifierMask getToggleMask() const;
// IScreenReceiver overrides
virtual void onError();
virtual void onInfoChanged(const CClientInfo&);
virtual bool onGrabClipboard(ClipboardID);
virtual void onClipboardChanged(ClipboardID, const CString&);
@ -71,7 +72,6 @@ private:
CString m_name;
UInt32 m_seqNum;
CClientInfo m_info;
bool m_clipboardOwner[kClipboardEnd]; // FIXME -- unneeded?
bool m_clipboardDirty[kClipboardEnd];
};

View File

@ -2,11 +2,10 @@
#include "IScreen.h"
#include "IScreenReceiver.h"
#include "ProtocolTypes.h"
#include "CLock.h"
#include "CThread.h"
#include "CLog.h"
// FIXME -- should be locking
//
// CPrimaryScreen
//
@ -84,7 +83,10 @@ CPrimaryScreen::open()
}
// enter the screen
enterNoWarp();
{
CLock lock(&m_mutex);
enterNoWarp();
}
// send screen info
m_receiver->onInfoChanged(info);
@ -104,6 +106,7 @@ void
CPrimaryScreen::enter(SInt32 x, SInt32 y, bool forScreensaver)
{
log((CLOG_INFO "entering primary at %d,%d%s", x, y, forScreensaver ? " for screen saver" : ""));
CLock lock(&m_mutex);
assert(m_active == true);
enterNoWarp();
@ -118,6 +121,8 @@ CPrimaryScreen::enter(SInt32 x, SInt32 y, bool forScreensaver)
void
CPrimaryScreen::enterNoWarp()
{
// note -- must be locked on entry
// not active anymore
m_active = false;
@ -135,6 +140,7 @@ bool
CPrimaryScreen::leave()
{
log((CLOG_INFO "leaving primary"));
CLock lock(&m_mutex);
assert(m_active == false);
// subclass hook
@ -187,6 +193,7 @@ CPrimaryScreen::grabClipboard(ClipboardID id)
bool
CPrimaryScreen::isActive() const
{
CLock lock(&m_mutex);
return m_active;
}

View File

@ -3,6 +3,7 @@
#include "ClipboardTypes.h"
#include "KeyTypes.h"
#include "CMutex.h"
class IClipboard;
class IScreen;
@ -146,8 +147,9 @@ private:
void enterNoWarp();
private:
// FIXME -- should have a mutex
CMutex m_mutex;
// object to notify of changes
IScreenReceiver* m_receiver;
// m_active is true if this screen has been left

View File

@ -212,6 +212,20 @@ CServer::getActivePrimarySides() const
return sides;
}
void
CServer::onError()
{
// stop all running threads but don't wait too long since some
// threads may be unable to proceed until this thread returns.
stopThreads(3.0);
// done with the HTTP server
delete m_httpServer;
m_httpServer = NULL;
// note -- we do not attempt to close down the primary screen
}
void
CServer::onInfoChanged(const CString& name, const CClientInfo& info)
{
@ -334,20 +348,6 @@ CServer::onClipboardChangedNoLock(ClipboardID id,
m_active->setClipboard(id, m_clipboards[id].m_clipboardData);
}
void
CServer::onError()
{
// stop all running threads but don't wait too long since some
// threads may be unable to proceed until this thread returns.
stopThreads(3.0);
// done with the HTTP server
delete m_httpServer;
m_httpServer = NULL;
// note -- we do not attempt to close down the primary screen
}
void
CServer::onScreensaver(bool activated)
{

View File

@ -55,12 +55,12 @@ public:
CString getPrimaryScreenName() const;
// IServer overrides
virtual void onError();
virtual void onInfoChanged(const CString&, const CClientInfo&);
virtual bool onGrabClipboard(const CString&, ClipboardID, UInt32);
virtual void onClipboardChanged(ClipboardID, UInt32, const CString&);
// IPrimaryScreenReceiver overrides
virtual void onError();
virtual void onScreensaver(bool activated);
virtual void onKeyDown(KeyID, KeyModifierMask);
virtual void onKeyUp(KeyID, KeyModifierMask);

View File

@ -132,13 +132,6 @@ CXWindowsPrimaryScreen::getScreen() const
return m_screen;
}
void
CXWindowsPrimaryScreen::onError()
{
// tell server to shutdown
m_receiver->onError();
}
void
CXWindowsPrimaryScreen::onScreensaver(bool activated)
{

View File

@ -28,7 +28,6 @@ public:
virtual IScreen* getScreen() const;
// IScreenEventHandler overrides
virtual void onError();
virtual void onScreensaver(bool activated);
virtual bool onPreDispatch(const CEvent* event);
virtual bool onEvent(CEvent* event);

View File

@ -11,13 +11,6 @@
// an IPrimaryScreenReceiver* and notify it of events.
class IPrimaryScreenReceiver : public IInterface {
public:
// called if the display is unexpectedly closing.
// called if the screen is unexpectedly closing. this implies that
// the screen is no longer usable and that the program should
// close the screen and possibly terminate.
virtual void onError() = 0;
// called when the screensaver is activated or deactivated
virtual void onScreensaver(bool activated) = 0;

View File

@ -43,7 +43,10 @@ public:
// activate or deactivate the screen saver
virtual void screensaver(bool activate) = 0;
// FIXME -- need explanation
// ensure that this thread attached with the visible desktop. this is
// mainly intended for windows which has an artificial distinction
// between desktops and a thread cannot interact with the visible
// desktop unless the thread is attached to that desktop.
virtual void syncDesktop() = 0;
// accessors
@ -58,8 +61,9 @@ public:
// get the current cursor coordinates
virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
// get the cursor center position
// FIXME -- need better explanation
// get the cursor center position. this is where we park the
// cursor to compute cursor motion deltas and should be far from
// the edges of the screen, typically the center.
virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
};

View File

@ -18,11 +18,6 @@ class IScreenEventHandler : public IInterface {
public:
// manipulators
// called if the screen is unexpectedly closing. this implies that
// the screen is no longer usable and that the program should
// close the screen and possibly terminate.
virtual void onError() = 0;
// called when the screensaver is activated or deactivated
virtual void onScreensaver(bool activated) = 0;

View File

@ -10,6 +10,11 @@
// notifications (indirectly) from the system.
class IScreenReceiver : public IInterface {
public:
// called if the screen is unexpectedly closing. this implies that
// the screen is no longer usable and that the program should
// close the screen and possibly terminate.
virtual void onError() = 0;
// notify of client info change
virtual void onInfoChanged(const CClientInfo&) = 0;

View File

@ -17,6 +17,11 @@ class IServer : public IInterface {
public:
// manipulators
// called if the screen is unexpectedly closing. this implies that
// the screen is no longer usable and that the program should
// close the screen and possibly terminate.
virtual void onError() = 0;
// notify of client info change
virtual void onInfoChanged(const CString& clientName,
const CClientInfo&) = 0;