wmi

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

xcore.cpp (17254B)


      1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us>
      2 // See LICENSE for license details.
      3 
      4 #include "xcore.h"
      5 
      6 extern "C" {
      7 #include <X11/Xatom.h>
      8 #include <X11/Xproto.h>
      9 }
     10 
     11 #include <sstream>
     12 
     13 #include "atoms.h"
     14 #include "font.h"
     15 #include "kernel.h"
     16 #include "logger.h"
     17 #include "rectangle.h"
     18 
     19 #include "xfont.h"
     20 #include "xftfont.h"
     21 
     22 XCore::XCore() {}
     23 
     24 XCore::~XCore() {}
     25 
     26 void XCore::setDisplay(Display *display) {
     27     display_ = display;
     28 }
     29 
     30 Window XCore::createWindow(Window root, XSetWindowAttributes *attr,
     31                            int x, int y, unsigned int w, unsigned int h,
     32                            unsigned long mask)
     33 {
     34     return XCreateWindow(display_, root, x, y, w, h, 0,
     35                          CopyFromParent, InputOutput, CopyFromParent,
     36                          mask, attr);
     37 }
     38 
     39 void XCore::sendEvent(Window window, unsigned long mask, XEvent *event) {
     40     XSendEvent(display_, window, True, mask, event);
     41 }
     42 
     43 void XCore::maskEvent(unsigned long mask, XEvent *event) {
     44     XMaskEvent(display_, mask, event);
     45 }
     46 
     47 void XCore::selectEvents(Window window, long mask) {
     48     XSelectInput(display_, window, mask);
     49 }
     50 
     51 void XCore::show(Window window) {
     52     XMapWindow(display_, window);
     53 }
     54 
     55 void XCore::showRaised(Window window) {
     56     XMapRaised(display_, window);
     57 }
     58 
     59 void XCore::hide(Window window) {
     60     XUnmapWindow(display_, window);
     61 }
     62 
     63 GC XCore::createGC(Window window, unsigned long mask, XGCValues *gcv) {
     64     return XCreateGC(display_, window, mask, gcv); 
     65 }
     66 
     67 void XCore::ungrabKey(Window window, unsigned int modMask, KeyCode keycode)
     68 {
     69     XUngrabKey(display_, keycode, modMask, window);
     70 }
     71 
     72 void XCore::grabKeyboard(Window window) {
     73     XGrabKeyboard(display_, window, True, GrabModeAsync,
     74                   GrabModeAsync, CurrentTime);
     75 }
     76 
     77 void XCore::ungrabKeyboard() {
     78     XUngrabKeyboard(display_, CurrentTime);
     79 }
     80 
     81 void XCore::free(void *data) {
     82     XFree(data);
     83 }
     84 
     85 void XCore::freeCursor(Cursor cursor) {
     86     XFreeCursor(display_, cursor);
     87 }
     88 
     89 void XCore::sync(bool discard) {
     90     XSync(display_, discard);
     91 }
     92 
     93 void XCore::setForeground(GC gc, unsigned long color) {
     94     XSetForeground(display_, gc, color);
     95 }
     96 
     97 void XCore::drawLines(Window window, GC gc, XPoint *points, unsigned int num)
     98 {
     99     XDrawLines(display_, window, gc, points, num,
    100                CoordModeOrigin);
    101 }
    102 
    103 void XCore::drawRectangle(Window window, GC gc, int x, int y,
    104                           unsigned int w, unsigned int h)
    105 {
    106     XDrawRectangle(display_, window, gc, x, y, w, h);
    107 }
    108 
    109 void XCore::drawRectangle(Window window, GC gc, Rectangle *rect) {
    110     XDrawRectangle(display_, window, gc, rect->x(), rect->y(),
    111                     rect->width(), rect->height());
    112 }
    113 
    114 void XCore::drawLine(Window window, GC gc, unsigned int x1, unsigned int y1,
    115                      unsigned int x2, unsigned int y2)
    116 {
    117     XDrawLine(display_, window, gc, x1, y1, x2, y2);
    118 }
    119 
    120 void XCore::clearArea(Window window, Rectangle *rect) {
    121     XClearArea(display_, window, rect->x(), rect->y(),
    122                rect->width(), rect->height(), False);
    123 }
    124 
    125 void XCore::clearArea(Window window, int x, int y, unsigned int w, unsigned int h) {
    126     XClearArea(display_, window, x, y, w, h, False);
    127 }
    128 
    129 void XCore::clearWindow(Window window) {
    130     XClearWindow(display_, window);
    131 }
    132 
    133 void XCore::fillRectangle(Window window, GC gc, Rectangle *rect) {
    134     XFillRectangle(display_, window, gc, rect->x(), rect->y(),
    135                    rect->width(), rect->height());
    136 }
    137 
    138 void XCore::fillRectangle(Window window, GC gc, int x, int y,
    139                           unsigned int w, unsigned int h)
    140 {
    141     XFillRectangle(display_, window, gc, x, y, w, h);
    142 }
    143 
    144 XFontStruct *XCore::loadQueryFont(string name) {
    145     return XLoadQueryFont(display_, name.c_str());
    146 }
    147 
    148 void XCore::drawText(Window window, GC gc, int x, int y,
    149                        string text)
    150 {
    151     XDrawString(display_, window, gc, x, y,
    152                 text.c_str(), text.length());
    153 }
    154 
    155 int XCore::textWidth(XFontStruct *font, string text) {
    156     return XTextWidth(font, text.c_str(), text.length());
    157 }
    158 
    159 #ifdef XFT_SUPPORT
    160 XftFont *XCore::xftOpenFontName(unsigned int screen, string name) {
    161     return XftFontOpenName(display_, screen, name.c_str());
    162 }
    163 
    164 void XCore::xftCloseFont(XftFont *font) {
    165     if (font != 0) {
    166         XftFontClose(display_, font);
    167     }
    168 }
    169 
    170 int XCore::textWidth(XftFont *font, string text) {
    171 
    172     if (font == 0) {
    173         return 0;
    174     }
    175     XGlyphInfo ginfo;
    176     XftTextExtents8(display_, font, (XftChar8 *)text.c_str(),
    177                     text.length(), &ginfo);
    178     return ginfo.xOff;
    179 }
    180 
    181 void XCore::drawText(XftFont *font, Window window, GC gc,
    182                      unsigned int screen, int x, int y, string text)
    183 {
    184     if (font == 0) {
    185         return;
    186     }
    187 
    188     Visual *visual = DefaultVisual(display_, screen);
    189     Colormap cmap = DefaultColormap(display_, screen);
    190 
    191     XftDraw *draw = XftDrawCreate(display_, window, visual, cmap);
    192 
    193     XGCValues gcv;
    194 
    195     // foreground pixel for XRenderColor value
    196     XGetGCValues(display_, gc, GCForeground, &gcv);
    197 
    198     // RGB values
    199     XColor color;
    200     color.pixel = gcv.foreground;
    201     XQueryColor(display_, cmap, &color);
    202 
    203     XRenderColor renderColor;
    204     renderColor.red = color.red;
    205     renderColor.green = color.green;
    206     renderColor.blue = color.blue;
    207     renderColor.alpha = 0xFFFF;
    208     XftColor xftColor;  
    209     XftColorAllocValue(display_, visual, cmap, &renderColor, &xftColor);
    210 
    211     // draw text
    212     XftDrawString8(draw, &xftColor, font, x, y,
    213                    (XftChar8 *)(text.c_str()), text.length());
    214 
    215     // clean up
    216     XftColorFree(display_, visual, cmap, &xftColor);
    217     XftDrawDestroy(draw);
    218 }
    219 
    220 #endif // XFT_SUPPORT
    221 
    222 string XCore::className(Window window) {
    223     XClassHint classHints;
    224 
    225     if (XGetClassHint(display_, window, &classHints) != 0) {
    226         return (string)classHints.res_class;
    227     }
    228     return "";
    229 }
    230 
    231 string XCore::instanceName(Window window) {
    232     XClassHint classHints;
    233 
    234     if (XGetClassHint(display_, window, &classHints) != 0) {
    235         return (string)classHints.res_name;
    236     }
    237     return "";
    238 }
    239 
    240 int XCore::state(Window window) {
    241 
    242     // state hints
    243     XWMHints *hints = XGetWMHints(display_, window);
    244     int result;
    245 
    246     long *prop = 0;
    247     if (property(window, Atoms::WM_STATE, Atoms::WM_STATE,
    248                 2L, (unsigned char**)&prop) > 0)
    249     {
    250         result = (int)*prop;
    251         free((long *)prop);
    252     }
    253     else {
    254         result = hints ? hints->initial_state : NormalState;
    255     }
    256 
    257     if (hints) {
    258         free(hints);
    259     }
    260 
    261     return result;
    262 }
    263 
    264 void XCore::setState(Window window, int state) {
    265 
    266     long data[2];
    267     data[0] = (long)state;
    268     data[1] = (long)None;
    269 
    270     XChangeProperty(display_, window,
    271             Atoms::WM_STATE, Atoms::WM_STATE,
    272             32, PropModeReplace, (unsigned char *)data, 2);
    273 }
    274 
    275 string XCore::atomValue(Window window, Atom atom) {
    276 
    277     string result;
    278     unsigned char *prop;
    279 
    280     if (property(window, atom, XA_STRING, 100L, &prop) > 0) {
    281         result = (char *)prop;
    282         free((char *)prop);
    283     }
    284     else {
    285         result = "";
    286     }
    287 
    288     return result;
    289 }
    290 
    291 void XCore::sizeHints(Window window, XSizeHints *sizeHints) {
    292     long msize;
    293     // size hints
    294     XGetWMNormalHints(display_, window, sizeHints, &msize);
    295 }
    296 
    297 void XCore::updateSize(Window window,
    298                        unsigned int *minW, unsigned int *minH,
    299                        unsigned int *maxW, unsigned int *maxH,
    300                        bool *isCentered)
    301 {
    302     XSizeHints sizeHints;
    303     long msize;
    304 
    305     // size hints
    306     if (!XGetWMNormalHints(display_, window, &sizeHints, &msize)
    307             || !sizeHints.flags)
    308     {
    309         sizeHints.flags = PSize;
    310     }
    311 
    312     *isCentered = !((sizeHints.flags & USPosition) ||
    313                     (sizeHints.flags & PPosition));
    314 
    315     // minimal dimensions 
    316     if (sizeHints.flags & PBaseSize) {
    317         *minW = sizeHints.base_width;
    318         *minH = sizeHints.base_height;
    319     }
    320     else if (sizeHints.flags & PMinSize) {
    321         *minW = sizeHints.min_width;
    322         *minH = sizeHints.min_height;
    323     }
    324     else {
    325         *minW = *minH = 23;
    326     }
    327 
    328     // maximal dimensions 
    329     if (sizeHints.flags & PMaxSize) {
    330         *maxW = sizeHints.max_width;
    331         *maxH = sizeHints.max_height;
    332     }
    333 }
    334 
    335 bool XCore::hasDecoration(Window window) {
    336 
    337     MWMHints *mwmHints = 0;
    338     long result = property(window, Atoms::MWM_HINTS,
    339                            Atoms::MWM_HINTS, 5, (unsigned char **)
    340                            &mwmHints);
    341 
    342     if ((result >= 0) && mwmHints) {
    343         bool decor = !(mwmHints->decorations == 0 &&
    344                        (mwmHints->flags & MWM_HINTS_DECORATIONS));
    345         free((void *)mwmHints);
    346         return decor;
    347     }
    348     // fallback, assumes decoration
    349     return true;
    350 }
    351 
    352 Window XCore::transient(Window window) {
    353     Window trans;
    354 
    355     if (!XGetTransientForHint(display_, window, &trans)) {
    356         return 0;
    357     }
    358     return trans;
    359 }
    360 
    361 int XCore::property(Window window, Atom atom, Atom type,
    362                     long length, unsigned char **prop)
    363 {
    364     Atom realType;
    365     int format;
    366     unsigned long result, extra;
    367     int status;
    368 
    369     status = XGetWindowProperty(display_, window,
    370             atom, 0L, length,
    371             False, type, &realType, &format,
    372             &result,
    373             &extra,
    374             prop);
    375 
    376     if (status != Success || *prop == 0) {
    377         return 0;
    378     }
    379     if (result == 0) {
    380         free((void*) *prop);
    381     }
    382 
    383     return result;
    384 }
    385 
    386 void XCore::configureWindow(Window window, unsigned int mask, XWindowChanges *wc) {
    387 
    388     XConfigureWindow(display_, window, mask, wc);
    389 }
    390 
    391 void XCore::configure(Window window, XConfigureEvent *event) {
    392     XSendEvent(display_, window, False, StructureNotifyMask,
    393                (XEvent *)event);
    394     XFlush(display_);
    395 }
    396 
    397 int XCore::protocols(Window window) {
    398     Atom *protocols;
    399     long result;
    400     int protos = 0;
    401 
    402     result = property(window, Atoms::WM_PROTOCOLS, XA_ATOM,
    403                       20L, (unsigned char **) &protocols);
    404     if (result <= 0) {
    405         return protos;
    406     }
    407 
    408     for (int i = 0; i < result; i++) {
    409         if (protocols[i] == Atoms::WM_DELETE) {
    410             protos |= PDELETE;
    411         }
    412         else if (protocols[i] == Atoms::WM_TAKE_FOCUS) {
    413             protos |= PTAKEFOCUS;
    414         }
    415     }
    416     free((char *) protocols);
    417     return protos;
    418 }
    419 
    420 void XCore::sendMessage(Window window, Atom atom, long value) {
    421 
    422     XEvent event;
    423     event.type = ClientMessage;
    424     event.xclient.window = window;
    425     event.xclient.message_type = atom;
    426     event.xclient.format = 32;
    427     event.xclient.data.l[0] = value;
    428     event.xclient.data.l[1] = CurrentTime;
    429 
    430     XSendEvent(display_, window, False, NoEventMask, &event);
    431     XFlush(display_);
    432 }
    433 
    434 void XCore::kill(Window window, int protos) {
    435 
    436     if (protos & PDELETE) {
    437         sendMessage(window, Atoms::WM_PROTOCOLS, Atoms::WM_DELETE);
    438     }
    439     else {
    440         XKillClient(display_, window);
    441     }
    442 }
    443 
    444 void XCore::moveResize(Window window, Rectangle *rect) {
    445     XMoveResizeWindow(display_, window, rect->x(), rect->y(),
    446                       rect->width(), rect->height());
    447 }
    448 
    449 void XCore::destroy(Window window) {
    450     XDestroyWindow(display_, window);
    451 }
    452 
    453 void XCore::raise(Window window) {
    454     XRaiseWindow(display_, window);
    455 }
    456 
    457 void XCore::lower(Window window) {
    458     XLowerWindow(display_, window);
    459 }
    460 
    461 void XCore::reparent(Window child, Window parent, int x, int y) {
    462     XReparentWindow(display_, child, parent, x, y);
    463 }
    464 
    465 void XCore::setInputFocus(Window window) {
    466     XSetInputFocus(display_, window, RevertToPointerRoot, CurrentTime);
    467 }
    468 
    469 void XCore::grabKey(Window window, unsigned int modMask, KeyCode keycode) {
    470     XGrabKey(display_, keycode, modMask, window, True, GrabModeAsync,
    471              GrabModeAsync);
    472 }
    473 
    474 void XCore::grabButton(Window window, unsigned int modMask, unsigned int button) {
    475     XGrabButton(display_, button, modMask, window, False,
    476                 ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
    477                 GrabModeAsync, None, None);
    478 }
    479 
    480 void XCore::ungrabButton(Window window, unsigned int modMask, unsigned int button) {
    481     XUngrabButton(display_, button, modMask, window);
    482 }
    483 
    484 void XCore::setWindowAttributes(Window window, unsigned int mask,
    485                                 XSetWindowAttributes *attr)
    486 {
    487     XChangeWindowAttributes(display_, window, mask, attr);
    488 }
    489 
    490 void XCore::windowAttributes(Window window, XWindowAttributes *attr)
    491 {
    492 
    493     XGetWindowAttributes(display_, window, attr);
    494 }
    495 
    496 Atom XCore::internAtom(string atom) {
    497     return XInternAtom(display_, atom.c_str(), False);
    498 }
    499 
    500 
    501 Cursor XCore::createFontCursor(unsigned int cursor) {
    502     return XCreateFontCursor(display_, cursor);
    503 }
    504 
    505 
    506 string XCore::atomName(Atom atom) {
    507     return (string)XGetAtomName(display_, atom);
    508 }
    509 
    510 
    511 void XCore::nextEvent(XEvent *event) {
    512     XNextEvent(display_, event);
    513 }
    514 
    515 bool XCore::checkMaskEvent(long mask, XEvent *event) {
    516     return XCheckMaskEvent(display_, mask, event);
    517 }
    518 
    519 KeyCode XCore::stringToKeyCode(string key) {
    520     KeySym keySym = XStringToKeysym(key.c_str());
    521     if (keySym) {
    522         return XKeysymToKeycode(display_, keySym);
    523     }
    524     return 0;
    525 }
    526 
    527 KeySym XCore::keyCodeToKeySym(KeyCode keyCode) {
    528     return XKeycodeToKeysym(display_, keyCode, 0);
    529 }
    530 
    531 string XCore::keyCodeToString(KeyCode keyCode) {
    532     KeySym keySym = XKeycodeToKeysym(display_, keyCode, 0);
    533     if (keySym) {
    534         return XKeysymToString(XKeycodeToKeysym(display_, keyCode, 0));
    535     }
    536     return "";
    537 }
    538 
    539 void XCore::grabServer() {
    540     XGrabServer(display_);
    541 }
    542 
    543 void XCore::ungrabServer() {
    544     XUngrabServer(display_);
    545 }
    546 
    547 void XCore::grabPointer(Window window, unsigned int mask,
    548                         Time time, Cursor cursor)
    549 {
    550 
    551     XGrabPointer(display_, window, False, mask,
    552                         GrabModeAsync, GrabModeAsync,
    553                         None, cursor, time);
    554 }
    555 
    556 void XCore::ungrabPointer(Time time) {
    557     XUngrabPointer(display_, time);
    558 }
    559 
    560 void XCore::translateCoordinates(Window child, Window parent,
    561                                  int srcX, int srcY, int *destX, int *destY)
    562 {
    563 
    564     Window dummy;
    565     XTranslateCoordinates(display_, child, parent, srcX, srcY,
    566                           destX, destY, &dummy);
    567 }
    568 
    569 bool XCore::allocNamedColor(Colormap colormap, string name, XColor *color) {
    570     return XAllocNamedColor(display_, colormap, name.c_str(),
    571                             color, color);
    572 }
    573 
    574 void XCore::installColormap(Colormap colormap) {
    575     XInstallColormap(display_, colormap);
    576 }
    577 
    578 KeySym XCore::lookupNextKeySym(XKeyEvent *event, int *count, char *buffer) {
    579     KeySym result;
    580     *count = XLookupString(event, buffer, 32, &result, 0);
    581     return result;
    582 }
    583 
    584 bool XCore::textProperty(Window window, Atom atom, string *value) {
    585     XTextProperty property;
    586 
    587     if (XGetTextProperty(display_, window, &property, atom)) {
    588 
    589         if (property.nitems > 0) {
    590             *value = (const char *)property.value;
    591         }
    592         else {
    593             *value = "";
    594         }
    595         free(property.value);
    596         return true;
    597     }
    598     return false;
    599 }
    600 
    601 void XCore::queryTree(Window root, Window **windows, unsigned int *num) {
    602 
    603     Window rootReturn, parentReturn;
    604 
    605     XQueryTree(display_, root, &rootReturn,
    606                &parentReturn, windows, num);
    607 }
    608 
    609 // X error manager
    610 int XCore::handleErrors(Display *display, XErrorEvent *e)
    611 {
    612     Logger *log = Logger::instance();
    613     Kernel *kernel = Kernel::instance();
    614 
    615     if ((kernel->runlevel() == Kernel::START) &&
    616         (e->request_code == X_ChangeWindowAttributes) &&
    617         (e->error_code == BadAccess))
    618     {
    619         log->error("seems, that there's running another window manager", true);
    620         // exits wmi
    621     }
    622 
    623     char errtxt[128];
    624 
    625     XGetErrorText(kernel->display(), e->error_code, errtxt, 128);
    626     ostringstream oss;
    627     oss << errtxt << "(" << (int)e->error_code << ") opcodes "
    628         << (int)e->request_code << "/" << (int)e->minor_code 
    629         << " resource 0x"<< hex << (int)e->resourceid;
    630     log->warning(oss.str());
    631 
    632 #ifdef DEBUG
    633     XTextProperty property;
    634 
    635     char *text = (char *)oss.str().c_str();
    636     XStringListToTextProperty(&text, 1, &property);
    637     XSetTextProperty(kernel->display(), kernel->defaultRootWindow(), &property,
    638                      Atoms::WMI_STATUSTEXT);
    639 #endif
    640 
    641     return 0;
    642 }
    643 
    644 void XCore::setTextProperty(Display *display, Window window,
    645                             XTextProperty *textProperty, Atom atom)
    646 {
    647     XSetTextProperty(display, window, textProperty, atom);
    648 }
    649 
    650 void XCore::stringListToTextProperty(string text, XTextProperty *textProperty)
    651 {
    652     char *txt = (char *)text.c_str();
    653     XStringListToTextProperty(&txt, 1, textProperty);
    654 }
    655 
    656 Colormap XCore::defaultColormap(unsigned int id) {
    657     return DefaultColormap(display_, id);
    658 }
    659 
    660 XModifierKeymap *XCore::modifierMapping() {
    661     return XGetModifierMapping(display_);
    662 }
    663 
    664 void XCore::freeModifierMapping(XModifierKeymap *modmap) {
    665     if (modmap) {
    666         XFreeModifiermap(modmap);
    667     }
    668 }
    669 
    670 void XCore::addToSaveSet(Window window) {
    671     XAddToSaveSet(display_, window);
    672 }
    673 
    674 void XCore::removeFromSaveSet(Window window) {
    675     XRemoveFromSaveSet(display_, window);
    676 }
    677 
    678 void XCore::warpPointer(Window window, int x, int y) {
    679     XWarpPointer(display_, None, window, 0, 0, 0, 0, x, y);
    680 }
    681 
    682 XWMHints *XCore::getWMHints(Window window) {
    683     return XGetWMHints(display_, window);
    684 }