CInputFilter::EFilterStatus CInputFilter::CKeystrokeCondition::match(CEvent& event, void*, EActionMode& outMode) { // check for hotkey events CEvent::Type type = event.getType(); if (type == IPrimaryScreen::getHotKeyDownEvent()) { outMode = kModeTurnOn; } else if (type == IPrimaryScreen::getHotKeyUpEvent()) { outMode = kModeTurnOff; } else { return kNoMatch; } // check if it's our hotkey IPrimaryScreen::CHotKeyInfo* kinfo = reinterpret_cast<IPlatformScreen::CHotKeyInfo*>(event.getData()); if (kinfo->m_id != m_id) { return kNoMatch; } // convert event type for toggled conditions if (getActionMode() != kModePass) { if (type != IPlatformScreen::getHotKeyDownEvent()) { return kDiscard; } outMode = getActionMode(); } return kMatch; }
CInputFilter::EFilterStatus CInputFilter::CMouseButtonCondition::match(const CEvent& event) { static const KeyModifierMask s_ignoreMask = KeyModifierAltGr | KeyModifierCapsLock | KeyModifierNumLock | KeyModifierScrollLock; EFilterStatus status; // check for hotkey events CEvent::Type type = event.getType(); if (type == IPrimaryScreen::getButtonDownEvent()) { status = kActivate; } else if (type == IPrimaryScreen::getButtonUpEvent()) { status = kDeactivate; } else { return kNoMatch; } // check if it's the right button and modifiers. ignore modifiers // that cannot be combined with a mouse button. IPlatformScreen::CButtonInfo* minfo = reinterpret_cast<IPlatformScreen::CButtonInfo*>(event.getData()); if (minfo->m_button != m_button || (minfo->m_mask & ~s_ignoreMask) != m_mask) { return kNoMatch; } return status; }
void CInputFilter::sendEvent(CEvent& event) { CEvent::Type type = event.getType(); // process keyboard modifiers here if (type == IPlatformScreen::getKeyDownEvent() || type == IPlatformScreen::getKeyUpEvent() || type == IPlatformScreen::getKeyRepeatEvent()) { // get CKeyInfo from event IPlatformScreen::CKeyInfo* kinfo = reinterpret_cast<IPlatformScreen::CKeyInfo*>(event.getData()); // save mask m_lastMask = kinfo->m_mask; // prepare new mask KeyModifierMask newMask = kinfo->m_mask; updateModifiers(); newMask &= ~m_clearMask; newMask |= m_modifierMask; // set new mask kinfo->m_mask = newMask; } // add event to eventqueue EVENTQUEUE->addEvent(event); }
CInputFilter::EFilterStatus CInputFilter::CKeystrokeCondition::match(const CEvent& event) { EFilterStatus status; // check for hotkey events CEvent::Type type = event.getType(); if (type == IPrimaryScreen::getHotKeyDownEvent()) { status = kActivate; } else if (type == IPrimaryScreen::getHotKeyUpEvent()) { status = kDeactivate; } else { return kNoMatch; } // check if it's our hotkey IPrimaryScreen::CHotKeyInfo* kinfo = reinterpret_cast<IPlatformScreen::CHotKeyInfo*>(event.getData()); if (kinfo->m_id != m_id) { return kNoMatch; } return status; }
void CClient::handleGameDeviceTimingResp(const CEvent& event, void*) { IPlatformScreen::CGameDeviceTimingRespInfo* info = reinterpret_cast<IPlatformScreen::CGameDeviceTimingRespInfo*>(event.getData()); m_server->onGameDeviceTimingResp(info->m_freq); }
void CClient::handleGameDeviceFeedback(const CEvent& event, void*) { IPlatformScreen::CGameDeviceFeedbackInfo* info = reinterpret_cast<IPlatformScreen::CGameDeviceFeedbackInfo*>(event.getData()); m_server->onGameDeviceFeedback(info->m_id, info->m_m1, info->m_m2); }
CInputFilter::EFilterStatus CInputFilter::CScreenConnectedCondition::match(const CEvent& event) { if (event.getType() == CServer::getConnectedEvent()) { CServer::CScreenConnectedInfo* info = reinterpret_cast<CServer::CScreenConnectedInfo*>(event.getData()); if (m_screen == info->m_screen || m_screen.empty()) { return kActivate; } } return kNoMatch; }
void CClient::handleConnectionFailed(const CEvent& event, void*) { IDataSocket::CConnectionFailedInfo* info = reinterpret_cast<IDataSocket::CConnectionFailedInfo*>(event.getData()); cleanupTimer(); cleanupConnecting(); delete m_stream; m_stream = NULL; LOG((CLOG_DEBUG1 "connection failed")); sendConnectionFailedEvent(info->m_what); }
void CEvent::deleteData(const CEvent& event) { switch (event.getType()) { case kUnknown: case kQuit: case kSystem: case kTimer: break; default: free(event.getData()); break; } }
void CInputFilter::handleEvent(const CEvent& event, void* arg) { // get a modifiable copy of this event. // set target to us, set kDontFreeData and kDeliverImmediately because the // original event will be destroyed after this method exits. CEvent evt(event.getType(), this, event.getData(), event.getFlags() | CEvent::kDontFreeData | CEvent::kDeliverImmediately); // clear dirty flag m_dirtyFlag = kNotDirty; EActionMode actionMode = kModePass; // match event against filter rules and perform actions for (CRuleList::iterator rule = m_ruleList.begin(); rule != m_ruleList.end(); ++rule) { EFilterStatus conditionStatus; EFilterStatus actionStatus; conditionStatus = rule->first->match(evt, arg, actionMode); if (conditionStatus == kDiscard) { return; } else if (conditionStatus == kNoMatch) { continue; } actionStatus = rule->second->perform(evt, arg, actionMode); if (actionStatus == kDiscard) { // discard event return; } else if (actionStatus == kNotHandled) { continue; } else if (actionStatus == kUpdateModifiers) { updateModifiers(); return; } // if we got here then the rule has matched and action returned // kHandled, so send the event. break; } sendEvent(evt); }
DataType getEventData() const { if (!m_lastEvent) throw exception::CNullReference("getEventData, no event available"); try { CEvent<DataType> evt = dynamic_cast<CEvent<DataType> & >(*m_lastEvent); return evt.getData(); } catch (std::bad_cast& bc) { std::string s = "getEventData : "; s += bc.what(); throw exception::CBadConversion(s, boost::lexical_cast<std::string>(m_lastEvent->getId())); } }
void COSXScreen::handleConfirmSleep(const CEvent& event, void*) { long messageArg = (long)event.getData(); if (messageArg != 0) { CLock lock(m_pmMutex); if (m_pmRootPort != 0) { // deliver suspend event immediately. m_events->addEvent(CEvent(m_events->forIScreen().suspend(), getEventTarget(), NULL, CEvent::kDeliverImmediately)); LOG((CLOG_DEBUG "system will sleep")); IOAllowPowerChange(m_pmRootPort, messageArg); } } }
void CEvent::deleteData(const CEvent& event) { switch (event.getType()) { case kUnknown: case kQuit: case kSystem: case kTimer: break; default: if ((event.getFlags() & kDontFreeData) == 0) { free(event.getData()); delete event.getDataObject(); } break; } }
void CClientApp::handleClientFailed(const CEvent& e, void*) { CClient::CFailInfo* info = reinterpret_cast<CClient::CFailInfo*>(e.getData()); updateStatus(CString("Failed to connect to server: ") + info->m_what); if (!args().m_restartable || !info->m_retry) { LOG((CLOG_ERR "failed to connect to server: %s", info->m_what.c_str())); EVENTQUEUE->addEvent(CEvent(CEvent::kQuit)); } else { LOG((CLOG_WARN "failed to connect to server: %s", info->m_what.c_str())); if (!m_suspended) { scheduleClientRestart(nextRestartTimeout()); } } delete info; }
void CInputFilter::CSwitchToScreenAction::perform(const CEvent& event) { // pick screen name. if m_screen is empty then use the screen from // event if it has one. CString screen = m_screen; if (screen.empty() && event.getType() == CServer::getConnectedEvent()) { CServer::CScreenConnectedInfo* info = reinterpret_cast<CServer::CScreenConnectedInfo*>(event.getData()); screen = info->m_screen; } // send event CServer::CSwitchToScreenInfo* info = CServer::CSwitchToScreenInfo::alloc(screen); EVENTQUEUE->addEvent(CEvent(CServer::getSwitchToScreenEvent(), event.getTarget(), info, CEvent::kDeliverImmediately)); }
void CClient::handleClipboardGrabbed(const CEvent& event, void*) { const IScreen::CClipboardInfo* info = reinterpret_cast<const IScreen::CClipboardInfo*>(event.getData()); // grab ownership m_server->onGrabClipboard(info->m_id); // we now own the clipboard and it has not been sent to the server m_ownClipboard[info->m_id] = true; m_sentClipboard[info->m_id] = false; m_timeClipboard[info->m_id] = 0; // if we're not the active screen then send the clipboard now, // otherwise we'll wait until we leave. if (!m_active) { sendClipboard(info->m_id); } }
void CInputFilter::handleEvent(const CEvent& event, void*) { // copy event and adjust target CEvent myEvent(event.getType(), this, event.getData(), event.getFlags() | CEvent::kDontFreeData | CEvent::kDeliverImmediately); // let each rule try to match the event until one does for (CRuleList::iterator rule = m_ruleList.begin(); rule != m_ruleList.end(); ++rule) { if (rule->handleEvent(myEvent)) { // handled return; } } // not handled so pass through EVENTQUEUE->addEvent(myEvent); }
CInputFilter::EFilterStatus CInputFilter::CMouseButtonCondition::match(CEvent& event, void*, EActionMode& outMode) { // check for hotkey events bool down; CEvent::Type type = event.getType(); if (type == IPrimaryScreen::getButtonDownEvent()) { outMode = kModeTurnOn; down = true; } else if (type == IPrimaryScreen::getButtonUpEvent()) { outMode = kModeTurnOff; down = false; } else { return kNoMatch; } // check if it's the right button and modifiers IPlatformScreen::CButtonInfo* minfo = reinterpret_cast<IPlatformScreen::CButtonInfo*>(event.getData()); if (minfo->m_button != m_button || getLastMask() != m_mask) { return kNoMatch; } // convert event type for toggled conditions if (getActionMode() != kModePass) { if (type != IPlatformScreen::getButtonDownEvent()) { return kDiscard; } outMode = getActionMode(); } setClearMask(down ? m_mask : 0); return kMatch; }
void CClient::handleFileChunkSending(const CEvent& event, void*) { sendFileChunk(event.getData()); }
void COSXScreen::handleSystemEvent(const CEvent& event, void*) { EventRef* carbonEvent = reinterpret_cast<EventRef*>(event.getData()); assert(carbonEvent != NULL); UInt32 eventClass = GetEventClass(*carbonEvent); switch (eventClass) { case kEventClassMouse: switch (GetEventKind(*carbonEvent)) { case kSynergyEventMouseScroll: { OSStatus r; long xScroll; long yScroll; // get scroll amount r = GetEventParameter(*carbonEvent, kSynergyMouseScrollAxisX, typeLongInteger, NULL, sizeof(xScroll), NULL, &xScroll); if (r != noErr) { xScroll = 0; } r = GetEventParameter(*carbonEvent, kSynergyMouseScrollAxisY, typeLongInteger, NULL, sizeof(yScroll), NULL, &yScroll); if (r != noErr) { yScroll = 0; } if (xScroll != 0 || yScroll != 0) { onMouseWheel(-mapScrollWheelToSynergy(xScroll), mapScrollWheelToSynergy(yScroll)); } } } break; case kEventClassKeyboard: switch (GetEventKind(*carbonEvent)) { case kEventHotKeyPressed: case kEventHotKeyReleased: onHotKey(*carbonEvent); break; } break; case kEventClassWindow: SendEventToWindow(*carbonEvent, m_userInputWindow); switch (GetEventKind(*carbonEvent)) { case kEventWindowActivated: LOG((CLOG_DEBUG1 "window activated")); break; case kEventWindowDeactivated: LOG((CLOG_DEBUG1 "window deactivated")); break; case kEventWindowFocusAcquired: LOG((CLOG_DEBUG1 "focus acquired")); break; case kEventWindowFocusRelinquish: LOG((CLOG_DEBUG1 "focus released")); break; } break; default: SendEventToEventTarget(*carbonEvent, GetEventDispatcherTarget()); break; } }
void COSXScreen::handleSystemEvent(const CEvent& event, void*) { EventRef* carbonEvent = reinterpret_cast<EventRef*>(event.getData()); assert(carbonEvent != NULL); UInt32 eventClass = GetEventClass(*carbonEvent); switch (eventClass) { case kEventClassMouse: switch (GetEventKind(*carbonEvent)) { case kEventMouseDown: { UInt16 myButton; GetEventParameter(*carbonEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(myButton), NULL, &myButton); onMouseButton(true, myButton); break; } case kEventMouseUp: { UInt16 myButton; GetEventParameter(*carbonEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(myButton), NULL, &myButton); onMouseButton(false, myButton); break; } case kEventMouseDragged: case kEventMouseMoved: { HIPoint point; GetEventParameter(*carbonEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point); onMouseMove((SInt32)point.x, (SInt32)point.y); break; } case kEventMouseWheelMoved: { EventMouseWheelAxis axis; SInt32 delta; GetEventParameter(*carbonEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(axis), NULL, &axis); if (axis == kEventMouseWheelAxisX || axis == kEventMouseWheelAxisY) { GetEventParameter(*carbonEvent, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(delta), NULL, &delta); if (axis == kEventMouseWheelAxisX) { onMouseWheel(-mapScrollWheelToSynergy((SInt32)delta), 0); } else { onMouseWheel(0, mapScrollWheelToSynergy((SInt32)delta)); } } break; } case kSynergyEventMouseScroll: { OSStatus r; long xScroll; long yScroll; // get scroll amount r = GetEventParameter(*carbonEvent, kSynergyMouseScrollAxisX, typeLongInteger, NULL, sizeof(xScroll), NULL, &xScroll); if (r != noErr) { xScroll = 0; } r = GetEventParameter(*carbonEvent, kSynergyMouseScrollAxisY, typeLongInteger, NULL, sizeof(yScroll), NULL, &yScroll); if (r != noErr) { yScroll = 0; } if (xScroll != 0 || yScroll != 0) { onMouseWheel(-mapScrollWheelToSynergy(xScroll), mapScrollWheelToSynergy(yScroll)); } } } break; case kEventClassKeyboard: switch (GetEventKind(*carbonEvent)) { case kEventRawKeyUp: case kEventRawKeyDown: case kEventRawKeyRepeat: case kEventRawKeyModifiersChanged: onKey(*carbonEvent); break; case kEventHotKeyPressed: case kEventHotKeyReleased: onHotKey(*carbonEvent); break; } break; case kEventClassWindow: SendEventToWindow(*carbonEvent, m_userInputWindow); switch (GetEventKind(*carbonEvent)) { case kEventWindowActivated: LOG((CLOG_DEBUG1 "window activated")); break; case kEventWindowDeactivated: LOG((CLOG_DEBUG1 "window deactivated")); break; case kEventWindowFocusAcquired: LOG((CLOG_DEBUG1 "focus acquired")); break; case kEventWindowFocusRelinquish: LOG((CLOG_DEBUG1 "focus released")); break; } break; default: SendEventToEventTarget(*carbonEvent, GetEventDispatcherTarget()); break; } }
void CStreamFilter::filterEvent(const CEvent& event) { EVENTQUEUE->dispatchEvent(CEvent(event.getType(), getEventTarget(), event.getData())); }
void CServerApp::handleScreenSwitched(const CEvent& e, void*) { if (!args().m_enableVnc) return; if (m_vncClient != NULL) { LOG((CLOG_DEBUG "hiding vnc viewer for: %s", m_vncClient->m_screen.c_str())); m_vncClient->hideViewer(); } CServer::CSwitchToScreenInfo* info = reinterpret_cast<CServer::CSwitchToScreenInfo*>(e.getData()); std::map<CString, CVncClient*>::iterator it = m_vncClients.find(info->m_screen); if (it == m_vncClients.end()) { LOG((CLOG_DEBUG "could not find vnc client for: %s", info->m_screen)); return; } LOG((CLOG_DEBUG "showing vnc viewer for: %s", info->m_screen)); m_vncClient = it->second; m_vncClient->showViewer(); }