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