x.cpp 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "x.hpp"
  2. using namespace slop;
  3. glm::vec4 slop::getWindowGeometry( Window win, bool removeDecoration ) {
  4. // First lets check for if we're a window manager frame.
  5. Window root, parent;
  6. Window* children;
  7. unsigned int num_children;
  8. XQueryTree( x11->display, win, &root, &parent, &children, &num_children);
  9. // To do that, we check if our top level child happens to have the _NET_FRAME_EXTENTS atom.
  10. unsigned char *data;
  11. Atom type_return;
  12. unsigned long nitems_return;
  13. unsigned long bytes_after_return;
  14. int format_return;
  15. bool window_frame = false;
  16. Window actualWindow = win;
  17. if ( num_children > 0 && XGetWindowProperty( x11->display, children[num_children-1], XInternAtom( x11->display, "_NET_FRAME_EXTENTS", False),
  18. 0, LONG_MAX, False, XA_CARDINAL, &type_return,
  19. &format_return, &nitems_return, &bytes_after_return,
  20. &data) == Success ) {
  21. if ((type_return == XA_CARDINAL) && (format_return == 32) && (nitems_return == 4) && (data)) {
  22. actualWindow = children[num_children-1];
  23. window_frame = true;
  24. }
  25. }
  26. // If we actually don't want the window frame (decoration), we just actually grab the decoration's innards.
  27. // And ignore all of the _NET_FRAME_EXTENTS information.
  28. if ( actualWindow != win && removeDecoration ) {
  29. win = actualWindow;
  30. window_frame = false;
  31. }
  32. // If we're a window frame, we actually get the dimensions of the child window, then add the _NET_FRAME_EXTENTS to it.
  33. // (then add the border width of the window frame after that.)
  34. if ( window_frame ) {
  35. // First lets grab the border width.
  36. XWindowAttributes frameattr;
  37. XGetWindowAttributes( x11->display, win, &frameattr );
  38. // Then lets grab the dims of the child window.
  39. XWindowAttributes attr;
  40. XGetWindowAttributes( x11->display, actualWindow, &attr );
  41. unsigned int width = attr.width;
  42. unsigned int height = attr.height;
  43. // We combine both border widths.
  44. unsigned int border = attr.border_width+frameattr.border_width;
  45. int x, y;
  46. // Gotta translate them into root coords, we can adjust for the border width here.
  47. Window junk;
  48. XTranslateCoordinates( x11->display, actualWindow, attr.root, -border, -border, &x, &y, &junk );
  49. width += border*2;
  50. height += border*2;
  51. // Now uh, remember that _NET_FRAME_EXTENTS stuff? That's the window frame information.
  52. // We HAVE to do this because mutter likes to mess with window sizes with shadows and stuff.
  53. unsigned long* ldata = (unsigned long*)data;
  54. width += ldata[0] + ldata[1];
  55. height += ldata[2] + ldata[3];
  56. x -= ldata[0];
  57. y -= ldata[2];
  58. XFree( data );
  59. return glm::vec4( x, y, width, height );
  60. } else {
  61. // Either the WM is malfunctioning, or the window specified isn't a window manager frame.
  62. // so we just rely on X to give a decent geometry.
  63. XWindowAttributes attr;
  64. XGetWindowAttributes( x11->display, win, &attr );
  65. unsigned int width = attr.width;
  66. unsigned int height = attr.height;
  67. // We combine both border widths.
  68. unsigned int border = attr.border_width;
  69. int x, y;
  70. // Gotta translate them into root coords, we can adjust for the border width here.
  71. Window junk;
  72. XTranslateCoordinates( x11->display, win, attr.root, -border, -border, &x, &y, &junk );
  73. width += border*2;
  74. height += border*2;
  75. return glm::vec4( x, y, width, height );
  76. }
  77. }
  78. bool X11::hasCompositor() {
  79. std::stringstream prop_name;
  80. prop_name << "_NET_WM_CM_S" << XScreenNumberOfScreen( screen );
  81. Atom prop_atom = XInternAtom(display, prop_name.str().c_str(), False);
  82. return XGetSelectionOwner(display, prop_atom) != None;
  83. }
  84. X11::X11( std::string displayName ) {
  85. // Initialize display
  86. display = XOpenDisplay( displayName.c_str() );
  87. if ( !display ) {
  88. throw std::runtime_error(std::string("Error: Failed to open X display: ") + displayName );
  89. }
  90. screen = ScreenOfDisplay( display, DefaultScreen( display ) );
  91. visual = DefaultVisual( display, XScreenNumberOfScreen( screen ) );
  92. root = DefaultRootWindow( display );
  93. }
  94. X11::~X11() {
  95. XCloseDisplay( display );
  96. }