Browse Source

fix crash when xrandr is not used

rdb 13 years ago
parent
commit
b83c81bee4

+ 84 - 76
panda/src/x11display/x11GraphicsWindow.cxx

@@ -60,7 +60,7 @@ static int xcursor_seek(XcursorFile *file, long offset, int whence) {
   case SEEK_END:
   case SEEK_END:
     str->seekg(offset, istream::end);
     str->seekg(offset, istream::end);
   }
   }
-  
+
   return str->tellg();
   return str->tellg();
 }
 }
 #endif
 #endif
@@ -75,7 +75,7 @@ TypeHandle x11GraphicsWindow::_type_handle;
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 x11GraphicsWindow::
 x11GraphicsWindow::
-x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, 
+x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
                   const string &name,
                   const string &name,
                   const FrameBufferProperties &fb_prop,
                   const FrameBufferProperties &fb_prop,
                   const WindowProperties &win_prop,
                   const WindowProperties &win_prop,
@@ -91,9 +91,15 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
   _xwindow = (X11_Window)NULL;
   _xwindow = (X11_Window)NULL;
   _ic = (XIC)NULL;
   _ic = (XIC)NULL;
   _visual_info = NULL;
   _visual_info = NULL;
+
 #ifdef HAVE_XRANDR
 #ifdef HAVE_XRANDR
   _orig_size_id = -1;
   _orig_size_id = -1;
+  int event, error;
+  _have_xrandr = XRRQueryExtension(_display, &event, &error);
+#else
+  _have_xrandr = false;
 #endif
 #endif
+
   _awaiting_configure = false;
   _awaiting_configure = false;
   _dga_mouse_enabled = false;
   _dga_mouse_enabled = false;
   _wm_delete_window = x11_pipe->_wm_delete_window;
   _wm_delete_window = x11_pipe->_wm_delete_window;
@@ -130,7 +136,7 @@ x11GraphicsWindow::
 //     Function: x11GraphicsWindow::move_pointer
 //     Function: x11GraphicsWindow::move_pointer
 //       Access: Published, Virtual
 //       Access: Published, Virtual
 //  Description: Forces the pointer to the indicated position within
 //  Description: Forces the pointer to the indicated position within
-//               the window, if possible.  
+//               the window, if possible.
 //
 //
 //               Returns true if successful, false on failure.  This
 //               Returns true if successful, false on failure.  This
 //               may fail if the mouse is not currently within the
 //               may fail if the mouse is not currently within the
@@ -190,17 +196,17 @@ begin_frame(FrameMode mode, Thread *current_thread) {
     // window and we haven't got the notification back yet.
     // window and we haven't got the notification back yet.
     return false;
     return false;
   }
   }
-  
+
   // Reset the GSG state if this is the first time it has been used.
   // Reset the GSG state if this is the first time it has been used.
   // (We can't just call reset() when we construct the GSG, because
   // (We can't just call reset() when we construct the GSG, because
   // reset() requires having a current context.)
   // reset() requires having a current context.)
   _gsg->reset_if_new();
   _gsg->reset_if_new();
-  
+
   if (mode == FM_render) {
   if (mode == FM_render) {
     // begin_render_texture();
     // begin_render_texture();
     clear_cube_map_selection();
     clear_cube_map_selection();
   }
   }
-  
+
   _gsg->set_current_properties(&get_fb_properties());
   _gsg->set_current_properties(&get_fb_properties());
   return _gsg->begin_frame(current_thread);
   return _gsg->begin_frame(current_thread);
 }
 }
@@ -249,9 +255,9 @@ process_events() {
   if (_xwindow == (X11_Window)0) {
   if (_xwindow == (X11_Window)0) {
     return;
     return;
   }
   }
-  
+
   poll_raw_mice();
   poll_raw_mice();
-  
+
   XEvent event;
   XEvent event;
   XKeyEvent keyrelease_event;
   XKeyEvent keyrelease_event;
   bool got_keyrelease_event = false;
   bool got_keyrelease_event = false;
@@ -338,7 +344,7 @@ process_events() {
       }
       }
       _input_devices[0].button_down(button);
       _input_devices[0].button_down(button);
       break;
       break;
-      
+
     case ButtonRelease:
     case ButtonRelease:
       button = get_mouse_button(event.xbutton);
       button = get_mouse_button(event.xbutton);
       if (!_dga_mouse_enabled) {
       if (!_dga_mouse_enabled) {
@@ -476,54 +482,56 @@ set_properties_now(WindowProperties &properties) {
 
 
   x11GraphicsPipe *x11_pipe;
   x11GraphicsPipe *x11_pipe;
   DCAST_INTO_V(x11_pipe, _pipe);
   DCAST_INTO_V(x11_pipe, _pipe);
-  
+
   // Handle fullscreen mode.
   // Handle fullscreen mode.
   if (properties.has_fullscreen()) {
   if (properties.has_fullscreen()) {
     if (properties.get_fullscreen()) {
     if (properties.get_fullscreen()) {
+      if (_have_xrandr) {
 #ifdef HAVE_XRANDR
 #ifdef HAVE_XRANDR
-      XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
-      if (_orig_size_id == (SizeID) -1) {
-        _orig_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
-      }
-      int num_sizes, reqsizex, reqsizey, new_size_id = -1;
-      if (properties.has_size()) {
-        reqsizex = properties.get_x_size();
-        reqsizey = properties.get_y_size();
-      } else {
-        reqsizex = _properties.get_x_size();
-        reqsizey = _properties.get_y_size();
-      }
-      XRRScreenSize *xrrs;
-      xrrs = XRRSizes(_display, 0, &num_sizes);
-      for (int i = 0; i < num_sizes; ++i) {
-        if (xrrs[i].width == properties.get_x_size() && 
-            xrrs[i].height == properties.get_y_size()) {
-          new_size_id = i;
+        XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
+        if (_orig_size_id == (SizeID) -1) {
+          _orig_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
         }
         }
-      }
-      if (new_size_id == -1) {
-        x11display_cat.error() 
-          << "Videocard has no supported display resolutions at specified res ("
-          << reqsizex << " x " << reqsizey <<")\n";
-        _orig_size_id = -1;
-      } else {
-        if (new_size_id != _orig_size_id) {
-          XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
+        int num_sizes, reqsizex, reqsizey, new_size_id = -1;
+        if (properties.has_size()) {
+          reqsizex = properties.get_x_size();
+          reqsizey = properties.get_y_size();
         } else {
         } else {
+          reqsizex = _properties.get_x_size();
+          reqsizey = _properties.get_y_size();
+        }
+        XRRScreenSize *xrrs;
+        xrrs = XRRSizes(_display, 0, &num_sizes);
+        for (int i = 0; i < num_sizes; ++i) {
+          if (xrrs[i].width == properties.get_x_size() &&
+              xrrs[i].height == properties.get_y_size()) {
+            new_size_id = i;
+          }
+        }
+        if (new_size_id == -1) {
+          x11display_cat.error()
+            << "Videocard has no supported display resolutions at specified res ("
+            << reqsizex << " x " << reqsizey <<")\n";
           _orig_size_id = -1;
           _orig_size_id = -1;
+        } else {
+          if (new_size_id != _orig_size_id) {
+            XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
+          } else {
+            _orig_size_id = -1;
+          }
         }
         }
-      }
-#else
-      // If we don't have Xrandr support, we fake the fullscreen
-      // support by setting the window size to the desktop size.
-      properties.set_size(x11_pipe->get_display_width(),
-                          x11_pipe->get_display_height());
 #endif
 #endif
+      } else {
+        // If we don't have Xrandr support, we fake the fullscreen
+        // support by setting the window size to the desktop size.
+        properties.set_size(x11_pipe->get_display_width(),
+                            x11_pipe->get_display_height());
+      }
     } else {
     } else {
 #ifdef HAVE_XRANDR
 #ifdef HAVE_XRANDR
       // Change the resolution back to what it was.
       // Change the resolution back to what it was.
       // Don't remove the SizeID typecast!
       // Don't remove the SizeID typecast!
-      if (_orig_size_id != (SizeID) -1) {
+      if (_have_xrandr && _orig_size_id != (SizeID) -1) {
         XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
         XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
         XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), _orig_size_id, _orig_rotation, CurrentTime);
         XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), _orig_size_id, _orig_rotation, CurrentTime);
         _orig_size_id = -1;
         _orig_size_id = -1;
@@ -535,7 +543,7 @@ set_properties_now(WindowProperties &properties) {
       }
       }
     }
     }
   }
   }
-  
+
   if (properties.has_origin()) {
   if (properties.has_origin()) {
     // A coordinate of -2 means to center the window on screen.
     // A coordinate of -2 means to center the window on screen.
     if (properties.get_x_origin() == -2 || properties.get_y_origin() == -2) {
     if (properties.get_x_origin() == -2 || properties.get_y_origin() == -2) {
@@ -559,7 +567,7 @@ set_properties_now(WindowProperties &properties) {
       properties.set_origin(x_origin, y_origin);
       properties.set_origin(x_origin, y_origin);
     }
     }
   }
   }
-  
+
   GraphicsWindow::set_properties_now(properties);
   GraphicsWindow::set_properties_now(properties);
   if (!properties.is_any_specified()) {
   if (!properties.is_any_specified()) {
     // The base class has already handled this case.
     // The base class has already handled this case.
@@ -579,20 +587,20 @@ set_properties_now(WindowProperties &properties) {
     _properties.set_title(properties.get_title());
     _properties.set_title(properties.get_title());
     properties.clear_title();
     properties.clear_title();
   }
   }
-  
+
   // Same for fullscreen.
   // Same for fullscreen.
   if (properties.has_fullscreen()) {
   if (properties.has_fullscreen()) {
     _properties.set_fullscreen(properties.get_fullscreen());
     _properties.set_fullscreen(properties.get_fullscreen());
     properties.clear_fullscreen();
     properties.clear_fullscreen();
   }
   }
-  
+
   // The size and position of an already-open window are changed via
   // The size and position of an already-open window are changed via
   // explicit X calls.  These may still get intercepted by the window
   // explicit X calls.  These may still get intercepted by the window
   // manager.  Rather than changing _properties immediately, we'll
   // manager.  Rather than changing _properties immediately, we'll
   // wait for the ConfigureNotify message to come back.
   // wait for the ConfigureNotify message to come back.
   XWindowChanges changes;
   XWindowChanges changes;
   int value_mask = 0;
   int value_mask = 0;
-  
+
   if (_properties.get_fullscreen()) {
   if (_properties.get_fullscreen()) {
     changes.x = 0;
     changes.x = 0;
     changes.y = 0;
     changes.y = 0;
@@ -605,14 +613,14 @@ set_properties_now(WindowProperties &properties) {
     if (changes.y != -1) value_mask |= CWY;
     if (changes.y != -1) value_mask |= CWY;
     properties.clear_origin();
     properties.clear_origin();
   }
   }
-  
+
   if (properties.has_size()) {
   if (properties.has_size()) {
     changes.width = properties.get_x_size();
     changes.width = properties.get_x_size();
     changes.height = properties.get_y_size();
     changes.height = properties.get_y_size();
     value_mask |= (CWWidth | CWHeight);
     value_mask |= (CWWidth | CWHeight);
     properties.clear_size();
     properties.clear_size();
   }
   }
-  
+
   if (properties.has_z_order()) {
   if (properties.has_z_order()) {
     // We'll send the classic stacking request through the standard
     // We'll send the classic stacking request through the standard
     // interface, for users of primitive window managers; but we'll
     // interface, for users of primitive window managers; but we'll
@@ -758,7 +766,7 @@ close_window() {
   if (_gsg != (GraphicsStateGuardian *)NULL) {
   if (_gsg != (GraphicsStateGuardian *)NULL) {
     _gsg.clear();
     _gsg.clear();
   }
   }
-  
+
   if (_ic != (XIC)NULL) {
   if (_ic != (XIC)NULL) {
     XDestroyIC(_ic);
     XDestroyIC(_ic);
     _ic = (XIC)NULL;
     _ic = (XIC)NULL;
@@ -776,7 +784,7 @@ close_window() {
 #ifdef HAVE_XRANDR
 #ifdef HAVE_XRANDR
   // Change the resolution back to what it was.
   // Change the resolution back to what it was.
   // Don't remove the SizeID typecast!
   // Don't remove the SizeID typecast!
-  if (_orig_size_id != (SizeID) -1) {
+  if (_have_xrandr && _orig_size_id != (SizeID) -1) {
     X11_Window root;
     X11_Window root;
     if (_pipe != NULL) {
     if (_pipe != NULL) {
       x11GraphicsPipe *x11_pipe;
       x11GraphicsPipe *x11_pipe;
@@ -812,19 +820,19 @@ open_window() {
       << "No X visual: cannot open window.\n";
       << "No X visual: cannot open window.\n";
     return false;
     return false;
   }
   }
-  
+
   x11GraphicsPipe *x11_pipe;
   x11GraphicsPipe *x11_pipe;
   DCAST_INTO_R(x11_pipe, _pipe, false);
   DCAST_INTO_R(x11_pipe, _pipe, false);
-  
+
   if (!_properties.has_origin()) {
   if (!_properties.has_origin()) {
     _properties.set_origin(0, 0);
     _properties.set_origin(0, 0);
   }
   }
   if (!_properties.has_size()) {
   if (!_properties.has_size()) {
     _properties.set_size(100, 100);
     _properties.set_size(100, 100);
   }
   }
-  
+
 #ifdef HAVE_XRANDR
 #ifdef HAVE_XRANDR
-  if (_properties.get_fullscreen()) {
+  if (_properties.get_fullscreen() && _have_xrandr) {
     XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
     XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
     if (_orig_size_id == (SizeID) -1) {
     if (_orig_size_id == (SizeID) -1) {
       _orig_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
       _orig_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
@@ -833,13 +841,13 @@ open_window() {
     XRRScreenSize *xrrs;
     XRRScreenSize *xrrs;
     xrrs = XRRSizes(_display, 0, &num_sizes);
     xrrs = XRRSizes(_display, 0, &num_sizes);
     for (int i = 0; i < num_sizes; ++i) {
     for (int i = 0; i < num_sizes; ++i) {
-      if (xrrs[i].width == _properties.get_x_size() && 
+      if (xrrs[i].width == _properties.get_x_size() &&
           xrrs[i].height == _properties.get_y_size()) {
           xrrs[i].height == _properties.get_y_size()) {
         new_size_id = i;
         new_size_id = i;
       }
       }
     }
     }
     if (new_size_id == -1) {
     if (new_size_id == -1) {
-      x11display_cat.error() 
+      x11display_cat.error()
         << "Videocard has no supported display resolutions at specified res ("
         << "Videocard has no supported display resolutions at specified res ("
         << _properties.get_x_size() << " x " << _properties.get_y_size() <<")\n";
         << _properties.get_x_size() << " x " << _properties.get_y_size() <<")\n";
       _orig_size_id = -1;
       _orig_size_id = -1;
@@ -852,7 +860,7 @@ open_window() {
     }
     }
   }
   }
 #endif
 #endif
-  
+
   X11_Window parent_window = x11_pipe->get_root();
   X11_Window parent_window = x11_pipe->get_root();
   WindowHandle *window_handle = _properties.get_parent_window();
   WindowHandle *window_handle = _properties.get_parent_window();
   if (window_handle != NULL) {
   if (window_handle != NULL) {
@@ -862,7 +870,7 @@ open_window() {
     if (os_handle != NULL) {
     if (os_handle != NULL) {
       x11display_cat.info()
       x11display_cat.info()
         << "os_handle type " << os_handle->get_type() << "\n";
         << "os_handle type " << os_handle->get_type() << "\n";
-      
+
       if (os_handle->is_of_type(NativeWindowHandle::X11Handle::get_class_type())) {
       if (os_handle->is_of_type(NativeWindowHandle::X11Handle::get_class_type())) {
         NativeWindowHandle::X11Handle *x11_handle = DCAST(NativeWindowHandle::X11Handle, os_handle);
         NativeWindowHandle::X11Handle *x11_handle = DCAST(NativeWindowHandle::X11Handle, os_handle);
         parent_window = x11_handle->get_handle();
         parent_window = x11_handle->get_handle();
@@ -873,7 +881,7 @@ open_window() {
     }
     }
   }
   }
   _parent_window_handle = window_handle;
   _parent_window_handle = window_handle;
-  
+
   _event_mask =
   _event_mask =
     ButtonPressMask | ButtonReleaseMask |
     ButtonPressMask | ButtonReleaseMask |
     KeyPressMask | KeyReleaseMask |
     KeyPressMask | KeyReleaseMask |
@@ -888,7 +896,7 @@ open_window() {
   wa.colormap = _colormap;
   wa.colormap = _colormap;
   wa.event_mask = _event_mask;
   wa.event_mask = _event_mask;
 
 
-  unsigned long attrib_mask = 
+  unsigned long attrib_mask =
     CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
     CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
 
 
   _xwindow = XCreateWindow
   _xwindow = XCreateWindow
@@ -930,7 +938,7 @@ open_window() {
     X11_Cursor cursor = get_cursor(_properties.get_cursor_filename());
     X11_Cursor cursor = get_cursor(_properties.get_cursor_filename());
     XDefineCursor(_display, _xwindow, cursor);
     XDefineCursor(_display, _xwindow, cursor);
   }
   }
-  
+
   XMapWindow(_display, _xwindow);
   XMapWindow(_display, _xwindow);
 
 
   if (_properties.get_raw_mice()) {
   if (_properties.get_raw_mice()) {
@@ -949,7 +957,7 @@ open_window() {
   if (_parent_window_handle != (WindowHandle *)NULL) {
   if (_parent_window_handle != (WindowHandle *)NULL) {
     _parent_window_handle->attach_child(_window_handle);
     _parent_window_handle->attach_child(_window_handle);
   }
   }
-  
+
   return true;
   return true;
 }
 }
 
 
@@ -1119,7 +1127,7 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
 
 
     x11GraphicsPipe *x11_pipe;
     x11GraphicsPipe *x11_pipe;
     DCAST_INTO_V(x11_pipe, _pipe);
     DCAST_INTO_V(x11_pipe, _pipe);
-  
+
     for (int i = 0; i < next_set_data; ++i) {
     for (int i = 0; i < next_set_data; ++i) {
       XClientMessageEvent event;
       XClientMessageEvent event;
       memset(&event, 0, sizeof(event));
       memset(&event, 0, sizeof(event));
@@ -1159,7 +1167,7 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
     _wm_delete_window,
     _wm_delete_window,
   };
   };
 
 
-  XSetWMProtocols(_display, _xwindow, protocols, 
+  XSetWMProtocols(_display, _xwindow, protocols,
                   sizeof(protocols) / sizeof(Atom));
                   sizeof(protocols) / sizeof(Atom));
 }
 }
 
 
@@ -1189,7 +1197,7 @@ open_raw_mice() {
 #ifdef HAVE_LINUX_INPUT_H
 #ifdef HAVE_LINUX_INPUT_H
   bool any_present = false;
   bool any_present = false;
   bool any_mice = false;
   bool any_mice = false;
-  
+
   for (int i=0; i<64; i++) {
   for (int i=0; i<64; i++) {
     uint8_t evtypes[EV_MAX/8 + 1];
     uint8_t evtypes[EV_MAX/8 + 1];
     ostringstream fnb;
     ostringstream fnb;
@@ -1241,17 +1249,17 @@ open_raw_mice() {
         break;
         break;
       } else {
       } else {
         any_present = true;
         any_present = true;
-        x11display_cat.error() << 
+        x11display_cat.error() <<
           "Opening raw mice: " << strerror(errno) << " " << fn << "\n";
           "Opening raw mice: " << strerror(errno) << " " << fn << "\n";
       }
       }
     }
     }
   }
   }
-  
+
   if (!any_present) {
   if (!any_present) {
-    x11display_cat.error() << 
+    x11display_cat.error() <<
       "Opening raw mice: files not found: /dev/input/event*\n";
       "Opening raw mice: files not found: /dev/input/event*\n";
   } else if (!any_mice) {
   } else if (!any_mice) {
-    x11display_cat.error() << 
+    x11display_cat.error() <<
       "Opening raw mice: no mouse devices detected in /dev/input/event*\n";
       "Opening raw mice: no mouse devices detected in /dev/input/event*\n";
   }
   }
 #else
 #else
@@ -1289,7 +1297,7 @@ poll_raw_mice()
         }
         }
       }
       }
     }
     }
-    
+
     // Process events.
     // Process events.
     int nevents = inf._io_buffer.size() / sizeof(struct input_event);
     int nevents = inf._io_buffer.size() / sizeof(struct input_event);
     if (nevents == 0) {
     if (nevents == 0) {
@@ -1347,7 +1355,7 @@ handle_keystroke(XKeyEvent &event) {
       x11display_cat.error()
       x11display_cat.error()
         << "Overflowed input buffer.\n";
         << "Overflowed input buffer.\n";
     }
     }
-    
+
     // Now each of the returned wide characters represents a
     // Now each of the returned wide characters represents a
     // keystroke.
     // keystroke.
     for (int i = 0; i < len; i++) {
     for (int i = 0; i < len; i++) {
@@ -1481,7 +1489,7 @@ get_button(XKeyEvent &key_event, bool allow_shift) {
 
 
     default:
     default:
       break;
       break;
-    } 
+    }
   }
   }
 
 
   if (allow_shift) {
   if (allow_shift) {
@@ -1904,7 +1912,7 @@ get_cursor(const Filename &filename) {
       << "Could not open cursor file " << filename << "\n";
       << "Could not open cursor file " << filename << "\n";
     return None;
     return None;
   }
   }
-  
+
   // Check the first four bytes to see what kind of file it is.
   // Check the first four bytes to see what kind of file it is.
   char magic[4];
   char magic[4];
   str->read(magic, 4);
   str->read(magic, 4);

+ 6 - 5
panda/src/x11display/x11GraphicsWindow.h

@@ -32,7 +32,7 @@ typedef unsigned short SizeID;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class x11GraphicsWindow : public GraphicsWindow {
 class x11GraphicsWindow : public GraphicsWindow {
 public:
 public:
-  x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, 
+  x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
                     const string &name,
                     const string &name,
                     const FrameBufferProperties &fb_prop,
                     const FrameBufferProperties &fb_prop,
                     const WindowProperties &win_prop,
                     const WindowProperties &win_prop,
@@ -79,7 +79,7 @@ private:
 #ifdef HAVE_XCURSOR
 #ifdef HAVE_XCURSOR
   X11_Cursor read_ico(istream &ico);
   X11_Cursor read_ico(istream &ico);
 #endif
 #endif
-  
+
 protected:
 protected:
   X11_Display *_display;
   X11_Display *_display;
   int _screen;
   int _screen;
@@ -87,7 +87,8 @@ protected:
   Colormap _colormap;
   Colormap _colormap;
   XIC _ic;
   XIC _ic;
   XVisualInfo *_visual_info;
   XVisualInfo *_visual_info;
-  
+
+  bool _have_xrandr;
 #ifdef HAVE_XRANDR
 #ifdef HAVE_XRANDR
   Rotation _orig_rotation;
   Rotation _orig_rotation;
   SizeID _orig_size_id;
   SizeID _orig_size_id;
@@ -113,7 +114,7 @@ protected:
     string _io_buffer;
     string _io_buffer;
   };
   };
   pvector<MouseDeviceInfo> _mouse_device_info;
   pvector<MouseDeviceInfo> _mouse_device_info;
-  
+
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;
@@ -130,7 +131,7 @@ public:
 
 
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
-  
+
   // Since the Panda API requests icons and cursors by filename, we
   // Since the Panda API requests icons and cursors by filename, we
   // need a table mapping filenames to handles, so we can avoid
   // need a table mapping filenames to handles, so we can avoid
   // re-reading the file each time we change icons.
   // re-reading the file each time we change icons.