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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -212,6 +212,20 @@ CServer::getActivePrimarySides() const
return sides; 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 void
CServer::onInfoChanged(const CString& name, const CClientInfo& info) 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); 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 void
CServer::onScreensaver(bool activated) CServer::onScreensaver(bool activated)
{ {

View File

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

View File

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

View File

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

View File

@ -11,13 +11,6 @@
// an IPrimaryScreenReceiver* and notify it of events. // an IPrimaryScreenReceiver* and notify it of events.
class IPrimaryScreenReceiver : public IInterface { class IPrimaryScreenReceiver : public IInterface {
public: 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 // called when the screensaver is activated or deactivated
virtual void onScreensaver(bool activated) = 0; virtual void onScreensaver(bool activated) = 0;

View File

@ -43,7 +43,10 @@ public:
// activate or deactivate the screen saver // activate or deactivate the screen saver
virtual void screensaver(bool activate) = 0; 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; virtual void syncDesktop() = 0;
// accessors // accessors
@ -58,8 +61,9 @@ public:
// get the current cursor coordinates // get the current cursor coordinates
virtual void getCursorPos(SInt32& x, SInt32& y) const = 0; virtual void getCursorPos(SInt32& x, SInt32& y) const = 0;
// get the cursor center position // get the cursor center position. this is where we park the
// FIXME -- need better explanation // 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; virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
}; };

View File

@ -18,11 +18,6 @@ class IScreenEventHandler : public IInterface {
public: public:
// manipulators // 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 // called when the screensaver is activated or deactivated
virtual void onScreensaver(bool activated) = 0; virtual void onScreensaver(bool activated) = 0;

View File

@ -10,6 +10,11 @@
// notifications (indirectly) from the system. // notifications (indirectly) from the system.
class IScreenReceiver : public IInterface { class IScreenReceiver : public IInterface {
public: 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 // notify of client info change
virtual void onInfoChanged(const CClientInfo&) = 0; virtual void onInfoChanged(const CClientInfo&) = 0;

View File

@ -17,6 +17,11 @@ class IServer : public IInterface {
public: public:
// manipulators // 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 // notify of client info change
virtual void onInfoChanged(const CString& clientName, virtual void onInfoChanged(const CString& clientName,
const CClientInfo&) = 0; const CClientInfo&) = 0;