00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CInputFilter.h"
00020 #include "CServer.h"
00021 #include "CPrimaryClient.h"
00022 #include "CKeyMap.h"
00023 #include "CEventQueue.h"
00024 #include "CLog.h"
00025 #include "TMethodEventJob.h"
00026 #include <cstdlib>
00027 #include <cstring>
00028
00029
00030
00031
00032 CInputFilter::CCondition::CCondition()
00033 {
00034
00035 }
00036
00037 CInputFilter::CCondition::~CCondition()
00038 {
00039
00040 }
00041
00042 void
00043 CInputFilter::CCondition::enablePrimary(CPrimaryClient*)
00044 {
00045
00046 }
00047
00048 void
00049 CInputFilter::CCondition::disablePrimary(CPrimaryClient*)
00050 {
00051
00052 }
00053
00054 CInputFilter::CKeystrokeCondition::CKeystrokeCondition(
00055 IPlatformScreen::CKeyInfo* info) :
00056 m_id(0),
00057 m_key(info->m_key),
00058 m_mask(info->m_mask)
00059 {
00060 free(info);
00061 }
00062
00063 CInputFilter::CKeystrokeCondition::CKeystrokeCondition(
00064 KeyID key, KeyModifierMask mask) :
00065 m_id(0),
00066 m_key(key),
00067 m_mask(mask)
00068 {
00069
00070 }
00071
00072 CInputFilter::CKeystrokeCondition::~CKeystrokeCondition()
00073 {
00074
00075 }
00076
00077 KeyID
00078 CInputFilter::CKeystrokeCondition::getKey() const
00079 {
00080 return m_key;
00081 }
00082
00083 KeyModifierMask
00084 CInputFilter::CKeystrokeCondition::getMask() const
00085 {
00086 return m_mask;
00087 }
00088
00089 CInputFilter::CCondition*
00090 CInputFilter::CKeystrokeCondition::clone() const
00091 {
00092 return new CKeystrokeCondition(m_key, m_mask);
00093 }
00094
00095 CString
00096 CInputFilter::CKeystrokeCondition::format() const
00097 {
00098 return CStringUtil::print("keystroke(%s)",
00099 CKeyMap::formatKey(m_key, m_mask).c_str());
00100 }
00101
00102 CInputFilter::EFilterStatus
00103 CInputFilter::CKeystrokeCondition::match(const CEvent& event)
00104 {
00105 EFilterStatus status;
00106
00107
00108 CEvent::Type type = event.getType();
00109 if (type == IPrimaryScreen::getHotKeyDownEvent()) {
00110 status = kActivate;
00111 }
00112 else if (type == IPrimaryScreen::getHotKeyUpEvent()) {
00113 status = kDeactivate;
00114 }
00115 else {
00116 return kNoMatch;
00117 }
00118
00119
00120 IPrimaryScreen::CHotKeyInfo* kinfo =
00121 reinterpret_cast<IPlatformScreen::CHotKeyInfo*>(event.getData());
00122 if (kinfo->m_id != m_id) {
00123 return kNoMatch;
00124 }
00125
00126 return status;
00127 }
00128
00129 void
00130 CInputFilter::CKeystrokeCondition::enablePrimary(CPrimaryClient* primary)
00131 {
00132 m_id = primary->registerHotKey(m_key, m_mask);
00133 }
00134
00135 void
00136 CInputFilter::CKeystrokeCondition::disablePrimary(CPrimaryClient* primary)
00137 {
00138 primary->unregisterHotKey(m_id);
00139 m_id = 0;
00140 }
00141
00142 CInputFilter::CMouseButtonCondition::CMouseButtonCondition(
00143 IPlatformScreen::CButtonInfo* info) :
00144 m_button(info->m_button),
00145 m_mask(info->m_mask)
00146 {
00147 free(info);
00148 }
00149
00150 CInputFilter::CMouseButtonCondition::CMouseButtonCondition(
00151 ButtonID button, KeyModifierMask mask) :
00152 m_button(button),
00153 m_mask(mask)
00154 {
00155
00156 }
00157
00158 CInputFilter::CMouseButtonCondition::~CMouseButtonCondition()
00159 {
00160
00161 }
00162
00163 ButtonID
00164 CInputFilter::CMouseButtonCondition::getButton() const
00165 {
00166 return m_button;
00167 }
00168
00169 KeyModifierMask
00170 CInputFilter::CMouseButtonCondition::getMask() const
00171 {
00172 return m_mask;
00173 }
00174
00175 CInputFilter::CCondition*
00176 CInputFilter::CMouseButtonCondition::clone() const
00177 {
00178 return new CMouseButtonCondition(m_button, m_mask);
00179 }
00180
00181 CString
00182 CInputFilter::CMouseButtonCondition::format() const
00183 {
00184 CString key = CKeyMap::formatKey(kKeyNone, m_mask);
00185 if (!key.empty()) {
00186 key += "+";
00187 }
00188 return CStringUtil::print("mousebutton(%s%d)", key.c_str(), m_button);
00189 }
00190
00191 CInputFilter::EFilterStatus
00192 CInputFilter::CMouseButtonCondition::match(const CEvent& event)
00193 {
00194 static const KeyModifierMask s_ignoreMask =
00195 KeyModifierAltGr | KeyModifierCapsLock |
00196 KeyModifierNumLock | KeyModifierScrollLock;
00197
00198 EFilterStatus status;
00199
00200
00201 CEvent::Type type = event.getType();
00202 if (type == IPrimaryScreen::getButtonDownEvent()) {
00203 status = kActivate;
00204 }
00205 else if (type == IPrimaryScreen::getButtonUpEvent()) {
00206 status = kDeactivate;
00207 }
00208 else {
00209 return kNoMatch;
00210 }
00211
00212
00213
00214 IPlatformScreen::CButtonInfo* minfo =
00215 reinterpret_cast<IPlatformScreen::CButtonInfo*>(event.getData());
00216 if (minfo->m_button != m_button ||
00217 (minfo->m_mask & ~s_ignoreMask) != m_mask) {
00218 return kNoMatch;
00219 }
00220
00221 return status;
00222 }
00223
00224 CInputFilter::CScreenConnectedCondition::CScreenConnectedCondition(
00225 const CString& screen) :
00226 m_screen(screen)
00227 {
00228
00229 }
00230
00231 CInputFilter::CScreenConnectedCondition::~CScreenConnectedCondition()
00232 {
00233
00234 }
00235
00236 CInputFilter::CCondition*
00237 CInputFilter::CScreenConnectedCondition::clone() const
00238 {
00239 return new CScreenConnectedCondition(m_screen);
00240 }
00241
00242 CString
00243 CInputFilter::CScreenConnectedCondition::format() const
00244 {
00245 return CStringUtil::print("connect(%s)", m_screen.c_str());
00246 }
00247
00248 CInputFilter::EFilterStatus
00249 CInputFilter::CScreenConnectedCondition::match(const CEvent& event)
00250 {
00251 if (event.getType() == CServer::getConnectedEvent()) {
00252 CServer::CScreenConnectedInfo* info =
00253 reinterpret_cast<CServer::CScreenConnectedInfo*>(event.getData());
00254 if (m_screen == info->m_screen || m_screen.empty()) {
00255 return kActivate;
00256 }
00257 }
00258
00259 return kNoMatch;
00260 }
00261
00262
00263
00264
00265 CInputFilter::CAction::CAction()
00266 {
00267
00268 }
00269
00270 CInputFilter::CAction::~CAction()
00271 {
00272
00273 }
00274
00275 CInputFilter::CLockCursorToScreenAction::CLockCursorToScreenAction(Mode mode) :
00276 m_mode(mode)
00277 {
00278
00279 }
00280
00281 CInputFilter::CLockCursorToScreenAction::Mode
00282 CInputFilter::CLockCursorToScreenAction::getMode() const
00283 {
00284 return m_mode;
00285 }
00286
00287 CInputFilter::CAction*
00288 CInputFilter::CLockCursorToScreenAction::clone() const
00289 {
00290 return new CLockCursorToScreenAction(*this);
00291 }
00292
00293 CString
00294 CInputFilter::CLockCursorToScreenAction::format() const
00295 {
00296 static const char* s_mode[] = { "off", "on", "toggle" };
00297
00298 return CStringUtil::print("lockCursorToScreen(%s)", s_mode[m_mode]);
00299 }
00300
00301 void
00302 CInputFilter::CLockCursorToScreenAction::perform(const CEvent& event)
00303 {
00304 static const CServer::CLockCursorToScreenInfo::State s_state[] = {
00305 CServer::CLockCursorToScreenInfo::kOff,
00306 CServer::CLockCursorToScreenInfo::kOn,
00307 CServer::CLockCursorToScreenInfo::kToggle
00308 };
00309
00310
00311 CServer::CLockCursorToScreenInfo* info =
00312 CServer::CLockCursorToScreenInfo::alloc(s_state[m_mode]);
00313 EVENTQUEUE->addEvent(CEvent(CServer::getLockCursorToScreenEvent(),
00314 event.getTarget(), info,
00315 CEvent::kDeliverImmediately));
00316 }
00317
00318 CInputFilter::CSwitchToScreenAction::CSwitchToScreenAction(
00319 const CString& screen) :
00320 m_screen(screen)
00321 {
00322
00323 }
00324
00325 CString
00326 CInputFilter::CSwitchToScreenAction::getScreen() const
00327 {
00328 return m_screen;
00329 }
00330
00331 CInputFilter::CAction*
00332 CInputFilter::CSwitchToScreenAction::clone() const
00333 {
00334 return new CSwitchToScreenAction(*this);
00335 }
00336
00337 CString
00338 CInputFilter::CSwitchToScreenAction::format() const
00339 {
00340 return CStringUtil::print("switchToScreen(%s)", m_screen.c_str());
00341 }
00342
00343 void
00344 CInputFilter::CSwitchToScreenAction::perform(const CEvent& event)
00345 {
00346
00347
00348 CString screen = m_screen;
00349 if (screen.empty() && event.getType() == CServer::getConnectedEvent()) {
00350 CServer::CScreenConnectedInfo* info =
00351 reinterpret_cast<CServer::CScreenConnectedInfo*>(event.getData());
00352 screen = info->m_screen;
00353 }
00354
00355
00356 CServer::CSwitchToScreenInfo* info =
00357 CServer::CSwitchToScreenInfo::alloc(screen);
00358 EVENTQUEUE->addEvent(CEvent(CServer::getSwitchToScreenEvent(),
00359 event.getTarget(), info,
00360 CEvent::kDeliverImmediately));
00361 }
00362
00363 CInputFilter::CSwitchInDirectionAction::CSwitchInDirectionAction(
00364 EDirection direction) :
00365 m_direction(direction)
00366 {
00367
00368 }
00369
00370 EDirection
00371 CInputFilter::CSwitchInDirectionAction::getDirection() const
00372 {
00373 return m_direction;
00374 }
00375
00376 CInputFilter::CAction*
00377 CInputFilter::CSwitchInDirectionAction::clone() const
00378 {
00379 return new CSwitchInDirectionAction(*this);
00380 }
00381
00382 CString
00383 CInputFilter::CSwitchInDirectionAction::format() const
00384 {
00385 static const char* s_names[] = {
00386 "",
00387 "left",
00388 "right",
00389 "up",
00390 "down"
00391 };
00392
00393 return CStringUtil::print("switchInDirection(%s)", s_names[m_direction]);
00394 }
00395
00396 void
00397 CInputFilter::CSwitchInDirectionAction::perform(const CEvent& event)
00398 {
00399 CServer::CSwitchInDirectionInfo* info =
00400 CServer::CSwitchInDirectionInfo::alloc(m_direction);
00401 EVENTQUEUE->addEvent(CEvent(CServer::getSwitchInDirectionEvent(),
00402 event.getTarget(), info,
00403 CEvent::kDeliverImmediately));
00404 }
00405
00406 CInputFilter::CKeyboardBroadcastAction::CKeyboardBroadcastAction(Mode mode) :
00407 m_mode(mode)
00408 {
00409
00410 }
00411
00412 CInputFilter::CKeyboardBroadcastAction::CKeyboardBroadcastAction(
00413 Mode mode,
00414 const std::set<CString>& screens) :
00415 m_mode(mode),
00416 m_screens(IKeyState::CKeyInfo::join(screens))
00417 {
00418
00419 }
00420
00421 CInputFilter::CKeyboardBroadcastAction::Mode
00422 CInputFilter::CKeyboardBroadcastAction::getMode() const
00423 {
00424 return m_mode;
00425 }
00426
00427 std::set<CString>
00428 CInputFilter::CKeyboardBroadcastAction::getScreens() const
00429 {
00430 std::set<CString> screens;
00431 IKeyState::CKeyInfo::split(m_screens.c_str(), screens);
00432 return screens;
00433 }
00434
00435 CInputFilter::CAction*
00436 CInputFilter::CKeyboardBroadcastAction::clone() const
00437 {
00438 return new CKeyboardBroadcastAction(*this);
00439 }
00440
00441 CString
00442 CInputFilter::CKeyboardBroadcastAction::format() const
00443 {
00444 static const char* s_mode[] = { "off", "on", "toggle" };
00445 static const char* s_name = "keyboardBroadcast";
00446
00447 if (m_screens.empty() || m_screens[0] == '*') {
00448 return CStringUtil::print("%s(%s)", s_name, s_mode[m_mode]);
00449 }
00450 else {
00451 return CStringUtil::print("%s(%s,%.*s)", s_name, s_mode[m_mode],
00452 m_screens.size() - 2,
00453 m_screens.c_str() + 1);
00454 }
00455 }
00456
00457 void
00458 CInputFilter::CKeyboardBroadcastAction::perform(const CEvent& event)
00459 {
00460 static const CServer::CKeyboardBroadcastInfo::State s_state[] = {
00461 CServer::CKeyboardBroadcastInfo::kOff,
00462 CServer::CKeyboardBroadcastInfo::kOn,
00463 CServer::CKeyboardBroadcastInfo::kToggle
00464 };
00465
00466
00467 CServer::CKeyboardBroadcastInfo* info =
00468 CServer::CKeyboardBroadcastInfo::alloc(s_state[m_mode], m_screens);
00469 EVENTQUEUE->addEvent(CEvent(CServer::getKeyboardBroadcastEvent(),
00470 event.getTarget(), info,
00471 CEvent::kDeliverImmediately));
00472 }
00473
00474 CInputFilter::CKeystrokeAction::CKeystrokeAction(
00475 IPlatformScreen::CKeyInfo* info, bool press) :
00476 m_keyInfo(info),
00477 m_press(press)
00478 {
00479
00480 }
00481
00482 CInputFilter::CKeystrokeAction::~CKeystrokeAction()
00483 {
00484 free(m_keyInfo);
00485 }
00486
00487 void
00488 CInputFilter::CKeystrokeAction::adoptInfo(IPlatformScreen::CKeyInfo* info)
00489 {
00490 free(m_keyInfo);
00491 m_keyInfo = info;
00492 }
00493
00494 const IPlatformScreen::CKeyInfo*
00495 CInputFilter::CKeystrokeAction::getInfo() const
00496 {
00497 return m_keyInfo;
00498 }
00499
00500 bool
00501 CInputFilter::CKeystrokeAction::isOnPress() const
00502 {
00503 return m_press;
00504 }
00505
00506 CInputFilter::CAction*
00507 CInputFilter::CKeystrokeAction::clone() const
00508 {
00509 IKeyState::CKeyInfo* info = IKeyState::CKeyInfo::alloc(*m_keyInfo);
00510 return new CKeystrokeAction(info, m_press);
00511 }
00512
00513 CString
00514 CInputFilter::CKeystrokeAction::format() const
00515 {
00516 const char* type = formatName();
00517
00518 if (m_keyInfo->m_screens[0] == '\0') {
00519 return CStringUtil::print("%s(%s)", type,
00520 CKeyMap::formatKey(m_keyInfo->m_key,
00521 m_keyInfo->m_mask).c_str());
00522 }
00523 else if (m_keyInfo->m_screens[0] == '*') {
00524 return CStringUtil::print("%s(%s,*)", type,
00525 CKeyMap::formatKey(m_keyInfo->m_key,
00526 m_keyInfo->m_mask).c_str());
00527 }
00528 else {
00529 return CStringUtil::print("%s(%s,%.*s)", type,
00530 CKeyMap::formatKey(m_keyInfo->m_key,
00531 m_keyInfo->m_mask).c_str(),
00532 strlen(m_keyInfo->m_screens + 1) - 1,
00533 m_keyInfo->m_screens + 1);
00534 }
00535 }
00536
00537 void
00538 CInputFilter::CKeystrokeAction::perform(const CEvent& event)
00539 {
00540 CEvent::Type type = m_press ? IPlatformScreen::getKeyDownEvent(*EVENTQUEUE) :
00541 IPlatformScreen::getKeyUpEvent(*EVENTQUEUE);
00542 EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getFakeInputBeginEvent(),
00543 event.getTarget(), NULL,
00544 CEvent::kDeliverImmediately));
00545 EVENTQUEUE->addEvent(CEvent(type, event.getTarget(), m_keyInfo,
00546 CEvent::kDeliverImmediately |
00547 CEvent::kDontFreeData));
00548 EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getFakeInputEndEvent(),
00549 event.getTarget(), NULL,
00550 CEvent::kDeliverImmediately));
00551 }
00552
00553 const char*
00554 CInputFilter::CKeystrokeAction::formatName() const
00555 {
00556 return (m_press ? "keyDown" : "keyUp");
00557 }
00558
00559 CInputFilter::CMouseButtonAction::CMouseButtonAction(
00560 IPlatformScreen::CButtonInfo* info, bool press) :
00561 m_buttonInfo(info),
00562 m_press(press)
00563 {
00564
00565 }
00566
00567 CInputFilter::CMouseButtonAction::~CMouseButtonAction()
00568 {
00569 free(m_buttonInfo);
00570 }
00571
00572 const IPlatformScreen::CButtonInfo*
00573 CInputFilter::CMouseButtonAction::getInfo() const
00574 {
00575 return m_buttonInfo;
00576 }
00577
00578 bool
00579 CInputFilter::CMouseButtonAction::isOnPress() const
00580 {
00581 return m_press;
00582 }
00583
00584 CInputFilter::CAction*
00585 CInputFilter::CMouseButtonAction::clone() const
00586 {
00587 IPlatformScreen::CButtonInfo* info =
00588 IPrimaryScreen::CButtonInfo::alloc(*m_buttonInfo);
00589 return new CMouseButtonAction(info, m_press);
00590 }
00591
00592 CString
00593 CInputFilter::CMouseButtonAction::format() const
00594 {
00595 const char* type = formatName();
00596
00597 CString key = CKeyMap::formatKey(kKeyNone, m_buttonInfo->m_mask);
00598 return CStringUtil::print("%s(%s%s%d)", type,
00599 key.c_str(), key.empty() ? "" : "+",
00600 m_buttonInfo->m_button);
00601 }
00602
00603 void
00604 CInputFilter::CMouseButtonAction::perform(const CEvent& event)
00605
00606 {
00607
00608 IPlatformScreen::CKeyInfo* modifierInfo = NULL;
00609 if (m_buttonInfo->m_mask != 0) {
00610 KeyID key = m_press ? kKeySetModifiers : kKeyClearModifiers;
00611 modifierInfo =
00612 IKeyState::CKeyInfo::alloc(key, m_buttonInfo->m_mask, 0, 1);
00613 EVENTQUEUE->addEvent(CEvent(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
00614 event.getTarget(), modifierInfo,
00615 CEvent::kDeliverImmediately));
00616 }
00617
00618
00619 CEvent::Type type = m_press ? IPlatformScreen::getButtonDownEvent() :
00620 IPlatformScreen::getButtonUpEvent();
00621 EVENTQUEUE->addEvent(CEvent(type, event.getTarget(), m_buttonInfo,
00622 CEvent::kDeliverImmediately |
00623 CEvent::kDontFreeData));
00624 }
00625
00626 const char*
00627 CInputFilter::CMouseButtonAction::formatName() const
00628 {
00629 return (m_press ? "mouseDown" : "mouseUp");
00630 }
00631
00632
00633
00634
00635
00636 CInputFilter::CRule::CRule() :
00637 m_condition(NULL)
00638 {
00639
00640 }
00641
00642 CInputFilter::CRule::CRule(CCondition* adoptedCondition) :
00643 m_condition(adoptedCondition)
00644 {
00645
00646 }
00647
00648 CInputFilter::CRule::CRule(const CRule& rule) :
00649 m_condition(NULL)
00650 {
00651 copy(rule);
00652 }
00653
00654 CInputFilter::CRule::~CRule()
00655 {
00656 clear();
00657 }
00658
00659 CInputFilter::CRule&
00660 CInputFilter::CRule::operator=(const CRule& rule)
00661 {
00662 if (&rule != this) {
00663 copy(rule);
00664 }
00665 return *this;
00666 }
00667
00668 void
00669 CInputFilter::CRule::clear()
00670 {
00671 delete m_condition;
00672 for (CActionList::iterator i = m_activateActions.begin();
00673 i != m_activateActions.end(); ++i) {
00674 delete *i;
00675 }
00676 for (CActionList::iterator i = m_deactivateActions.begin();
00677 i != m_deactivateActions.end(); ++i) {
00678 delete *i;
00679 }
00680
00681 m_condition = NULL;
00682 m_activateActions.clear();
00683 m_deactivateActions.clear();
00684 }
00685
00686 void
00687 CInputFilter::CRule::copy(const CRule& rule)
00688 {
00689 clear();
00690 if (rule.m_condition != NULL) {
00691 m_condition = rule.m_condition->clone();
00692 }
00693 for (CActionList::const_iterator i = rule.m_activateActions.begin();
00694 i != rule.m_activateActions.end(); ++i) {
00695 m_activateActions.push_back((*i)->clone());
00696 }
00697 for (CActionList::const_iterator i = rule.m_deactivateActions.begin();
00698 i != rule.m_deactivateActions.end(); ++i) {
00699 m_deactivateActions.push_back((*i)->clone());
00700 }
00701 }
00702
00703 void
00704 CInputFilter::CRule::setCondition(CCondition* adopted)
00705 {
00706 delete m_condition;
00707 m_condition = adopted;
00708 }
00709
00710 void
00711 CInputFilter::CRule::adoptAction(CAction* action, bool onActivation)
00712 {
00713 if (action != NULL) {
00714 if (onActivation) {
00715 m_activateActions.push_back(action);
00716 }
00717 else {
00718 m_deactivateActions.push_back(action);
00719 }
00720 }
00721 }
00722
00723 void
00724 CInputFilter::CRule::removeAction(bool onActivation, UInt32 index)
00725 {
00726 if (onActivation) {
00727 delete m_activateActions[index];
00728 m_activateActions.erase(m_activateActions.begin() + index);
00729 }
00730 else {
00731 delete m_deactivateActions[index];
00732 m_deactivateActions.erase(m_deactivateActions.begin() + index);
00733 }
00734 }
00735
00736 void
00737 CInputFilter::CRule::replaceAction(CAction* adopted,
00738 bool onActivation, UInt32 index)
00739 {
00740 if (adopted == NULL) {
00741 removeAction(onActivation, index);
00742 }
00743 else if (onActivation) {
00744 delete m_activateActions[index];
00745 m_activateActions[index] = adopted;
00746 }
00747 else {
00748 delete m_deactivateActions[index];
00749 m_deactivateActions[index] = adopted;
00750 }
00751 }
00752
00753 void
00754 CInputFilter::CRule::enable(CPrimaryClient* primaryClient)
00755 {
00756 if (m_condition != NULL) {
00757 m_condition->enablePrimary(primaryClient);
00758 }
00759 }
00760
00761 void
00762 CInputFilter::CRule::disable(CPrimaryClient* primaryClient)
00763 {
00764 if (m_condition != NULL) {
00765 m_condition->disablePrimary(primaryClient);
00766 }
00767 }
00768
00769 bool
00770 CInputFilter::CRule::handleEvent(const CEvent& event)
00771 {
00772
00773 if (m_condition == NULL) {
00774 return false;
00775 }
00776
00777
00778 const CActionList* actions;
00779 switch (m_condition->match(event)) {
00780 default:
00781
00782 return false;
00783
00784 case kActivate:
00785 actions = &m_activateActions;
00786 LOG((CLOG_DEBUG1 "activate actions"));
00787 break;
00788
00789 case kDeactivate:
00790 actions = &m_deactivateActions;
00791 LOG((CLOG_DEBUG1 "deactivate actions"));
00792 break;
00793 }
00794
00795
00796 for (CActionList::const_iterator i = actions->begin();
00797 i != actions->end(); ++i) {
00798 LOG((CLOG_DEBUG1 "hotkey: %s", (*i)->format().c_str()));
00799 (*i)->perform(event);
00800 }
00801
00802 return true;
00803 }
00804
00805 CString
00806 CInputFilter::CRule::format() const
00807 {
00808 CString s;
00809 if (m_condition != NULL) {
00810
00811 s += m_condition->format();
00812 s += " = ";
00813
00814
00815 CActionList::const_iterator i = m_activateActions.begin();
00816 if (i != m_activateActions.end()) {
00817 s += (*i)->format();
00818 while (++i != m_activateActions.end()) {
00819 s += ", ";
00820 s += (*i)->format();
00821 }
00822 }
00823
00824
00825 if (!m_deactivateActions.empty()) {
00826 s += "; ";
00827 i = m_deactivateActions.begin();
00828 if (i != m_deactivateActions.end()) {
00829 s += (*i)->format();
00830 while (++i != m_deactivateActions.end()) {
00831 s += ", ";
00832 s += (*i)->format();
00833 }
00834 }
00835 }
00836 }
00837 return s;
00838 }
00839
00840 const CInputFilter::CCondition*
00841 CInputFilter::CRule::getCondition() const
00842 {
00843 return m_condition;
00844 }
00845
00846 UInt32
00847 CInputFilter::CRule::getNumActions(bool onActivation) const
00848 {
00849 if (onActivation) {
00850 return static_cast<UInt32>(m_activateActions.size());
00851 }
00852 else {
00853 return static_cast<UInt32>(m_deactivateActions.size());
00854 }
00855 }
00856
00857 const CInputFilter::CAction&
00858 CInputFilter::CRule::getAction(bool onActivation, UInt32 index) const
00859 {
00860 if (onActivation) {
00861 return *m_activateActions[index];
00862 }
00863 else {
00864 return *m_deactivateActions[index];
00865 }
00866 }
00867
00868
00869
00870
00871
00872 CInputFilter::CInputFilter() :
00873 m_primaryClient(NULL)
00874 {
00875
00876 }
00877
00878 CInputFilter::CInputFilter(const CInputFilter& x) :
00879 m_ruleList(x.m_ruleList),
00880 m_primaryClient(NULL)
00881 {
00882 setPrimaryClient(x.m_primaryClient);
00883 }
00884
00885 CInputFilter::~CInputFilter()
00886 {
00887 setPrimaryClient(NULL);
00888 }
00889
00890 CInputFilter&
00891 CInputFilter::operator=(const CInputFilter& x)
00892 {
00893 if (&x != this) {
00894 CPrimaryClient* oldClient = m_primaryClient;
00895 setPrimaryClient(NULL);
00896
00897 m_ruleList = x.m_ruleList;
00898
00899 setPrimaryClient(oldClient);
00900 }
00901 return *this;
00902 }
00903
00904 void
00905 CInputFilter::addFilterRule(const CRule& rule)
00906 {
00907 m_ruleList.push_back(rule);
00908 if (m_primaryClient != NULL) {
00909 m_ruleList.back().enable(m_primaryClient);
00910 }
00911 }
00912
00913 void
00914 CInputFilter::removeFilterRule(UInt32 index)
00915 {
00916 if (m_primaryClient != NULL) {
00917 m_ruleList[index].disable(m_primaryClient);
00918 }
00919 m_ruleList.erase(m_ruleList.begin() + index);
00920 }
00921
00922 CInputFilter::CRule&
00923 CInputFilter::getRule(UInt32 index)
00924 {
00925 return m_ruleList[index];
00926 }
00927
00928 void
00929 CInputFilter::setPrimaryClient(CPrimaryClient* client)
00930 {
00931 if (m_primaryClient == client) {
00932 return;
00933 }
00934
00935 if (m_primaryClient != NULL) {
00936 for (CRuleList::iterator rule = m_ruleList.begin();
00937 rule != m_ruleList.end(); ++rule) {
00938 rule->disable(m_primaryClient);
00939 }
00940
00941 EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
00942 m_primaryClient->getEventTarget());
00943 EVENTQUEUE->removeHandler(IPlatformScreen::getKeyUpEvent(*EVENTQUEUE),
00944 m_primaryClient->getEventTarget());
00945 EVENTQUEUE->removeHandler(IPlatformScreen::getKeyRepeatEvent(*EVENTQUEUE),
00946 m_primaryClient->getEventTarget());
00947 EVENTQUEUE->removeHandler(IPlatformScreen::getButtonDownEvent(),
00948 m_primaryClient->getEventTarget());
00949 EVENTQUEUE->removeHandler(IPlatformScreen::getButtonUpEvent(),
00950 m_primaryClient->getEventTarget());
00951 EVENTQUEUE->removeHandler(IPlatformScreen::getHotKeyDownEvent(),
00952 m_primaryClient->getEventTarget());
00953 EVENTQUEUE->removeHandler(IPlatformScreen::getHotKeyUpEvent(),
00954 m_primaryClient->getEventTarget());
00955 EVENTQUEUE->removeHandler(CServer::getConnectedEvent(),
00956 m_primaryClient->getEventTarget());
00957 }
00958
00959 m_primaryClient = client;
00960
00961 if (m_primaryClient != NULL) {
00962 EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
00963 m_primaryClient->getEventTarget(),
00964 new TMethodEventJob<CInputFilter>(this,
00965 &CInputFilter::handleEvent));
00966 EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyUpEvent(*EVENTQUEUE),
00967 m_primaryClient->getEventTarget(),
00968 new TMethodEventJob<CInputFilter>(this,
00969 &CInputFilter::handleEvent));
00970 EVENTQUEUE->adoptHandler(IPlatformScreen::getKeyRepeatEvent(*EVENTQUEUE),
00971 m_primaryClient->getEventTarget(),
00972 new TMethodEventJob<CInputFilter>(this,
00973 &CInputFilter::handleEvent));
00974 EVENTQUEUE->adoptHandler(IPlatformScreen::getButtonDownEvent(),
00975 m_primaryClient->getEventTarget(),
00976 new TMethodEventJob<CInputFilter>(this,
00977 &CInputFilter::handleEvent));
00978 EVENTQUEUE->adoptHandler(IPlatformScreen::getButtonUpEvent(),
00979 m_primaryClient->getEventTarget(),
00980 new TMethodEventJob<CInputFilter>(this,
00981 &CInputFilter::handleEvent));
00982 EVENTQUEUE->adoptHandler(IPlatformScreen::getHotKeyDownEvent(),
00983 m_primaryClient->getEventTarget(),
00984 new TMethodEventJob<CInputFilter>(this,
00985 &CInputFilter::handleEvent));
00986 EVENTQUEUE->adoptHandler(IPlatformScreen::getHotKeyUpEvent(),
00987 m_primaryClient->getEventTarget(),
00988 new TMethodEventJob<CInputFilter>(this,
00989 &CInputFilter::handleEvent));
00990 EVENTQUEUE->adoptHandler(CServer::getConnectedEvent(),
00991 m_primaryClient->getEventTarget(),
00992 new TMethodEventJob<CInputFilter>(this,
00993 &CInputFilter::handleEvent));
00994
00995 for (CRuleList::iterator rule = m_ruleList.begin();
00996 rule != m_ruleList.end(); ++rule) {
00997 rule->enable(m_primaryClient);
00998 }
00999 }
01000 }
01001
01002 CString
01003 CInputFilter::format(const CString& linePrefix) const
01004 {
01005 CString s;
01006 for (CRuleList::const_iterator i = m_ruleList.begin();
01007 i != m_ruleList.end(); ++i) {
01008 s += linePrefix;
01009 s += i->format();
01010 s += "\n";
01011 }
01012 return s;
01013 }
01014
01015 UInt32
01016 CInputFilter::getNumRules() const
01017 {
01018 return static_cast<UInt32>(m_ruleList.size());
01019 }
01020
01021 bool
01022 CInputFilter::operator==(const CInputFilter& x) const
01023 {
01024
01025 if (m_ruleList.size() != x.m_ruleList.size()) {
01026 return false;
01027 }
01028
01029
01030
01031 std::vector<CString> aList, bList;
01032 for (CRuleList::const_iterator i = m_ruleList.begin();
01033 i != m_ruleList.end(); ++i) {
01034 aList.push_back(i->format());
01035 }
01036 for (CRuleList::const_iterator i = x.m_ruleList.begin();
01037 i != x.m_ruleList.end(); ++i) {
01038 bList.push_back(i->format());
01039 }
01040 std::partial_sort(aList.begin(), aList.end(), aList.end());
01041 std::partial_sort(bList.begin(), bList.end(), bList.end());
01042 return (aList == bList);
01043 }
01044
01045 bool
01046 CInputFilter::operator!=(const CInputFilter& x) const
01047 {
01048 return !operator==(x);
01049 }
01050
01051 void
01052 CInputFilter::handleEvent(const CEvent& event, void*)
01053 {
01054
01055 CEvent myEvent(event.getType(), this, event.getData(),
01056 event.getFlags() | CEvent::kDontFreeData |
01057 CEvent::kDeliverImmediately);
01058
01059
01060 for (CRuleList::iterator rule = m_ruleList.begin();
01061 rule != m_ruleList.end(); ++rule) {
01062 if (rule->handleEvent(myEvent)) {
01063
01064 return;
01065 }
01066 }
01067
01068
01069 EVENTQUEUE->addEvent(myEvent);
01070 }