From 58c7debfa506b3c438d028b3790ed8221af6c99c Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 3 Mar 2004 20:15:09 +0000 Subject: [PATCH] support cursor_hidden --- panda/src/glxdisplay/glxGraphicsPipe.I | 28 +++++++++++---- panda/src/glxdisplay/glxGraphicsPipe.cxx | 40 ++++++++++++++++++++++ panda/src/glxdisplay/glxGraphicsPipe.h | 6 ++++ panda/src/glxdisplay/glxGraphicsWindow.cxx | 17 +++++++++ 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/panda/src/glxdisplay/glxGraphicsPipe.I b/panda/src/glxdisplay/glxGraphicsPipe.I index ffc86610df..d7e23e16ed 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.I +++ b/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; } diff --git a/panda/src/glxdisplay/glxGraphicsPipe.cxx b/panda/src/glxdisplay/glxGraphicsPipe.cxx index edf3814f98..aa790cad25 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.cxx +++ b/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 diff --git a/panda/src/glxdisplay/glxGraphicsPipe.h b/panda/src/glxdisplay/glxGraphicsPipe.h index 567ab418f4..bd828aaf6e 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.h +++ b/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 *); diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index 505bb2eba7..b3d55a1633 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/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;