wmi

git clone git://oldgit.suckless.org/wmi/
Log | Files | Refs | LICENSE

util.cpp (10822B)


      1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us>
      2 // See LICENSE for license details.
      3 
      4 extern "C" {
      5 #include <unistd.h>
      6 #include <stdlib.h>
      7 #include <X11/Xlib.h>
      8 }
      9 
     10 #include <sstream>
     11 #include <iostream>
     12 
     13 #include "util.h"
     14 
     15 #include "action.h"
     16 
     17 #include "rectangle.h"
     18 
     19 Util::Util() {
     20 }
     21 
     22 Util::~Util() {
     23 }
     24 
     25 string Util::lowerCase(string str) {
     26     string input = str;
     27 
     28     for (string::iterator it = input.begin(); it != input.end(); it++) {
     29         *it = tolower(*it);
     30     }
     31 
     32     return input;
     33 }
     34 
     35 bool Util::containsWhitespaces(string str) {
     36 
     37     for (string::iterator it = str.begin(); it != str.end(); it++) {
     38         if (*it == ' ' || *it == '\t') {
     39             return true;
     40         }
     41     }
     42 
     43     return false;
     44 }
     45 
     46 string Util::truncate(string str, char c) {
     47 
     48     string result = "";
     49 
     50     for (string::iterator it = str.begin(); it != str.end(); it++) {
     51         if ((*it != c) && (*it != '\t')) {
     52             result += *it;
     53         }
     54     }
     55 
     56     return result;
     57 }
     58 
     59 string Util::canonicalDir(string path) {
     60     string dir = canonicalPath(path);
     61     unsigned int pos = 0;
     62 
     63     pos = dir.find_last_of('/');
     64     if (pos != string::npos) {
     65         dir = dir.substr(0, pos);
     66     }
     67 
     68     return dir;
     69 }
     70 
     71 string Util::canonicalPath(string file) {
     72 
     73     string result = "";
     74     for (string::iterator it = file.begin(); it != file.end(); it++) {
     75 
     76         if (*it == '~') { // found HOME
     77             char *home = getenv("HOME");
     78             // Note: if home would be 0, WMI won't have started
     79             // but who knows what boxes there're around :)
     80             if (home == 0) {
     81                 cerr << "wmi[E " << timestamp() << "]: "
     82                      << "Util::canonicalPath() cannot determine your "
     83                      << "$HOME directory, giving up";
     84                 exit(1);
     85             }
     86 
     87             result += home;
     88         }
     89         else {
     90             result += *it;
     91         }
     92     }
     93     return result;
     94 }
     95 
     96 string Util::encodeEscapes(string str) {
     97     string encoded = "";
     98 
     99     for (string::iterator it = str.begin(); it != str.end(); it++) {
    100         switch (*it) {
    101         case '\\':
    102             encoded += "\\\\";
    103             break;
    104         case '#':
    105             encoded += "\\#";
    106             break;
    107         case '"':
    108             encoded += "\\\"";
    109             break;
    110         case '=':
    111             encoded += "\\=";
    112             break;
    113         default:
    114             encoded += *it;
    115             break;
    116         }
    117     }
    118 
    119     return encoded;
    120 }
    121 
    122 string Util::lastToken(string str, char delim) {
    123 
    124     string result = "";
    125     unsigned int pos = str.find_last_of(delim);
    126 
    127     if (pos != string::npos) {
    128         result = str.substr(pos + 1, str.length() - pos);
    129     }
    130 
    131     return result;
    132 }
    133 
    134 string Util::nthToken(string str, char delim, unsigned int n) {
    135 
    136     unsigned int delimCounter = 1;
    137     string token = "";
    138 
    139     for (string::iterator it = str.begin(); it != str.end(); it++) {
    140 
    141         if (*it == delim) {
    142             delimCounter++;
    143             continue;
    144         }
    145 
    146 
    147         if (delimCounter == n) {
    148             token += *it;
    149         }
    150         else if (delimCounter > n) {
    151             return token; // token ready
    152         }
    153     }
    154 
    155     return token;
    156 }
    157 
    158 char **Util::arguments(string command) {
    159 
    160     string arg = "";
    161     list<const char *> args;
    162 
    163     bool proceed = true;
    164     for (string::iterator it = command.begin(); proceed; it++) {
    165 
    166         proceed = it != command.end();
    167         if (!proceed || (*it == ' ') || (*it == '\t'))
    168         {
    169             if (arg.length() > 0) {
    170                 args.push_back((new string(arg))->c_str());
    171             }
    172             arg = "";
    173         }
    174         else {
    175             arg += *it;
    176         }
    177     }
    178 
    179     const char **result = new const char *[args.size() + 1];
    180     unsigned int i = 0;
    181     for (list<const char *>::iterator it = args.begin();
    182          it != args.end(); it++, i++)
    183     {
    184         result[i] = *it;
    185     }
    186     result[i] = 0;
    187 
    188     return (char **)result;
    189 }
    190 
    191 unsigned int Util::numDigits(unsigned int number)
    192 {
    193     unsigned int n = 0;
    194     do {
    195         ++n; number /= 10;
    196     } while (number);
    197 
    198     return n;
    199 }
    200 
    201 string Util::timestamp() {
    202     static time_t utctime;
    203     static struct tm *todaylocal;
    204     static char timestamp[16];
    205     time(&utctime);
    206     todaylocal = localtime(&utctime);
    207     strftime(timestamp, 16,"%Y%m%d%H%M%S", todaylocal);
    208 
    209     return (string)timestamp;
    210 }
    211 
    212 string Util::stringForButton(unsigned int button) {
    213     ostringstream oss;
    214 
    215     oss << "Button" << button;
    216     return oss.str();
    217 }
    218 
    219 unsigned int Util::buttonForString(string button) {
    220 
    221     if (button.find("Button1") != string::npos) {
    222         return Button1;
    223     }
    224     else if (button.find("Button2") != string::npos) {
    225         return Button2;
    226     }
    227     else if (button.find("Button3") != string::npos) {
    228         return Button3;
    229     }
    230     else if (button.find("Button4") != string::npos) {
    231         return Button4;
    232     }
    233     else if (button.find("Button5") != string::npos) {
    234         return Button5;
    235     }
    236 
    237     return 0;
    238 }
    239 
    240 string Util::stringForModMask(unsigned long modMask) {
    241 
    242     string result = "";
    243     if (modMask & ShiftMask) {
    244         result += "shift + ";
    245     }
    246     if (modMask & LockMask) {
    247         result += "lock + ";
    248     }
    249     if (modMask & ControlMask) {
    250         result += "ctrl + ";
    251     }
    252     if (modMask & Mod1Mask) {
    253         result += "mod1 + ";
    254     }
    255     if (modMask & Mod2Mask) {
    256         result += "mod2 + ";
    257     }
    258     if (modMask & Mod3Mask) {
    259         result += "mod3 + ";
    260     }
    261     if (modMask & Mod4Mask) {
    262         result += "mod4 + ";
    263     }
    264     if (modMask & Mod5Mask) {
    265         result += "mod5 + ";
    266     }
    267     if (!modMask) {
    268         result += "none + ";
    269     }
    270     return result;
    271 }
    272 
    273 unsigned long Util::modMaskForString(string modKeys)
    274 {
    275     unsigned long modMask = 0;
    276     if (modKeys.find("shift") != string::npos) {
    277         modMask |= ShiftMask;
    278     }
    279     if (modKeys.find("lock") != string::npos) {
    280         modMask |= LockMask;
    281     }
    282     if ((modKeys.find("control") != string::npos) ||
    283         (modKeys.find("ctrl") != string::npos)) {
    284         modMask |= ControlMask;
    285     }
    286     if ((modKeys.find("alt") != string::npos) ||
    287         (modKeys.find("mod1") != string::npos)) {
    288         modMask |= Mod1Mask;
    289     }
    290     if (modKeys.find("mod2") != string::npos) {
    291         modMask |= Mod2Mask;
    292     }
    293     if (modKeys.find("mod3") != string::npos) {
    294         modMask |= Mod3Mask;
    295     }
    296     if (modKeys.find("mod4") != string::npos) {
    297         modMask |= Mod4Mask;
    298     }
    299     if (modKeys.find("mod5") != string::npos) {
    300         modMask |= Mod5Mask;
    301     }
    302     return modMask;
    303 }
    304 
    305 unsigned int Util::strToUInt(string str) {
    306 
    307     return atoi(str.c_str());
    308 }
    309 
    310 void Util::fitIntoDirection(int horigin, int hw, int *corigin, int *cw)
    311 {
    312     int horigin1 = horigin;
    313     int horigin2 = horigin + hw;
    314     int corigin1 = *corigin;
    315     int corigin2 = *corigin + *cw;
    316 
    317     if ((corigin1 < horigin1) && (corigin2 <= horigin2)) {
    318         *corigin = horigin;
    319         if (*corigin + *cw > horigin2) {
    320             *cw = hw;
    321         }
    322     }
    323     else if ((corigin1 < horigin1) && (corigin2 > horigin2)) {
    324         *corigin = horigin;
    325         *cw = hw;
    326     }
    327     else if ((corigin1 >= horigin1) && (corigin2 > horigin2)) {
    328         *cw = horigin2 - *corigin;
    329     }
    330 }
    331 
    332 
    333 void Util::fitInto(Rectangle *client, Rectangle *host) {
    334 
    335     int cx = client->x();
    336     int cw = client->width();
    337 
    338     fitIntoDirection(host->x(), host->width(), &cx, &cw);
    339     client->setX(cx);
    340     client->setWidth(cw);
    341 
    342     int cy = client->y();
    343     int ch = client->height();
    344 
    345     fitIntoDirection(host->y(), host->height(), &cy, &ch);
    346     client->setY(cy);
    347     client->setHeight(ch);
    348 }
    349 
    350 Direction Util::dirForString(string str) {
    351 
    352     string dirStr;
    353 
    354     dirStr = lowerCase(str);
    355 
    356     if (dirStr == "left") {
    357         return LEFT;
    358     }
    359     else if (dirStr == "right") {
    360         return RIGHT;
    361     }
    362     else if (dirStr == "up") {
    363         return UP;
    364     }
    365     else {
    366         return DOWN;
    367     }
    368 }
    369 
    370 bool Util::exists(const char *path) {
    371 
    372     return access(path, F_OK) == 0;
    373 }
    374 
    375 string Util::shortenString(string str, unsigned int n) {
    376 
    377     return str.substr(0, n) + "...";
    378 }
    379 
    380 
    381 set<string> Util::stringSplit(string s, string delimiter){
    382     set<string> res;
    383     unsigned int pos = 0;
    384     while (pos != string::npos){
    385         pos = s.find_first_of(delimiter);
    386         res.insert(s.substr(0, pos));
    387         s.erase(0, pos + 1);
    388     }
    389     return(res);
    390 }
    391 
    392 string Util::trimL(string s){
    393     return s.substr(s.find_first_not_of(' '));
    394 }
    395 
    396 
    397 bool Util::isPointWithinRect(unsigned int x, unsigned int y, Rectangle *rect,
    398                         Rectangle *offset)
    399 {
    400     unsigned int offsetX = rect->x();
    401     unsigned int offsetY = rect->y();
    402     if (offset) {
    403         offsetX += offset->x();
    404         offsetY += offset->y();
    405     }
    406 
    407     return ((offsetX <= x) && (offsetY <= y) &&
    408             (offsetX + rect->width() >= x) &&
    409             (offsetY + rect->height() >= y));
    410 }
    411 
    412 
    413 void Util::swapChars(string *str, char from, char to,
    414                        unsigned int *swapCount)
    415 {
    416     for (string::iterator it = str->begin(); it != str->end(); it++) {
    417         if (*it == from) {
    418             *it = to;
    419             if (swapCount) {
    420                 (*swapCount)++;
    421             }
    422         }
    423     }
    424 }
    425 
    426 Direction Util::reverseDir(Direction dir) {
    427     switch (dir) {
    428     case LEFT:
    429         return RIGHT;
    430         break;
    431     case RIGHT:
    432         return LEFT;
    433         break;
    434     case UP:
    435         return DOWN;
    436         break;
    437     case DOWN:
    438         return UP;
    439         break;
    440     case NORTH_WEST:
    441         return SOUTH_EAST;
    442         break;
    443     case NORTH_EAST:
    444         return SOUTH_WEST;
    445         break;
    446     case SOUTH_WEST:
    447         return NORTH_EAST;
    448         break;
    449     case SOUTH_EAST:
    450         return NORTH_WEST;
    451         break;
    452     }
    453     return LEFT;
    454 }
    455 
    456 string Util::get(MSettings *settings, string key) {
    457     MSettings::iterator it = settings->find(key);
    458     return (it != settings->end()) ? (*it).second : "";
    459 }
    460 
    461 void Util::remove(MSettings *settings, string prefix) {
    462 
    463     unsigned int length = prefix.length();
    464     for (MSettings::iterator it = settings->begin();
    465             it != settings->end(); it++)
    466     {
    467         string key = (*it).first;
    468         if (key.length() >= length) {
    469             if (key.substr(0, length) == prefix) {
    470                 settings->erase(it);
    471             }
    472         }
    473     }
    474 }
    475 
    476 Action *Util::get(MBindings *bindings, string key) {
    477     MBindings::iterator it = bindings->find(key);
    478     return (it != bindings->end()) ? (*it).second : 0;
    479 }
    480 
    481 void Util::remove(MBindings *bindings, string prefix) {
    482 
    483     unsigned int length = prefix.length();
    484     for (MBindings::iterator it = bindings->begin();
    485             it != bindings->end(); it++)
    486     {
    487         string key = (*it).first;
    488         if (key.length() >= length) {
    489             if (key.substr(0, length) == prefix) {
    490                 bindings->erase(it);
    491             }
    492         }
    493     }
    494 }