00001
00002
00003
00004
00005
00006 #include "xcore.h"
00007
00008 extern "C" {
00009 #include <X11/Xatom.h>
00010 #include <X11/Xproto.h>
00011 }
00012
00013 #include <sstream>
00014
00015 #include "atoms.h"
00016 #include "font.h"
00017 #include "kernel.h"
00018 #include "logger.h"
00019 #include "rectangle.h"
00020
00021 #include "xfont.h"
00022 #include "xftfont.h"
00023
00024 XCore::XCore() {}
00025
00026 XCore::~XCore() {}
00027
00028 void XCore::setDisplay(Display *display) {
00029 display_ = display;
00030 }
00031
00032 Window XCore::createWindow(Window root, XSetWindowAttributes *attr,
00033 int x, int y, unsigned int w, unsigned int h,
00034 unsigned long mask)
00035 {
00036 return XCreateWindow(display_, root, x, y, w, h, 0,
00037 CopyFromParent, InputOutput, CopyFromParent,
00038 mask, attr);
00039 }
00040
00041 void XCore::sendEvent(Window window, unsigned long mask, XEvent *event) {
00042 XSendEvent(display_, window, True, mask, event);
00043 }
00044
00045 void XCore::maskEvent(unsigned long mask, XEvent *event) {
00046 XMaskEvent(display_, mask, event);
00047 }
00048
00049 void XCore::selectEvents(Window window, long mask) {
00050 XSelectInput(display_, window, mask);
00051 }
00052
00053 void XCore::show(Window window) {
00054 XMapWindow(display_, window);
00055 }
00056
00057 void XCore::showRaised(Window window) {
00058 XMapRaised(display_, window);
00059 }
00060
00061 void XCore::hide(Window window) {
00062 XUnmapWindow(display_, window);
00063 }
00064
00065 GC XCore::createGC(Window window, unsigned long mask, XGCValues *gcv) {
00066 return XCreateGC(display_, window, mask, gcv);
00067 }
00068
00069 void XCore::ungrabKey(Window window, unsigned int modMask, KeyCode keycode)
00070 {
00071 XUngrabKey(display_, keycode, modMask, window);
00072 }
00073
00074 void XCore::grabKeyboard(Window window) {
00075 XGrabKeyboard(display_, window, True, GrabModeAsync,
00076 GrabModeAsync, CurrentTime);
00077 }
00078
00079 void XCore::ungrabKeyboard() {
00080 XUngrabKeyboard(display_, CurrentTime);
00081 }
00082
00083 void XCore::free(void *data) {
00084 XFree(data);
00085 }
00086
00087 void XCore::freeCursor(Cursor cursor) {
00088 XFreeCursor(display_, cursor);
00089 }
00090
00091 void XCore::sync(bool discard) {
00092 XSync(display_, discard);
00093 }
00094
00095 void XCore::setForeground(GC gc, unsigned long color) {
00096 XSetForeground(display_, gc, color);
00097 }
00098
00099 void XCore::drawLines(Window window, GC gc, XPoint *points, unsigned int num)
00100 {
00101 XDrawLines(display_, window, gc, points, num,
00102 CoordModeOrigin);
00103 }
00104
00105 void XCore::drawRectangle(Window window, GC gc, int x, int y,
00106 unsigned int w, unsigned int h)
00107 {
00108 XDrawRectangle(display_, window, gc, x, y, w, h);
00109 }
00110
00111 void XCore::drawRectangle(Window window, GC gc, Rectangle *rect) {
00112 XDrawRectangle(display_, window, gc, rect->x(), rect->y(),
00113 rect->width(), rect->height());
00114 }
00115
00116 void XCore::drawLine(Window window, GC gc, unsigned int x1, unsigned int y1,
00117 unsigned int x2, unsigned int y2)
00118 {
00119 XDrawLine(display_, window, gc, x1, y1, x2, y2);
00120 }
00121
00122 void XCore::clearArea(Window window, Rectangle *rect) {
00123 XClearArea(display_, window, rect->x(), rect->y(),
00124 rect->width(), rect->height(), False);
00125 }
00126
00127 void XCore::clearArea(Window window, int x, int y, unsigned int w, unsigned int h) {
00128 XClearArea(display_, window, x, y, w, h, False);
00129 }
00130
00131 void XCore::clearWindow(Window window) {
00132 XClearWindow(display_, window);
00133 }
00134
00135 void XCore::fillRectangle(Window window, GC gc, Rectangle *rect) {
00136 XFillRectangle(display_, window, gc, rect->x(), rect->y(),
00137 rect->width(), rect->height());
00138 }
00139
00140 void XCore::fillRectangle(Window window, GC gc, int x, int y,
00141 unsigned int w, unsigned int h)
00142 {
00143 XFillRectangle(display_, window, gc, x, y, w, h);
00144 }
00145
00146 XFontStruct *XCore::loadQueryFont(string name) {
00147 return XLoadQueryFont(display_, name.c_str());
00148 }
00149
00150 void XCore::drawText(Window window, GC gc, int x, int y,
00151 string text)
00152 {
00153 XDrawString(display_, window, gc, x, y,
00154 text.c_str(), text.length());
00155 }
00156
00157 int XCore::textWidth(XFontStruct *font, string text) {
00158 return XTextWidth(font, text.c_str(), text.length());
00159 }
00160
00161 #ifdef XFT_SUPPORT
00162 XftFont *XCore::xftOpenFontName(unsigned int screen, string name) {
00163 return XftFontOpenName(display_, screen, name.c_str());
00164 }
00165
00166 void XCore::xftCloseFont(XftFont *font) {
00167 if (font != 0) {
00168 XftFontClose(display_, font);
00169 }
00170 }
00171
00172 int XCore::textWidth(XftFont *font, string text) {
00173
00174 if (font == 0) {
00175 return 0;
00176 }
00177 XGlyphInfo ginfo;
00178 XftTextExtents8(display_, font, (XftChar8 *)text.c_str(),
00179 text.length(), &ginfo);
00180 return ginfo.xOff;
00181 }
00182
00183 void XCore::drawText(XftFont *font, Window window, GC gc,
00184 unsigned int screen, int x, int y, string text)
00185 {
00186 if (font == 0) {
00187 return;
00188 }
00189
00190 Visual *visual = DefaultVisual(display_, screen);
00191 Colormap cmap = DefaultColormap(display_, screen);
00192
00193 XftDraw *draw = XftDrawCreate(display_, window, visual, cmap);
00194
00195 XGCValues gcv;
00196
00197
00198 XGetGCValues(display_, gc, GCForeground, &gcv);
00199
00200
00201 XColor color;
00202 color.pixel = gcv.foreground;
00203 XQueryColor(display_, cmap, &color);
00204
00205 XRenderColor renderColor;
00206 renderColor.red = color.red;
00207 renderColor.green = color.green;
00208 renderColor.blue = color.blue;
00209 renderColor.alpha = 0xFFFF;
00210 XftColor xftColor;
00211 XftColorAllocValue(display_, visual, cmap, &renderColor, &xftColor);
00212
00213
00214 XftDrawString8(draw, &xftColor, font, x, y,
00215 (XftChar8 *)(text.c_str()), text.length());
00216
00217
00218 XftColorFree(display_, visual, cmap, &xftColor);
00219 XftDrawDestroy(draw);
00220 }
00221
00222 #endif // XFT_SUPPORT
00223
00224 string XCore::className(Window window) {
00225 XClassHint classHints;
00226
00227 if (XGetClassHint(display_, window, &classHints) != 0) {
00228 return (string)classHints.res_class;
00229 }
00230 return "";
00231 }
00232
00233 string XCore::instanceName(Window window) {
00234 XClassHint classHints;
00235
00236 if (XGetClassHint(display_, window, &classHints) != 0) {
00237 return (string)classHints.res_name;
00238 }
00239 return "";
00240 }
00241
00242 int XCore::state(Window window) {
00243
00244
00245 XWMHints *hints = XGetWMHints(display_, window);
00246 int result;
00247
00248 long *prop = 0;
00249 if (property(window, Atoms::WM_STATE, Atoms::WM_STATE,
00250 2L, (unsigned char**)&prop) > 0)
00251 {
00252 result = (int)*prop;
00253 free((long *)prop);
00254 }
00255 else {
00256 result = hints ? hints->initial_state : NormalState;
00257 }
00258
00259 if (hints) {
00260 free(hints);
00261 }
00262
00263 return result;
00264 }
00265
00266 void XCore::setState(Window window, int state) {
00267
00268 long data[2];
00269 data[0] = (long)state;
00270 data[1] = (long)None;
00271
00272 XChangeProperty(display_, window,
00273 Atoms::WM_STATE, Atoms::WM_STATE,
00274 32, PropModeReplace, (unsigned char *)data, 2);
00275 }
00276
00277 string XCore::atomValue(Window window, Atom atom) {
00278
00279 string result;
00280 unsigned char *prop;
00281
00282 if (property(window, atom, XA_STRING, 100L, &prop) > 0) {
00283 result = (char *)prop;
00284 free((char *)prop);
00285 }
00286 else {
00287 result = "";
00288 }
00289
00290 return result;
00291 }
00292
00293 void XCore::sizeHints(Window window, XSizeHints *sizeHints) {
00294 long msize;
00295
00296 XGetWMNormalHints(display_, window, sizeHints, &msize);
00297 }
00298
00299 void XCore::updateSize(Window window,
00300 unsigned int *minW, unsigned int *minH,
00301 unsigned int *maxW, unsigned int *maxH,
00302 bool *isCentered)
00303 {
00304 XSizeHints sizeHints;
00305 long msize;
00306
00307
00308 if (!XGetWMNormalHints(display_, window, &sizeHints, &msize)
00309 || !sizeHints.flags)
00310 {
00311 sizeHints.flags = PSize;
00312 }
00313
00314 *isCentered = !((sizeHints.flags & USPosition) ||
00315 (sizeHints.flags & PPosition));
00316
00317
00318 if (sizeHints.flags & PBaseSize) {
00319 *minW = sizeHints.base_width;
00320 *minH = sizeHints.base_height;
00321 }
00322 else if (sizeHints.flags & PMinSize) {
00323 *minW = sizeHints.min_width;
00324 *minH = sizeHints.min_height;
00325 }
00326 else {
00327 *minW = *minH = 23;
00328 }
00329
00330
00331 if (sizeHints.flags & PMaxSize) {
00332 *maxW = sizeHints.max_width;
00333 *maxH = sizeHints.max_height;
00334 }
00335 }
00336
00337 bool XCore::hasDecoration(Window window) {
00338
00339 MWMHints *mwmHints = 0;
00340 long result = property(window, Atoms::MWM_HINTS,
00341 Atoms::MWM_HINTS, 5, (unsigned char **)
00342 &mwmHints);
00343
00344 if ((result >= 0) && mwmHints) {
00345 bool decor = !(mwmHints->decorations == 0 &&
00346 (mwmHints->flags & MWM_HINTS_DECORATIONS));
00347 free((void *)mwmHints);
00348 return decor;
00349 }
00350
00351 return true;
00352 }
00353
00354 Window XCore::transient(Window window) {
00355 Window trans;
00356
00357 if (!XGetTransientForHint(display_, window, &trans)) {
00358 return 0;
00359 }
00360 return trans;
00361 }
00362
00363 int XCore::property(Window window, Atom atom, Atom type,
00364 long length, unsigned char **prop)
00365 {
00366 Atom realType;
00367 int format;
00368 unsigned long result, extra;
00369 int status;
00370
00371 status = XGetWindowProperty(display_, window,
00372 atom, 0L, length,
00373 False, type, &realType, &format,
00374 &result,
00375 &extra,
00376 prop);
00377
00378 if (status != Success || *prop == 0) {
00379 return 0;
00380 }
00381 if (result == 0) {
00382 free((void*) *prop);
00383 }
00384
00385 return result;
00386 }
00387
00388 void XCore::configureWindow(Window window, unsigned int mask, XWindowChanges *wc) {
00389
00390 XConfigureWindow(display_, window, mask, wc);
00391 }
00392
00393 void XCore::configure(Window window, XConfigureEvent *event) {
00394 XSendEvent(display_, window, False, StructureNotifyMask,
00395 (XEvent *)event);
00396 XFlush(display_);
00397 }
00398
00399 int XCore::protocols(Window window) {
00400 Atom *protocols;
00401 long result;
00402 int protos = 0;
00403
00404 result = property(window, Atoms::WM_PROTOCOLS, XA_ATOM,
00405 20L, (unsigned char **) &protocols);
00406 if (result <= 0) {
00407 return protos;
00408 }
00409
00410 for (int i = 0; i < result; i++) {
00411 if (protocols[i] == Atoms::WM_DELETE) {
00412 protos |= PDELETE;
00413 }
00414 else if (protocols[i] == Atoms::WM_TAKE_FOCUS) {
00415 protos |= PTAKEFOCUS;
00416 }
00417 }
00418 free((char *) protocols);
00419 return protos;
00420 }
00421
00422 void XCore::sendMessage(Window window, Atom atom, long value) {
00423
00424 XEvent event;
00425 event.type = ClientMessage;
00426 event.xclient.window = window;
00427 event.xclient.message_type = atom;
00428 event.xclient.format = 32;
00429 event.xclient.data.l[0] = value;
00430 event.xclient.data.l[1] = CurrentTime;
00431
00432 XSendEvent(display_, window, False, NoEventMask, &event);
00433 XFlush(display_);
00434 }
00435
00436 void XCore::kill(Window window, int protos) {
00437
00438 if (protos & PDELETE) {
00439 sendMessage(window, Atoms::WM_PROTOCOLS, Atoms::WM_DELETE);
00440 }
00441 else {
00442 XKillClient(display_, window);
00443 }
00444 }
00445
00446 void XCore::moveResize(Window window, Rectangle *rect) {
00447 XMoveResizeWindow(display_, window, rect->x(), rect->y(),
00448 rect->width(), rect->height());
00449 }
00450
00451 void XCore::destroy(Window window) {
00452 XDestroyWindow(display_, window);
00453 }
00454
00455 void XCore::raise(Window window) {
00456 XRaiseWindow(display_, window);
00457 }
00458
00459 void XCore::lower(Window window) {
00460 XLowerWindow(display_, window);
00461 }
00462
00463 void XCore::reparent(Window child, Window parent, int x, int y) {
00464 XReparentWindow(display_, child, parent, x, y);
00465 }
00466
00467 void XCore::setInputFocus(Window window) {
00468 XSetInputFocus(display_, window, RevertToPointerRoot, CurrentTime);
00469 }
00470
00471 void XCore::grabKey(Window window, unsigned int modMask, KeyCode keycode) {
00472 XGrabKey(display_, keycode, modMask, window, True, GrabModeAsync,
00473 GrabModeAsync);
00474 }
00475
00476 void XCore::grabButton(Window window, unsigned int modMask, unsigned int button) {
00477 XGrabButton(display_, button, modMask, window, False,
00478 ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
00479 GrabModeAsync, None, None);
00480 }
00481
00482 void XCore::ungrabButton(Window window, unsigned int modMask, unsigned int button) {
00483 XUngrabButton(display_, button, modMask, window);
00484 }
00485
00486 void XCore::setWindowAttributes(Window window, unsigned int mask,
00487 XSetWindowAttributes *attr)
00488 {
00489 XChangeWindowAttributes(display_, window, mask, attr);
00490 }
00491
00492 void XCore::windowAttributes(Window window, XWindowAttributes *attr)
00493 {
00494
00495 XGetWindowAttributes(display_, window, attr);
00496 }
00497
00498 Atom XCore::internAtom(string atom) {
00499 return XInternAtom(display_, atom.c_str(), False);
00500 }
00501
00502
00503 Cursor XCore::createFontCursor(unsigned int cursor) {
00504 return XCreateFontCursor(display_, cursor);
00505 }
00506
00507
00508 string XCore::atomName(Atom atom) {
00509 return (string)XGetAtomName(display_, atom);
00510 }
00511
00512
00513 void XCore::nextEvent(XEvent *event) {
00514 XNextEvent(display_, event);
00515 }
00516
00517 bool XCore::checkMaskEvent(long mask, XEvent *event) {
00518 return XCheckMaskEvent(display_, mask, event);
00519 }
00520
00521 KeyCode XCore::stringToKeyCode(string key) {
00522 KeySym keySym = XStringToKeysym(key.c_str());
00523 if (keySym) {
00524 return XKeysymToKeycode(display_, keySym);
00525 }
00526 return 0;
00527 }
00528
00529 KeySym XCore::keyCodeToKeySym(KeyCode keyCode) {
00530 return XKeycodeToKeysym(display_, keyCode, 0);
00531 }
00532
00533 string XCore::keyCodeToString(KeyCode keyCode) {
00534 KeySym keySym = XKeycodeToKeysym(display_, keyCode, 0);
00535 if (keySym) {
00536 return XKeysymToString(XKeycodeToKeysym(display_, keyCode, 0));
00537 }
00538 return "";
00539 }
00540
00541 void XCore::grabServer() {
00542 XGrabServer(display_);
00543 }
00544
00545 void XCore::ungrabServer() {
00546 XUngrabServer(display_);
00547 }
00548
00549 void XCore::grabPointer(Window window, unsigned int mask,
00550 Time time, Cursor cursor)
00551 {
00552
00553 XGrabPointer(display_, window, False, mask,
00554 GrabModeAsync, GrabModeAsync,
00555 None, cursor, time);
00556 }
00557
00558 void XCore::ungrabPointer(Time time) {
00559 XUngrabPointer(display_, time);
00560 }
00561
00562 void XCore::translateCoordinates(Window child, Window parent,
00563 int srcX, int srcY, int *destX, int *destY)
00564 {
00565
00566 Window dummy;
00567 XTranslateCoordinates(display_, child, parent, srcX, srcY,
00568 destX, destY, &dummy);
00569 }
00570
00571 bool XCore::allocNamedColor(Colormap colormap, string name, XColor *color) {
00572 return XAllocNamedColor(display_, colormap, name.c_str(),
00573 color, color);
00574 }
00575
00576 void XCore::installColormap(Colormap colormap) {
00577 XInstallColormap(display_, colormap);
00578 }
00579
00580 KeySym XCore::lookupNextKeySym(XKeyEvent *event, int *count, char *buffer) {
00581 KeySym result;
00582 *count = XLookupString(event, buffer, 32, &result, 0);
00583 return result;
00584 }
00585
00586 bool XCore::textProperty(Window window, Atom atom, string *value) {
00587 XTextProperty property;
00588
00589 if (XGetTextProperty(display_, window, &property, atom)) {
00590
00591 if (property.nitems > 0) {
00592 *value = (const char *)property.value;
00593 }
00594 else {
00595 *value = "";
00596 }
00597 free(property.value);
00598 return true;
00599 }
00600 return false;
00601 }
00602
00603 void XCore::queryTree(Window root, Window **windows, unsigned int *num) {
00604
00605 Window rootReturn, parentReturn;
00606
00607 XQueryTree(display_, root, &rootReturn,
00608 &parentReturn, windows, num);
00609 }
00610
00611
00612 int XCore::handleErrors(Display *display, XErrorEvent *e)
00613 {
00614 Logger *log = Logger::instance();
00615 Kernel *kernel = Kernel::instance();
00616
00617 if ((kernel->runlevel() == Kernel::START) &&
00618 (e->request_code == X_ChangeWindowAttributes) &&
00619 (e->error_code == BadAccess))
00620 {
00621 log->error("seems, that there's running another window manager", true);
00622
00623 }
00624
00625 char errtxt[128];
00626
00627 XGetErrorText(kernel->display(), e->error_code, errtxt, 128);
00628 ostringstream oss;
00629 oss << errtxt << "(" << (int)e->error_code << ") opcodes "
00630 << (int)e->request_code << "/" << (int)e->minor_code
00631 << " resource 0x"<< hex << (int)e->resourceid;
00632 log->warning(oss.str());
00633
00634 #ifdef DEBUG
00635 XTextProperty property;
00636
00637 char *text = (char *)oss.str().c_str();
00638 XStringListToTextProperty(&text, 1, &property);
00639 XSetTextProperty(kernel->display(), kernel->defaultRootWindow(), &property,
00640 Atoms::NCWM_STATUSTEXT);
00641 #endif
00642
00643 return 0;
00644 }
00645
00646 void XCore::setTextProperty(Display *display, Window window,
00647 XTextProperty *textProperty, Atom atom)
00648 {
00649 XSetTextProperty(display, window, textProperty, atom);
00650 }
00651
00652 void XCore::stringListToTextProperty(string text, XTextProperty *textProperty)
00653 {
00654 char *txt = (char *)text.c_str();
00655 XStringListToTextProperty(&txt, 1, textProperty);
00656 }
00657
00658 Colormap XCore::defaultColormap(unsigned int id) {
00659 return DefaultColormap(display_, id);
00660 }
00661
00662 XModifierKeymap *XCore::modifierMapping() {
00663 return XGetModifierMapping(display_);
00664 }
00665
00666 void XCore::freeModifierMapping(XModifierKeymap *modmap) {
00667 if (modmap) {
00668 XFreeModifiermap(modmap);
00669 }
00670 }
00671
00672 void XCore::addToSaveSet(Window window) {
00673 XAddToSaveSet(display_, window);
00674 }
00675
00676 void XCore::removeFromSaveSet(Window window) {
00677 XRemoveFromSaveSet(display_, window);
00678 }
00679
00680 void XCore::warpPointer(Window window, int x, int y) {
00681 XWarpPointer(display_, None, window, 0, 0, 0, 0, x, y);
00682 }
00683
00684 XWMHints *XCore::getWMHints(Window window) {
00685 return XGetWMHints(display_, window);
00686 }