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 }