• Main Page
  • Classes
  • Files
  • File List

CClient.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2012 Bolton Software Ltd.
00004  * Copyright (C) 2002 Chris Schoeneman
00005  * 
00006  * This package is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * found in the file COPYING that should have accompanied this file.
00009  * 
00010  * This package is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include "CClient.h"
00020 #include "CServerProxy.h"
00021 #include "CScreen.h"
00022 #include "CClipboard.h"
00023 #include "CPacketStreamFilter.h"
00024 #include "CProtocolUtil.h"
00025 #include "ProtocolTypes.h"
00026 #include "XSynergy.h"
00027 #include "IDataSocket.h"
00028 #include "ISocketFactory.h"
00029 #include "IStreamFilterFactory.h"
00030 #include "CLog.h"
00031 #include "IEventQueue.h"
00032 #include "TMethodEventJob.h"
00033 #include <cstring>
00034 #include <cstdlib>
00035 #include "CArch.h"
00036 #include "IPlatformScreen.h"
00037 #include "CCryptoStream.h"
00038 
00039 //
00040 // CClient
00041 //
00042 
00043 CEvent::Type            CClient::s_connectedEvent        = CEvent::kUnknown;
00044 CEvent::Type            CClient::s_connectionFailedEvent = CEvent::kUnknown;
00045 CEvent::Type            CClient::s_disconnectedEvent     = CEvent::kUnknown;
00046 
00047 CClient::CClient(IEventQueue* eventQueue,
00048                 const CString& name, const CNetworkAddress& address,
00049                 ISocketFactory* socketFactory,
00050                 IStreamFilterFactory* streamFilterFactory,
00051                 CScreen* screen,
00052                 const CCryptoOptions& crypto) :
00053     m_mock(false),
00054     m_name(name),
00055     m_serverAddress(address),
00056     m_socketFactory(socketFactory),
00057     m_streamFilterFactory(streamFilterFactory),
00058     m_screen(screen),
00059     m_stream(NULL),
00060     m_timer(NULL),
00061     m_server(NULL),
00062     m_ready(false),
00063     m_active(false),
00064     m_suspended(false),
00065     m_connectOnResume(false),
00066     m_eventQueue(eventQueue),
00067     m_cryptoStream(NULL),
00068     m_crypto(crypto)
00069 {
00070     assert(m_socketFactory != NULL);
00071     assert(m_screen        != NULL);
00072 
00073     // register suspend/resume event handlers
00074     m_eventQueue->adoptHandler(IScreen::getSuspendEvent(),
00075                             getEventTarget(),
00076                             new TMethodEventJob<CClient>(this,
00077                                 &CClient::handleSuspend));
00078     m_eventQueue->adoptHandler(IScreen::getResumeEvent(),
00079                             getEventTarget(),
00080                             new TMethodEventJob<CClient>(this,
00081                                 &CClient::handleResume));
00082     m_eventQueue->adoptHandler(IPlatformScreen::getGameDeviceTimingRespEvent(),
00083                             getEventTarget(),
00084                             new TMethodEventJob<CClient>(this,
00085                                 &CClient::handleGameDeviceTimingResp));
00086     m_eventQueue->adoptHandler(IPlatformScreen::getGameDeviceFeedbackEvent(),
00087                             getEventTarget(),
00088                             new TMethodEventJob<CClient>(this,
00089                                 &CClient::handleGameDeviceFeedback));
00090 }
00091 
00092 CClient::~CClient()
00093 {
00094     if (m_mock) {
00095         return;
00096     }
00097 
00098     m_eventQueue->removeHandler(IScreen::getSuspendEvent(),
00099                               getEventTarget());
00100     m_eventQueue->removeHandler(IScreen::getResumeEvent(),
00101                               getEventTarget());
00102 
00103     cleanupTimer();
00104     cleanupScreen();
00105     cleanupConnecting();
00106     cleanupConnection();
00107     delete m_socketFactory;
00108     delete m_streamFilterFactory;
00109 }
00110 
00111 void
00112 CClient::connect()
00113 {
00114     if (m_stream != NULL) {
00115         return;
00116     }
00117     if (m_suspended) {
00118         m_connectOnResume = true;
00119         return;
00120     }
00121 
00122     try {
00123         // resolve the server hostname.  do this every time we connect
00124         // in case we couldn't resolve the address earlier or the address
00125         // has changed (which can happen frequently if this is a laptop
00126         // being shuttled between various networks).  patch by Brent
00127         // Priddy.
00128         m_serverAddress.resolve();
00129         
00130         // m_serverAddress will be null if the hostname address is not reolved
00131         if (m_serverAddress.getAddress() != NULL) {
00132           // to help users troubleshoot, show server host name (issue: 60)
00133           LOG((CLOG_NOTE "connecting to '%s': %s:%i", 
00134           m_serverAddress.getHostname().c_str(),
00135           ARCH->addrToString(m_serverAddress.getAddress()).c_str(),
00136           m_serverAddress.getPort()));
00137         }
00138 
00139         // create the socket
00140         IDataSocket* socket = m_socketFactory->create();
00141 
00142         // filter socket messages, including a packetizing filter
00143         m_stream = socket;
00144         if (m_streamFilterFactory != NULL) {
00145             m_stream = m_streamFilterFactory->create(m_stream, true);
00146         }
00147         m_stream = new CPacketStreamFilter(m_stream, true);
00148 
00149         if (m_crypto.m_mode != kDisabled) {
00150             m_cryptoStream = new CCryptoStream(
00151                 EVENTQUEUE, m_stream, m_crypto, true);
00152             m_stream = m_cryptoStream;
00153         }
00154 
00155         // connect
00156         LOG((CLOG_DEBUG1 "connecting to server"));
00157         setupConnecting();
00158         setupTimer();
00159         socket->connect(m_serverAddress);
00160     }
00161     catch (XBase& e) {
00162         cleanupTimer();
00163         cleanupConnecting();
00164         delete m_stream;
00165         m_stream = NULL;
00166         LOG((CLOG_DEBUG1 "connection failed"));
00167         sendConnectionFailedEvent(e.what());
00168         return;
00169     }
00170 }
00171 
00172 void
00173 CClient::disconnect(const char* msg)
00174 {
00175     m_connectOnResume = false;
00176     cleanupTimer();
00177     cleanupScreen();
00178     cleanupConnecting();
00179     cleanupConnection();
00180     if (msg != NULL) {
00181         sendConnectionFailedEvent(msg);
00182     }
00183     else {
00184         sendEvent(getDisconnectedEvent(), NULL);
00185     }
00186 }
00187 
00188 void
00189 CClient::handshakeComplete()
00190 {
00191     m_ready = true;
00192     m_screen->enable();
00193     sendEvent(getConnectedEvent(), NULL);
00194 }
00195 
00196 void
00197 CClient::setDecryptIv(const UInt8* iv)
00198 {
00199     if (m_cryptoStream != NULL) {
00200         m_cryptoStream->setDecryptIv(iv);
00201     }
00202 }
00203 
00204 bool
00205 CClient::isConnected() const
00206 {
00207     return (m_server != NULL);
00208 }
00209 
00210 bool
00211 CClient::isConnecting() const
00212 {
00213     return (m_timer != NULL);
00214 }
00215 
00216 CNetworkAddress
00217 CClient::getServerAddress() const
00218 {
00219     return m_serverAddress;
00220 }
00221 
00222 CEvent::Type
00223 CClient::getConnectedEvent()
00224 {
00225     return EVENTQUEUE->registerTypeOnce(s_connectedEvent,
00226                             "CClient::connected");
00227 }
00228 
00229 CEvent::Type
00230 CClient::getConnectionFailedEvent()
00231 {
00232     return EVENTQUEUE->registerTypeOnce(s_connectionFailedEvent,
00233                             "CClient::failed");
00234 }
00235 
00236 CEvent::Type
00237 CClient::getDisconnectedEvent()
00238 {
00239     return EVENTQUEUE->registerTypeOnce(s_disconnectedEvent,
00240                             "CClient::disconnected");
00241 }
00242 
00243 void*
00244 CClient::getEventTarget() const
00245 {
00246     return m_screen->getEventTarget();
00247 }
00248 
00249 bool
00250 CClient::getClipboard(ClipboardID id, IClipboard* clipboard) const
00251 {
00252     return m_screen->getClipboard(id, clipboard);
00253 }
00254 
00255 void
00256 CClient::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
00257 {
00258     m_screen->getShape(x, y, w, h);
00259 }
00260 
00261 void
00262 CClient::getCursorPos(SInt32& x, SInt32& y) const
00263 {
00264     m_screen->getCursorPos(x, y);
00265 }
00266 
00267 void
00268 CClient::enter(SInt32 xAbs, SInt32 yAbs, UInt32, KeyModifierMask mask, bool)
00269 {
00270     m_active = true;
00271     m_screen->mouseMove(xAbs, yAbs);
00272     m_screen->enter(mask);
00273 }
00274 
00275 bool
00276 CClient::leave()
00277 {
00278     m_screen->leave();
00279 
00280     m_active = false;
00281 
00282     // send clipboards that we own and that have changed
00283     for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
00284         if (m_ownClipboard[id]) {
00285             sendClipboard(id);
00286         }
00287     }
00288 
00289     return true;
00290 }
00291 
00292 void
00293 CClient::setClipboard(ClipboardID id, const IClipboard* clipboard)
00294 {
00295     m_screen->setClipboard(id, clipboard);
00296     m_ownClipboard[id]  = false;
00297     m_sentClipboard[id] = false;
00298 }
00299 
00300 void
00301 CClient::grabClipboard(ClipboardID id)
00302 {
00303     m_screen->grabClipboard(id);
00304     m_ownClipboard[id]  = false;
00305     m_sentClipboard[id] = false;
00306 }
00307 
00308 void
00309 CClient::setClipboardDirty(ClipboardID, bool)
00310 {
00311     assert(0 && "shouldn't be called");
00312 }
00313 
00314 void
00315 CClient::keyDown(KeyID id, KeyModifierMask mask, KeyButton button)
00316 {
00317     m_screen->keyDown(id, mask, button);
00318 }
00319 
00320 void
00321 CClient::keyRepeat(KeyID id, KeyModifierMask mask,
00322                 SInt32 count, KeyButton button)
00323 {
00324     m_screen->keyRepeat(id, mask, count, button);
00325 }
00326 
00327 void
00328 CClient::keyUp(KeyID id, KeyModifierMask mask, KeyButton button)
00329 {
00330     m_screen->keyUp(id, mask, button);
00331 }
00332 
00333 void
00334 CClient::mouseDown(ButtonID id)
00335 {
00336     m_screen->mouseDown(id);
00337 }
00338 
00339 void
00340 CClient::mouseUp(ButtonID id)
00341 {
00342     m_screen->mouseUp(id);
00343 }
00344 
00345 void
00346 CClient::mouseMove(SInt32 x, SInt32 y)
00347 {
00348     m_screen->mouseMove(x, y);
00349 }
00350 
00351 void
00352 CClient::mouseRelativeMove(SInt32 dx, SInt32 dy)
00353 {
00354     m_screen->mouseRelativeMove(dx, dy);
00355 }
00356 
00357 void
00358 CClient::mouseWheel(SInt32 xDelta, SInt32 yDelta)
00359 {
00360     m_screen->mouseWheel(xDelta, yDelta);
00361 }
00362 
00363 void
00364 CClient::screensaver(bool activate)
00365 {
00366     m_screen->screensaver(activate);
00367 }
00368 
00369 void
00370 CClient::resetOptions()
00371 {
00372     m_screen->resetOptions();
00373 }
00374 
00375 void
00376 CClient::setOptions(const COptionsList& options)
00377 {
00378     m_screen->setOptions(options);
00379 }
00380 
00381 void
00382 CClient::gameDeviceButtons(GameDeviceID id, GameDeviceButton buttons)
00383 {
00384     m_screen->gameDeviceButtons(id, buttons);
00385 }
00386 
00387 void
00388 CClient::gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2)
00389 {
00390     m_screen->gameDeviceSticks(id, x1, y1, x2, y2);
00391 }
00392 
00393 void
00394 CClient::gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2)
00395 {
00396     m_screen->gameDeviceTriggers(id, t1, t2);
00397 }
00398 
00399 void
00400 CClient::gameDeviceTimingReq()
00401 {
00402     m_screen->gameDeviceTimingReq();
00403 }
00404 
00405 CString
00406 CClient::getName() const
00407 {
00408     return m_name;
00409 }
00410 
00411 void
00412 CClient::sendClipboard(ClipboardID id)
00413 {
00414     // note -- m_mutex must be locked on entry
00415     assert(m_screen != NULL);
00416     assert(m_server != NULL);
00417 
00418     // get clipboard data.  set the clipboard time to the last
00419     // clipboard time before getting the data from the screen
00420     // as the screen may detect an unchanged clipboard and
00421     // avoid copying the data.
00422     CClipboard clipboard;
00423     if (clipboard.open(m_timeClipboard[id])) {
00424         clipboard.close();
00425     }
00426     m_screen->getClipboard(id, &clipboard);
00427 
00428     // check time
00429     if (m_timeClipboard[id] == 0 ||
00430         clipboard.getTime() != m_timeClipboard[id]) {
00431         // save new time
00432         m_timeClipboard[id] = clipboard.getTime();
00433 
00434         // marshall the data
00435         CString data = clipboard.marshall();
00436 
00437         // save and send data if different or not yet sent
00438         if (!m_sentClipboard[id] || data != m_dataClipboard[id]) {
00439             m_sentClipboard[id] = true;
00440             m_dataClipboard[id] = data;
00441             m_server->onClipboardChanged(id, &clipboard);
00442         }
00443     }
00444 }
00445 
00446 void
00447 CClient::sendEvent(CEvent::Type type, void* data)
00448 {
00449     m_eventQueue->addEvent(CEvent(type, getEventTarget(), data));
00450 }
00451 
00452 void
00453 CClient::sendConnectionFailedEvent(const char* msg)
00454 {
00455     CFailInfo* info = new CFailInfo(msg);
00456     info->m_retry = true;
00457     CEvent event(getConnectionFailedEvent(), getEventTarget(), info, CEvent::kDontFreeData);
00458     m_eventQueue->addEvent(event);
00459 }
00460 
00461 void
00462 CClient::setupConnecting()
00463 {
00464     assert(m_stream != NULL);
00465 
00466     m_eventQueue->adoptHandler(IDataSocket::getConnectedEvent(),
00467                             m_stream->getEventTarget(),
00468                             new TMethodEventJob<CClient>(this,
00469                                 &CClient::handleConnected));
00470     m_eventQueue->adoptHandler(IDataSocket::getConnectionFailedEvent(),
00471                             m_stream->getEventTarget(),
00472                             new TMethodEventJob<CClient>(this,
00473                                 &CClient::handleConnectionFailed));
00474 }
00475 
00476 void
00477 CClient::setupConnection()
00478 {
00479     assert(m_stream != NULL);
00480 
00481     m_eventQueue->adoptHandler(ISocket::getDisconnectedEvent(),
00482                             m_stream->getEventTarget(),
00483                             new TMethodEventJob<CClient>(this,
00484                                 &CClient::handleDisconnected));
00485     m_eventQueue->adoptHandler(m_stream->getInputReadyEvent(),
00486                             m_stream->getEventTarget(),
00487                             new TMethodEventJob<CClient>(this,
00488                                 &CClient::handleHello));
00489     m_eventQueue->adoptHandler(m_stream->getOutputErrorEvent(),
00490                             m_stream->getEventTarget(),
00491                             new TMethodEventJob<CClient>(this,
00492                                 &CClient::handleOutputError));
00493     m_eventQueue->adoptHandler(m_stream->getInputShutdownEvent(),
00494                             m_stream->getEventTarget(),
00495                             new TMethodEventJob<CClient>(this,
00496                                 &CClient::handleDisconnected));
00497     m_eventQueue->adoptHandler(m_stream->getOutputShutdownEvent(),
00498                             m_stream->getEventTarget(),
00499                             new TMethodEventJob<CClient>(this,
00500                                 &CClient::handleDisconnected));
00501 }
00502 
00503 void
00504 CClient::setupScreen()
00505 {
00506     assert(m_server == NULL);
00507 
00508     m_ready  = false;
00509     m_server = new CServerProxy(this, m_stream, m_eventQueue);
00510     m_eventQueue->adoptHandler(IScreen::getShapeChangedEvent(),
00511                             getEventTarget(),
00512                             new TMethodEventJob<CClient>(this,
00513                                 &CClient::handleShapeChanged));
00514     m_eventQueue->adoptHandler(IScreen::getClipboardGrabbedEvent(),
00515                             getEventTarget(),
00516                             new TMethodEventJob<CClient>(this,
00517                                 &CClient::handleClipboardGrabbed));
00518 }
00519 
00520 void
00521 CClient::setupTimer()
00522 {
00523     assert(m_timer == NULL);
00524 
00525     m_timer = m_eventQueue->newOneShotTimer(15.0, NULL);
00526     m_eventQueue->adoptHandler(CEvent::kTimer, m_timer,
00527                             new TMethodEventJob<CClient>(this,
00528                                 &CClient::handleConnectTimeout));
00529 }
00530 
00531 void
00532 CClient::cleanupConnecting()
00533 {
00534     if (m_stream != NULL) {
00535         m_eventQueue->removeHandler(IDataSocket::getConnectedEvent(),
00536                             m_stream->getEventTarget());
00537         m_eventQueue->removeHandler(IDataSocket::getConnectionFailedEvent(),
00538                             m_stream->getEventTarget());
00539     }
00540 }
00541 
00542 void
00543 CClient::cleanupConnection()
00544 {
00545     if (m_stream != NULL) {
00546         m_eventQueue->removeHandler(m_stream->getInputReadyEvent(),
00547                             m_stream->getEventTarget());
00548         m_eventQueue->removeHandler(m_stream->getOutputErrorEvent(),
00549                             m_stream->getEventTarget());
00550         m_eventQueue->removeHandler(m_stream->getInputShutdownEvent(),
00551                             m_stream->getEventTarget());
00552         m_eventQueue->removeHandler(m_stream->getOutputShutdownEvent(),
00553                             m_stream->getEventTarget());
00554         m_eventQueue->removeHandler(ISocket::getDisconnectedEvent(),
00555                             m_stream->getEventTarget());
00556         delete m_stream;
00557         m_stream = NULL;
00558     }
00559 }
00560 
00561 void
00562 CClient::cleanupScreen()
00563 {
00564     if (m_server != NULL) {
00565         if (m_ready) {
00566             m_screen->disable();
00567             m_ready = false;
00568         }
00569         m_eventQueue->removeHandler(IScreen::getShapeChangedEvent(),
00570                             getEventTarget());
00571         m_eventQueue->removeHandler(IScreen::getClipboardGrabbedEvent(),
00572                             getEventTarget());
00573         delete m_server;
00574         m_server = NULL;
00575     }
00576 }
00577 
00578 void
00579 CClient::cleanupTimer()
00580 {
00581     if (m_timer != NULL) {
00582         m_eventQueue->removeHandler(CEvent::kTimer, m_timer);
00583         m_eventQueue->deleteTimer(m_timer);
00584         m_timer = NULL;
00585     }
00586 }
00587 
00588 void
00589 CClient::handleConnected(const CEvent&, void*)
00590 {
00591     LOG((CLOG_DEBUG1 "connected;  wait for hello"));
00592     cleanupConnecting();
00593     setupConnection();
00594 
00595     // reset clipboard state
00596     for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
00597         m_ownClipboard[id]  = false;
00598         m_sentClipboard[id] = false;
00599         m_timeClipboard[id] = 0;
00600     }
00601 }
00602 
00603 void
00604 CClient::handleConnectionFailed(const CEvent& event, void*)
00605 {
00606     IDataSocket::CConnectionFailedInfo* info =
00607         reinterpret_cast<IDataSocket::CConnectionFailedInfo*>(event.getData());
00608 
00609     cleanupTimer();
00610     cleanupConnecting();
00611     delete m_stream;
00612     m_stream = NULL;
00613     LOG((CLOG_DEBUG1 "connection failed"));
00614     sendConnectionFailedEvent(info->m_what.c_str());
00615     delete info;
00616 }
00617 
00618 void
00619 CClient::handleConnectTimeout(const CEvent&, void*)
00620 {
00621     cleanupTimer();
00622     cleanupConnecting();
00623     cleanupConnection();
00624     delete m_stream;
00625     m_stream = NULL;
00626     LOG((CLOG_DEBUG1 "connection timed out"));
00627     sendConnectionFailedEvent("Timed out");
00628 }
00629 
00630 void
00631 CClient::handleOutputError(const CEvent&, void*)
00632 {
00633     cleanupTimer();
00634     cleanupScreen();
00635     cleanupConnection();
00636     LOG((CLOG_WARN "error sending to server"));
00637     sendEvent(getDisconnectedEvent(), NULL);
00638 }
00639 
00640 void
00641 CClient::handleDisconnected(const CEvent&, void*)
00642 {
00643     cleanupTimer();
00644     cleanupScreen();
00645     cleanupConnection();
00646     LOG((CLOG_DEBUG1 "disconnected"));
00647     sendEvent(getDisconnectedEvent(), NULL);
00648 }
00649 
00650 void
00651 CClient::handleShapeChanged(const CEvent&, void*)
00652 {
00653     LOG((CLOG_DEBUG "resolution changed"));
00654     m_server->onInfoChanged();
00655 }
00656 
00657 void
00658 CClient::handleClipboardGrabbed(const CEvent& event, void*)
00659 {
00660     const IScreen::CClipboardInfo* info =
00661         reinterpret_cast<const IScreen::CClipboardInfo*>(event.getData());
00662 
00663     // grab ownership
00664     m_server->onGrabClipboard(info->m_id);
00665 
00666     // we now own the clipboard and it has not been sent to the server
00667     m_ownClipboard[info->m_id]  = true;
00668     m_sentClipboard[info->m_id] = false;
00669     m_timeClipboard[info->m_id] = 0;
00670 
00671     // if we're not the active screen then send the clipboard now,
00672     // otherwise we'll wait until we leave.
00673     if (!m_active) {
00674         sendClipboard(info->m_id);
00675     }
00676 }
00677 
00678 void
00679 CClient::handleHello(const CEvent&, void*)
00680 {
00681     SInt16 major, minor;
00682     if (!CProtocolUtil::readf(m_stream, kMsgHello, &major, &minor)) {
00683         sendConnectionFailedEvent("Protocol error from server");
00684         cleanupTimer();
00685         cleanupConnection();
00686         return;
00687     }
00688 
00689     // check versions
00690     LOG((CLOG_DEBUG1 "got hello version %d.%d", major, minor));
00691     if (major < kProtocolMajorVersion ||
00692         (major == kProtocolMajorVersion && minor < kProtocolMinorVersion)) {
00693         sendConnectionFailedEvent(XIncompatibleClient(major, minor).what());
00694         cleanupTimer();
00695         cleanupConnection();
00696         return;
00697     }
00698 
00699     // say hello back
00700     LOG((CLOG_DEBUG1 "say hello version %d.%d", kProtocolMajorVersion, kProtocolMinorVersion));
00701     CProtocolUtil::writef(m_stream, kMsgHelloBack,
00702                             kProtocolMajorVersion,
00703                             kProtocolMinorVersion, &m_name);
00704 
00705     // now connected but waiting to complete handshake
00706     setupScreen();
00707     cleanupTimer();
00708 
00709     // make sure we process any remaining messages later.  we won't
00710     // receive another event for already pending messages so we fake
00711     // one.
00712     if (m_stream->isReady()) {
00713         m_eventQueue->addEvent(CEvent(m_stream->getInputReadyEvent(),
00714                             m_stream->getEventTarget()));
00715     }
00716 }
00717 
00718 void
00719 CClient::handleSuspend(const CEvent&, void*)
00720 {
00721     LOG((CLOG_INFO "suspend"));
00722     m_suspended       = true;
00723     bool wasConnected = isConnected();
00724     disconnect(NULL);
00725     m_connectOnResume = wasConnected;
00726 }
00727 
00728 void
00729 CClient::handleResume(const CEvent&, void*)
00730 {
00731     LOG((CLOG_INFO "resume"));
00732     m_suspended = false;
00733     if (m_connectOnResume) {
00734         m_connectOnResume = false;
00735         connect();
00736     }
00737 }
00738 
00739 void
00740 CClient::handleGameDeviceTimingResp(const CEvent& event, void*)
00741 {
00742     IPlatformScreen::CGameDeviceTimingRespInfo* info =
00743         reinterpret_cast<IPlatformScreen::CGameDeviceTimingRespInfo*>(event.getData());
00744 
00745     m_server->onGameDeviceTimingResp(info->m_freq);
00746 }
00747 
00748 void
00749 CClient::handleGameDeviceFeedback(const CEvent& event, void*)
00750 {
00751     IPlatformScreen::CGameDeviceFeedbackInfo* info =
00752         reinterpret_cast<IPlatformScreen::CGameDeviceFeedbackInfo*>(event.getData());
00753 
00754     m_server->onGameDeviceFeedback(info->m_id, info->m_m1, info->m_m2);
00755 }

Generated on Fri May 24 2013 00:00:03 for Synergy by  doxygen 1.7.1