src/binder.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2003 - 2004 Anselm R. Garbe <anselmg at t-online.de>
00002 // Copyright (c) 2003 - 2004 Marcel Manthe <schneegloeckchen at gmx.li>
00003 // See ../LICENSE.txt for license details.
00004 //
00005 // $Id: binder.cpp 7 2007-05-24 11:03:53Z eg1981 $
00006 
00007 extern "C" {
00008 #include <assert.h>
00009 }
00010 
00011 #include <sstream>
00012 #include <string>
00013 #include "ncwm.h"
00014 
00015 #include "binder.h"
00016 
00017 #include "action.h"
00018 #include "box.h"
00019 #include "client.h"
00020 #include "container.h"
00021 #include "cursors.h"
00022 #include "expander.h"
00023 #include "frame.h"
00024 #include "inputbar.h"
00025 #include "kernel.h"
00026 #include "logger.h"
00027 #include "monitor.h"
00028 #include "shortcut.h"
00029 #include "thing.h"
00030 #include "util.h"
00031 #include "workspace.h"
00032 #include "xcore.h"
00033 
00034 
00035 Binder::Binder() {
00036     actionBindings_ = KERNEL->actionBindings();
00037     initLockModifiers();
00038 #ifdef POSIX_REGEX
00039     temp_pattern_="uninitalized";
00040     regex_prepare();
00041 #endif
00042 }
00043 
00044 Binder::~Binder() {
00045 }
00046 
00047 void Binder::grabShortcut(Shortcut *shortcut, Window window) {
00048 
00049     // update keysym definitions of the action
00050     if (shortcut->button()) {
00051         XCORE->grabButton(window, shortcut->modMask(),
00052                           shortcut->button());
00053 
00054         if (shortcut->modMask() == AnyModifier) {
00055             return;
00056         }
00057         if (numLockMask_) {
00058             XCORE->grabButton(window, shortcut->modMask() | numLockMask_,
00059                               shortcut->button());
00060             XCORE->grabButton(window, shortcut->modMask() | numLockMask_
00061                               | LockMask, shortcut->button());
00062         }
00063         if (scrollLockMask_) {
00064             XCORE->grabButton(window, shortcut->modMask() | scrollLockMask_,
00065                               shortcut->button());
00066             XCORE->grabButton(window, shortcut->modMask() | scrollLockMask_
00067                               | LockMask, shortcut->button());
00068         }
00069         if (numLockMask_ && scrollLockMask_) {
00070             XCORE->grabButton(window, shortcut->modMask() | numLockMask_
00071                     | scrollLockMask_, shortcut->button());
00072             XCORE->grabButton(window, shortcut->modMask() | numLockMask_
00073                     | scrollLockMask_ | LockMask, shortcut->button());
00074         }
00075     }
00076     else if (shortcut->keyCode()) {
00077         XCORE->grabKey(window, shortcut->modMask(),
00078                        shortcut->keyCode());
00079 
00080         if (shortcut->modMask() == AnyModifier) {
00081             return;
00082         }
00083         if (numLockMask_) {
00084             XCORE->grabKey(window, shortcut->modMask() | numLockMask_,
00085                               shortcut->keyCode());
00086             XCORE->grabKey(window, shortcut->modMask() | numLockMask_
00087                               | LockMask, shortcut->keyCode());
00088         }
00089         if (scrollLockMask_) {
00090             XCORE->grabKey(window, shortcut->modMask() | scrollLockMask_,
00091                               shortcut->keyCode());
00092             XCORE->grabKey(window, shortcut->modMask() | scrollLockMask_
00093                               | LockMask, shortcut->keyCode());
00094         }
00095         if (numLockMask_ && scrollLockMask_) {
00096             XCORE->grabKey(window, shortcut->modMask() | numLockMask_
00097                     | scrollLockMask_, shortcut->keyCode());
00098             XCORE->grabKey(window, shortcut->modMask() | numLockMask_
00099                     | scrollLockMask_ | LockMask, shortcut->keyCode());
00100         }
00101     }
00102 }
00103 
00104 void Binder::ungrabShortcut(Shortcut *shortcut, Window window) {
00105 
00106     if (shortcut->button()) {
00107         XCORE->ungrabButton(window, shortcut->modMask(), shortcut->button());
00108 
00109         if (shortcut->modMask() == AnyModifier) {
00110             return;
00111         }
00112         if (numLockMask_) {
00113             XCORE->ungrabButton(window, shortcut->modMask() | numLockMask_,
00114                               shortcut->button());
00115             XCORE->ungrabButton(window, shortcut->modMask() | numLockMask_
00116                               | LockMask, shortcut->button());
00117         }
00118         if (scrollLockMask_) {
00119             XCORE->ungrabButton(window, shortcut->modMask() | scrollLockMask_,
00120                               shortcut->button());
00121             XCORE->ungrabButton(window, shortcut->modMask() | scrollLockMask_
00122                               | LockMask, shortcut->button());
00123         }
00124         if (numLockMask_ && scrollLockMask_) {
00125             XCORE->ungrabButton(window, shortcut->modMask() | numLockMask_
00126                     | scrollLockMask_, shortcut->button());
00127             XCORE->ungrabButton(window, shortcut->modMask() | numLockMask_
00128                     | scrollLockMask_ | LockMask, shortcut->button());
00129         }
00130     }
00131     else {
00132         XCORE->ungrabKey(window, shortcut->modMask(),
00133                     shortcut->keyCode());
00134 
00135         if (shortcut->modMask() == AnyModifier) {
00136             return;
00137         }
00138         if (numLockMask_) {
00139             XCORE->ungrabKey(window, shortcut->modMask() | numLockMask_,
00140                               shortcut->keyCode());
00141             XCORE->ungrabKey(window, shortcut->modMask() | numLockMask_
00142                               | LockMask, shortcut->keyCode());
00143         }
00144         if (scrollLockMask_) {
00145             XCORE->ungrabKey(window, shortcut->modMask() | scrollLockMask_,
00146                               shortcut->keyCode());
00147             XCORE->ungrabKey(window, shortcut->modMask() | scrollLockMask_
00148                               | LockMask, shortcut->keyCode());
00149         }
00150         if (numLockMask_ && scrollLockMask_) {
00151             XCORE->ungrabKey(window, shortcut->modMask() | numLockMask_
00152                     | scrollLockMask_, shortcut->keyCode());
00153             XCORE->ungrabKey(window, shortcut->modMask() | numLockMask_
00154                     | scrollLockMask_ | LockMask, shortcut->keyCode());
00155         }
00156     }
00157 }
00158 
00159 void Binder::initKeys(Window window) {
00160 
00161     for (MBindings::iterator it = actionBindings_->begin();
00162          it != actionBindings_->end(); it++)
00163     {
00164         Action *action = (*it).second;
00165         LOGDEBUG("initKeys: " + action->id());
00166         if (action->listenOn()) {
00167             grabShortcut(action->listenOn(), window);
00168         }
00169     }
00170 }
00171 
00172 string Binder::prettyPrintKeyBindings() {
00173 
00174     ostringstream oss;
00175     for (MBindings::iterator it = actionBindings_->begin();
00176          it != actionBindings_->end(); it++)
00177     {
00178         Action *action = (*it).second;
00179         Shortcut *shortcut = action->shortcut();
00180         Shortcut *tmp = action->shortcut();
00181         if (shortcut) {
00182             oss.width(35);
00183             oss.fill(' ');
00184             oss << action->id() << " = ";
00185         }
00186         while (tmp) {
00187             oss.width(0);
00188             if (tmp->button()) {
00189                 oss << Util::stringForModMask(tmp->modMask())
00190                     << Util::stringForButton(tmp->button());
00191             }
00192             else {
00193                 oss << Util::stringForModMask(tmp->modMask())
00194                     << XCORE->keyCodeToString(tmp->keyCode());
00195             }
00196             tmp = tmp->next();
00197             if (tmp) {
00198                 oss << " :: ";
00199             }
00200         }
00201         if (shortcut) {
00202             oss << "\n";
00203         }
00204     }
00205 
00206     string result = oss.str();
00207     if (result == "") {
00208         result = "no key bindings defined\n";
00209     }
00210     return result;
00211 }
00212 
00213 void Binder::handleButton(Window window, XButtonEvent *event)
00214 {
00215     LOGDEBUG("handle button press event");
00216     handleShortcut(window, event->state, 0, event->button);
00217 }
00218 
00219 void Binder::handleShortcut(Window window, unsigned long modMask,
00220                             KeyCode keyCode, unsigned int button)
00221 {
00222     LOGDEBUG("handle shortcut event");
00223     LAction grabbedActions;
00224     // only gets in here for the first part of a shortcut, thus
00225     // create a list of all shortcuts which are listened for
00226     for (MBindings::iterator it = actionBindings_->begin();
00227             it != actionBindings_->end(); it++)
00228     {
00229         Action *action = (*it).second;
00230         Shortcut *shortcut = action->listenOn();
00231 
00232         if (shortcut &&
00233             (modMask == shortcut->modMask()) &&
00234             (keyCode == shortcut->keyCode()) &&
00235             (button == shortcut->button()))
00236         {
00237             if (shortcut->next()) {
00238                 action->setListenOn(shortcut->next());
00239                 grabbedActions.push_back(action);
00240             }
00241             else {
00242                 grabbedActions.clear();
00243                 LOGDEBUG("handle shortcut performs action '"
00244                          + action->id() + "'");
00245                 if (action->promptsCount() > 0) {
00246                     KERNEL->focusedMonitor()->inputBar()->runArgument(action);
00247                     // action will be performed by argument processing
00248                 }
00249                 else {
00250                     action->perform();
00251                 }
00252                 break;
00253             }
00254         }
00255     }
00256     if (grabbedActions.size()) {
00257         Shortcut shortcut(modMask, keyCode, 0, button);
00258         // now the magic occurs
00259         handleShortcutChains(window, &shortcut, &grabbedActions);
00260     }
00261     // reset listen on info
00262     for (MBindings::iterator it = actionBindings_->begin();
00263             it != actionBindings_->end(); it++)
00264     {
00265         Action *action = (*it).second;
00266         if (action->shortcut()) {
00267             // already grabbed
00268             action->setListenOn(action->shortcut());
00269         }
00270     }
00271 }
00272 
00273 void Binder::handleShortcutChains(Window window, Shortcut *prefix,
00274                                   LAction *grabbedActions)
00275 {
00276     string sequence = 
00277         " " + Util::stringForModMask(prefix->modMask())
00278             + XCORE->keyCodeToString(prefix->keyCode()) + " ::";
00279     Box *box = KERNEL->focusedMonitor()->box();
00280     box->setText(sequence);
00281     box->show();
00282     box->illuminate();
00283 
00284     XCORE->grabKeyboard(window);
00285 
00286     bool isDoubleShortcut = false;
00287     unsigned long modMask;
00288     KeyCode keyCode;
00289     Action *action = 0;
00290     while (grabbedActions->size()) {
00291         // fetch new key stroke
00292         nextKeystroke(&modMask, &keyCode);
00293 
00294         if ((prefix->modMask() == modMask) &&
00295             (prefix->keyCode() == keyCode))
00296         {
00297             isDoubleShortcut = true;
00298             break;
00299         }
00300         prefix->setModMask(modMask);
00301         prefix->setKeyCode(keyCode);
00302         sequence += " " + Util::stringForModMask(modMask)
00303                         + XCORE->keyCodeToString(keyCode) + " ::";
00304         box->setText(sequence);
00305         box->illuminate();
00306         for (LAction::iterator it = grabbedActions->begin();
00307                 it != grabbedActions->end(); )
00308         {
00309             action = *it;
00310             Shortcut *shortcut = action->listenOn();
00311             if (shortcut &&
00312                 (modMask == shortcut->modMask()) &&
00313                 (keyCode == shortcut->keyCode()))
00314             {
00315                 // iterates next
00316                 it++;
00317                 if (shortcut->next()) {
00318                     action->setListenOn(shortcut->next());
00319                 }
00320                 else {
00321                     grabbedActions->clear(); // escape condition
00322                     break;
00323                 }
00324             }
00325             else {
00326                 // iterates next
00327                 it = grabbedActions->erase(it);
00328             }
00329             action = 0;
00330         }
00331     }
00332     XCORE->ungrabKeyboard();
00333     box->hide();
00334     if (action) {
00335 
00336         LOGDEBUG("handle shortcut performs action '"
00337                 + action->id() + "'");
00338         if (action->promptsCount() > 0) {
00339             KERNEL->focusedMonitor()->inputBar()->runArgument(action);
00340             // action will be performed by argument processing
00341         }
00342         else {
00343             action->perform();
00344         }
00345     }
00346     else if (isDoubleShortcut) {
00347         emulateKeyPress(modMask, keyCode);
00348     }
00349 }
00350 
00351 void Binder::emulateKeyPress(unsigned long modMask, KeyCode keyCode) {
00352 
00353     Monitor *monitor = KERNEL->focusedMonitor();
00354     Client *client = monitor->focused()->topClient();
00355 
00356     if (client) {
00357         XEvent event;
00358         event.xkey.type = KeyPress;
00359         event.xkey.time = CurrentTime;
00360         event.xkey.window = client->clientWindow();
00361         event.xkey.display = KERNEL->display();
00362         event.xkey.state = modMask;
00363         event.xkey.keycode = keyCode;
00364         XCORE->sendEvent(client->clientWindow(), KeyPressMask, &event);
00365         event.xkey.type = KeyRelease;
00366         XCORE->sendEvent(client->clientWindow(), KeyReleaseMask, &event);
00367         XCORE->sync();
00368     }
00369 }
00370 
00371 void Binder::nextKeystroke(unsigned long *modMask, KeyCode *keyCode) {
00372     XEvent event;
00373     KeySym sym;
00374     *modMask = 0;
00375     do {
00376         XCORE->maskEvent(KeyPressMask, &event);
00377         *modMask |= event.xkey.state & validModMask_;
00378         *keyCode = event.xkey.keycode;
00379         sym = XCORE->keyCodeToKeySym(event.xkey.keycode);
00380     } while (IsModifierKey(sym));
00381 }
00382 
00383 void Binder::handleKey(Window window, XKeyEvent *event)
00384 {
00385     LOGDEBUG("handle key press event");
00386     handleShortcut(window, event->state, event->keycode, 0);
00387 }
00388 
00389 void Binder::grabButtons(Window window, unsigned long modMask)
00390 {
00391     XCORE->grabButton(window, modMask, AnyModifier);
00392 }
00393 
00394 void Binder::ungrabButtons(Window window) {
00395     XCORE->ungrabButton(window, AnyModifier, AnyButton);
00396 }
00397 
00398 #ifdef POSIX_REGEX
00399 bool Binder::regex_first_match(const string& pattern, const string& haystack, int& begin, int& end){
00400     regmatch_t temp_regmatch;
00401 
00402     begin = 0;
00403     end = -1 ;
00404     bool condition = false;
00405     if (pattern == temp_pattern_ && pattern!="") { condition = true; } else
00406     {
00407         condition = (regcomp(&temp_regex_, pattern.c_str(), REG_EXTENDED)==0);
00408         if (!condition) regex_prepare(); //reinitialize
00409     }
00410     if (condition){
00411         bool result = (regexec(&temp_regex_, haystack.c_str(), 1, &temp_regmatch, 0)==0);
00412         if (result){
00413             begin = temp_regmatch.rm_so;
00414             end = temp_regmatch.rm_eo;
00415         }
00416         temp_pattern_ = pattern;
00417         return result;
00418     }
00419     return false;
00420 }
00421 
00422 bool Binder::regex_match(const string& pattern, const string& haystack){
00423     int begin;
00424     int end;
00425     return(regex_first_match(pattern, haystack, begin, end));
00426 }
00427 #endif
00428 
00429 
00430 string Binder::absolutePattern(string pattern, Sstring *names,
00431                                    unsigned int offset)
00432 {
00433 
00434     string result = pattern;
00435 if (!(names->empty())) {
00436 
00437 #ifdef POSIX_REGEX
00438         if (doRegex_) {
00439 
00440             /* Check whether the search-pattern contains a modifier.
00441                If it does, simply return the pattern itself, otherwise,
00442                perform an infix-matching-algorithm. */
00443 
00444             string first = *names->begin();
00445             for (int direction = 0; direction <= 1; direction++){
00446                 bool matches_all = true;
00447                 do {
00448                     LOGDEBUG("Entering do-while-infix-matching-loop");
00449                     int begin;
00450                     int end;
00451 
00452                     if (regex_first_match (result, first, begin, end)){
00453                         LOGDEBUG("pattern-rule matched first member");
00454                         int count = end - begin + 1;
00455                         if (direction == 1) begin--;
00456                         if ((begin + count  <= (int)first.length()) && (begin >= 0) && (count>0)){
00457                             pattern=first.substr(begin, count);
00458                             LOGDEBUG("trying to add a char to pattern");
00459                             LOGDEBUG(pattern);
00460                         } else break;
00461                     }
00462 
00463                     for (Sstring::iterator it = names->begin(); it != names->end(); it++) 
00464                         if(!regex_match(pattern, (*it))) matches_all = false;
00465                     if (matches_all) result = pattern;
00466                 } while (matches_all);
00467             }
00468             return(result);
00469         }
00470 #endif
00471 
00472         string firstName = *names->begin();
00473         string lastName = *names->rbegin();
00474 
00475         unsigned int firstLength = firstName.length();
00476         unsigned int lastLength = lastName.length();
00477         for (unsigned int i = offset;
00478              (i < firstLength) && (i < lastLength); i++)
00479         {
00480             if (firstName[i] == lastName[i]) {
00481                 result += firstName[i];
00482             }
00483             else {
00484                 break;
00485             }
00486         }
00487     }
00488 
00489     return result; // return absolute pattern
00490 }
00491 
00492 void Binder::matchPattern(string digest, string pattern, Sstring *strings,
00493                           unsigned int patternLength)
00494 {
00495     bool condition;
00496     condition = (digest.substr(0, patternLength) == pattern);
00497 
00498 #ifdef POSIX_REGEX
00499     if (doRegex_) {
00500         condition = regex_match(pattern, digest);
00501     }
00502 #endif
00503 
00504     if (condition) {
00505         strings->insert(digest);
00506     }
00507 }
00508 
00509 void Binder::initRegex(string pattern){
00510 #ifdef POSIX_REGEX
00511     doRegex_ = Util::get(KERNEL->commonSettings(), "autocompletion.mode") == "regex";
00512 #endif
00513 }
00514 
00515 string Binder::queryFramesForPattern(string pattern, Sstring *sFrames)
00516 {
00517 
00518     Workspace *workspace = KERNEL->focusedMonitor()->focused();
00519     CFrame *frames = workspace->frames();
00520     unsigned int patternLength = pattern.length();
00521     string lName;
00522     initRegex(pattern);
00523     for (LFrame::iterator it = frames->begin(); it != frames->end(); it++) {
00524         Frame *frame = *it;
00525         matchPattern(frame->name(), pattern,
00526                      sFrames, patternLength);
00527     }
00528     return absolutePattern(pattern, sFrames, patternLength);
00529 }
00530 
00531 string Binder::queryClientIdsForPattern(string pattern, Sstring *clients)
00532 {
00533 
00534     Monitor *focusedMonitor = KERNEL->focusedMonitor();
00535     MClient *clientMap = focusedMonitor->clients();
00536     unsigned int patternLength = pattern.length();
00537     initRegex(pattern);
00538     for (MClient::iterator it = clientMap->begin();
00539          it != clientMap->end(); it++)
00540     {
00541         Client *client = (*it).second;
00542         if (client->attached()
00543 #ifdef SLOT_SUPPORT
00544                 || client->mode() == Client::SLOT
00545 #endif // SLOT_SUPPORT 
00546            )
00547         {
00548             matchPattern(client->id(), pattern, clients, patternLength);
00549         }
00550     }
00551     return absolutePattern(pattern, clients, pattern.length());
00552 }
00553 
00554 string Binder::queryClientsForPattern(string pattern, Sstring *clients)
00555 {
00556 
00557     Monitor *focusedMonitor = KERNEL->focusedMonitor();
00558     MClient *clientMap = focusedMonitor->clients();
00559     unsigned int patternLength = pattern.length();
00560     initRegex(pattern);
00561     for (MClient::iterator it = clientMap->begin();
00562          it != clientMap->end(); it++)
00563     {
00564         Client *client = (*it).second;
00565         if (client->attached()
00566 #ifdef SLOT_SUPPORT 
00567                 || client->mode() == Client::SLOT
00568 #endif
00569            )
00570         {
00571             matchPattern(client->name(), pattern, clients, patternLength);
00572         }
00573     }
00574     return absolutePattern(pattern, clients, pattern.length());
00575 }
00576 
00577 string Binder::queryDetachedClientsForPattern(string pattern, Sstring *clients)
00578 {
00579 
00580     Monitor *focusedMonitor = KERNEL->focusedMonitor();
00581     CClient *detachedClients = focusedMonitor->detachedClients();
00582     unsigned int patternLength = pattern.length();
00583     initRegex(pattern);
00584     for (LClient::iterator it = detachedClients->begin();
00585          it != detachedClients->end(); it++)
00586     {
00587         Client *client = *it;
00588         matchPattern(client->name(), pattern, clients, patternLength);
00589     }
00590     return absolutePattern(pattern, clients, pattern.length());
00591 }
00592 
00593 string Binder::queryMonitorsForPattern(string pattern, Sstring *monitors) {
00594 
00595     CMonitor *ms = KERNEL->monitors();
00596     unsigned int patternLength = pattern.length();
00597     initRegex(pattern);
00598     for (LMonitor::iterator it = ms->begin(); it != ms->end(); it++) {
00599         matchPattern((*it)->displayString(), pattern, monitors, patternLength);
00600     }
00601 
00602     return absolutePattern(pattern, monitors, patternLength);
00603 }
00604 
00605 string Binder::queryWorkspacesForPattern(string pattern,
00606         Sstring *workspaces)
00607 {
00608 
00609     Monitor *focusedMonitor = KERNEL->focusedMonitor();
00610     unsigned int patternLength = pattern.length();
00611     string wsName;
00612     initRegex(pattern);
00613     for (LWorkspace::iterator it = focusedMonitor->begin();
00614          it != focusedMonitor->end(); it++)
00615     {
00616         matchPattern((*it)->name(), pattern, workspaces, patternLength);
00617     }
00618 
00619     return absolutePattern(pattern, workspaces, patternLength);
00620 }
00621 
00622 string Binder::queryExternChainActionsForPattern(
00623         string pattern, Sstring *actionKeys)
00624 {
00625     unsigned int patternLength = pattern.length();
00626     string actionKey;
00627     Action *action;
00628     initRegex(pattern);
00629     for (MBindings::iterator it = actionBindings_->begin();
00630          it != actionBindings_->end(); it++)
00631     {
00632         actionKey = (*it).first;
00633         action = (*it).second;
00634         if (action->type() == Action::INTERN) {
00635             continue;
00636         }
00637         matchPattern(actionKey, pattern, actionKeys, patternLength);
00638     }
00639 
00640     return absolutePattern(pattern, actionKeys, patternLength);
00641 }
00642 
00643 string Binder::queryActionKeysWithoutValidationForPattern(
00644         string pattern, Sstring *actionKeys)
00645 {
00646     unsigned int patternLength = pattern.length();
00647     string actionKey;
00648     initRegex(pattern);
00649     for (MBindings::iterator it = actionBindings_->begin();
00650          it != actionBindings_->end(); it++)
00651     {
00652         actionKey = (*it).first;
00653         matchPattern(actionKey, pattern, actionKeys, patternLength);
00654     }
00655 
00656     return absolutePattern(pattern, actionKeys, patternLength);
00657 }
00658 
00659 string Binder::queryActionKeysForPattern(string pattern, Sstring *actionKeys) {
00660 
00661     unsigned int patternLength = pattern.length();
00662     string actionKey;
00663     initRegex(pattern);
00664     for (MBindings::iterator it = actionBindings_->begin();
00665          it != actionBindings_->end(); it++)
00666     {
00667         Action *action = (*it).second;
00668 
00669         if (action->isValid()) {
00670             actionKey = (*it).first;
00671             matchPattern(actionKey, pattern, actionKeys, patternLength);
00672         }
00673     }
00674 
00675     return absolutePattern(pattern, actionKeys, patternLength);
00676 }
00677 
00678 string Binder::queryCommandForPattern(string pattern, Sstring *expands) {
00679 
00680     Expander::instance()->queryString(pattern);
00681     Sstring exp = Expander::instance()->expands();
00682     initRegex(pattern);
00683 
00684 
00685     unsigned int offset  = pattern.find_last_of('/');
00686     if (offset == string::npos) offset=0; else offset++; 
00687 
00688 #ifdef POSIX_REGEX
00689     doRegex_ = doRegex_ && (offset == 0);
00690 #endif
00691 
00692     for (Sstring::iterator it = exp.begin();
00693         it != exp.end(); it++)
00694     {
00695     matchPattern((string)(*it), pattern.substr(offset), expands, pattern.length()-offset);
00696     }
00697 
00698     return absolutePattern(pattern, expands, pattern.length() -
00699             pattern.find_last_of('/') - 1);
00700 }
00701 
00702 #define NUM_MASKS 8
00703 
00704 void Binder::initLockModifiers() {
00705     XModifierKeymap *modmap;
00706     KeyCode numLock, scrollLock;
00707 
00708     // preinit
00709     numLockMask_ = scrollLockMask_ = 0;
00710 
00711     // init modifier map
00712     modmap = XCORE->modifierMapping();
00713 
00714     // modifier masks we know
00715     static int masks[NUM_MASKS] = {
00716         ShiftMask, LockMask, ControlMask, Mod1Mask,
00717         Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
00718     };
00719 
00720     // temporary keysyms of evil keys
00721     numLock = XCORE->stringToKeyCode("Num_Lock");
00722     scrollLock = XCORE->stringToKeyCode("Scroll_Lock");
00723 
00724     if (modmap && modmap->max_keypermod > 0) {
00725         unsigned int max = NUM_MASKS * modmap->max_keypermod;
00726         for (unsigned int i = 0; i < max; i++) {
00727             if (numLock && (modmap->modifiermap[i] == numLock)) {
00728                 numLockMask_ = masks[i / modmap->max_keypermod];
00729             }
00730             else if (scrollLock && (modmap->modifiermap[i] == scrollLock)) {
00731                 scrollLockMask_ = masks[i / modmap->max_keypermod];
00732             }
00733         }
00734     }
00735 
00736     XCORE->freeModifierMapping(modmap);
00737     validModMask_ = 255 & ~(numLockMask_ | scrollLockMask_ | LockMask);
00738 }
00739 
00740 unsigned int Binder::validModMask() const {
00741     return validModMask_;
00742 }

Generated on Thu May 24 15:19:31 2007 for ncwm by  doxygen 1.5.1