Browse Source

support cursor_hidden

David Rose 22 years ago
parent
commit
58c7debfa5

+ 21 - 7
panda/src/glxdisplay/glxGraphicsPipe.I

@@ -49,6 +49,18 @@ get_root() const {
   return _root;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsPipe::get_im
+//       Access: Public
+//  Description: Returns the input method opened for the pipe, or NULL
+//               if the input method could not be opened for some
+//               reason.
+////////////////////////////////////////////////////////////////////
+INLINE XIM glxGraphicsPipe::
+get_im() const {
+  return _im;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: glxGraphicsPipe::get_wm_delete_window
 //       Access: Public
@@ -61,13 +73,15 @@ get_wm_delete_window() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: glxGraphicsPipe::get_im
+//     Function: glxGraphicsPipe::get_hidden_cursor
 //       Access: Public
-//  Description: Returns the input method opened for the pipe, or NULL
-//               if the input method could not be opened for some
-//               reason.
+//  Description: Returns an invisible Cursor suitable for assigning to
+//               windows that have the cursor_hidden property set.
 ////////////////////////////////////////////////////////////////////
-INLINE XIM glxGraphicsPipe::
-get_im() const {
-  return _im;
+INLINE Cursor glxGraphicsPipe::
+get_hidden_cursor() {
+  if (_hidden_cursor == None) {
+    make_hidden_cursor();
+  }
+  return _hidden_cursor;
 }

+ 40 - 0
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -56,6 +56,7 @@ glxGraphicsPipe(const string &display) {
   _screen = 0;
   _root = (Window)NULL;
   _im = (XIM)NULL;
+  _hidden_cursor = None;
 
   install_error_handlers();
 
@@ -118,6 +119,7 @@ glxGraphicsPipe(const string &display) {
 ////////////////////////////////////////////////////////////////////
 glxGraphicsPipe::
 ~glxGraphicsPipe() {
+  release_hidden_cursor();
   if (_im) {
     XCloseIM(_im);
   }
@@ -574,6 +576,44 @@ try_for_fbconfig(int framebuffer_mode,
   return fbconfig;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsPipe::make_hidden_cursor
+//       Access: Private
+//  Description: Called once to make an invisible Cursor for return
+//               from get_hidden_cursor().
+////////////////////////////////////////////////////////////////////
+void glxGraphicsPipe::
+make_hidden_cursor() {
+  nassertv(_hidden_cursor == None);
+
+  unsigned int x_size, y_size;
+  XQueryBestCursor(_display, _root, 1, 1, &x_size, &y_size);
+  cerr << "best size is " << x_size << " x " << y_size << "\n";
+
+  Pixmap empty = XCreatePixmap(_display, _root, x_size, y_size, 1);
+
+  XColor black;
+  memset(&black, 0, sizeof(black));
+
+  _hidden_cursor = XCreatePixmapCursor(_display, empty, empty, 
+                                       &black, &black, x_size, y_size);
+  XFreePixmap(_display, empty);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsPipe::release_hidden_cursor
+//       Access: Private
+//  Description: Called once to release the invisible cursor created
+//               by make_hidden_cursor().
+////////////////////////////////////////////////////////////////////
+void glxGraphicsPipe::
+release_hidden_cursor() {
+  if (_hidden_cursor != None) {
+    XFreeCursor(_display, _hidden_cursor);
+    _hidden_cursor = None;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: glxGraphicsPipe::install_error_handlers
 //       Access: Private, Static

+ 6 - 0
panda/src/glxdisplay/glxGraphicsPipe.h

@@ -34,6 +34,7 @@ typedef int XVisualInfo;
 typedef int GLXFBConfig;
 typedef int GLXPbuffer;
 typedef int Atom;
+typedef int Cursor;
 typedef int XIM;
 typedef int XIC;
 #else
@@ -77,6 +78,8 @@ public:
 
   INLINE Atom get_wm_delete_window() const;
 
+  INLINE Cursor get_hidden_cursor();
+
 protected:
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
                                              GraphicsStateGuardian *share_with);
@@ -90,6 +93,8 @@ private:
   GLXFBConfig choose_fbconfig(FrameBufferProperties &properties) const;
   GLXFBConfig try_for_fbconfig(int framebuffer_mode,
                                int want_depth_bits, int want_color_bits) const;
+  void make_hidden_cursor();
+  void release_hidden_cursor();
 
   static void install_error_handlers();
   static int error_handler(Display *display, XErrorEvent *error);
@@ -102,6 +107,7 @@ private:
 
   Atom _wm_protocols;
   Atom _wm_delete_window;
+  Cursor _hidden_cursor;
 
   typedef int ErrorHandlerFunc(Display *, XErrorEvent *);
   typedef int IOErrorHandlerFunc(Display *);

+ 17 - 0
panda/src/glxdisplay/glxGraphicsWindow.cxx

@@ -407,6 +407,9 @@ set_properties_now(WindowProperties &properties) {
   // The window is already open; we are limited to what we can change
   // on the fly.
 
+  glxGraphicsPipe *glx_pipe;
+  DCAST_INTO_V(glx_pipe, _pipe);
+
   // The window title may be changed by issuing another hint request.
   // Assume this will be honored.
   if (properties.has_title()) {
@@ -443,6 +446,16 @@ set_properties_now(WindowProperties &properties) {
     // Don't draw anything until this is done reconfiguring.
     _awaiting_configure = true;
   }
+
+  // We hide the cursor by setting it to an invisible pixmap.
+  if (properties.has_cursor_hidden()) {
+    if (properties.get_cursor_hidden()) {
+      XDefineCursor(_display, _xwindow, glx_pipe->get_hidden_cursor());
+    } else {
+      XDefineCursor(_display, _xwindow, None);
+    }
+    properties.clear_cursor_hidden();
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -557,6 +570,10 @@ open_window() {
       << "Couldn't create input context.\n";
   }
 
+  if (_properties.get_cursor_hidden()) {
+    XDefineCursor(_display, _xwindow, glx_pipe->get_hidden_cursor());
+  }
+
   XMapWindow(_display, _xwindow);
 
   return true;