[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#254257: libxcursor1: Xrendered Xcursor rendering artifacts & flicker



Package: libxcursor1
Version: 1.1.3-1
Severity: normal


The latest GNOME upgrades shifted /etc/alternatives/x-cursor-theme to 
the high-quality Industrial theme cursors.  That change exposed 
one or more bugs in the way that XRender renders cursors on the 
screen.

First, the cursor will flicker whenever doing one of several drag 
actions that causes the parent window to be redrawn: window resizing by 
drag, resizing a window pane, and during the rendering of webpages in 
Galeon or Mozilla.

Second, when using Blender, the various OpenGL-drawn widgets are not 
being updated properly when you move the mouse accross them.  Also, 
whenever dragging a model through some movement, there is noticable 
distortion around the area covered by the mouse.

Finally, in a simple OpenGL program that does nothing but swap its 
buffers (attached), the mouse will disappear entirely when it hovers 
over the window and remains still.  As you move the mouse within the 
window, it reappears but flickers.

Changing cursor.c (in the libxcursor1 package) line 548 to "#if 0" works 
around the problem by converting the cursor to a simple bitmap and 
avoids use of XRender, but yields a set of somewhat ugly cursors.

Hardware:
Pentium 3 with an NVIDIA TNT2 M64 AGP video card.

Software configurations tested:
nvidia driver with and without the RenderAccel option set.
nv driver with Mesa software OpenGL.

The attached test program should be compiled with:
$ g++ -o mouse_test `pkg-config --cflags --libs gtkglextmm-1.0` \
mouse_test.cpp
and run with no arguments.  The libgtkglextmm1-dev package must be
installed to build the program.

Feel free to reassign this to whatever X package is most appropriate.

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.5-1-686
Locale: LANG=en_US, LC_CTYPE=en_US

Versions of packages libxcursor1 depends on:
ii  libc6                     2.3.2.ds1-13   GNU C Library: Shared libraries an
ii  libx11-6                  4.3.0.dfsg.1-4 X Window System protocol client li
ii  libxrender1               0.8.3-7        X Rendering Extension client libra
ii  xlibs                     4.3.0.dfsg.1-4 X Window System client libraries m

-- no debconf information
/* Copyright (C) 2004  Jonathan Brandmeyer
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation,
 * version 2.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
 */

#include <gtkmm.h>

#ifdef GTKMM_2_4
#include <sigc++/compatibility.h>
#endif

// Headers for gtkglextmm
#include <gtkmm/gl/drawingarea.h>
#include <gdkmm/gl/init.h>

#include <GL/gl.h>

#include <iostream>
#include <cstdlib>

class scene : public Gtk::GL::DrawingArea
{
 public:
	scene();
	virtual ~scene();
	
 private:
	virtual void on_realize();
	virtual bool on_configure_event(GdkEventConfigure* event);
	bool gl_render();
	virtual bool on_expose_event(GdkEventExpose* event);
};

// Only configuration work gets done here.
scene::scene()
{
	// Create a double-buffered Configuration.
	Glib::RefPtr<Gdk::GL::Config> config 
		= Gdk::GL::Config::create( 
		Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE);
	if (!config) {
		std::cerr << "Could not create any OpenGL surface\n";
		std::exit(1);
	}
	set_gl_capability(config);		
}

scene::~scene()
{
}

// Set up parameters common for the scene.  This is called only once when the
// widget is created.
void
scene::on_realize()
{
	Gtk::GL::DrawingArea::on_realize();
	if (!get_gl_window()->gl_begin(get_gl_context()))
		return;
	// Use a transparent black background when clearing it.
	glClearColor( 0, 0, 0, 0);
	get_gl_window()->gl_end();
	Glib::signal_timeout().connect( SigC::slot( *this, &scene::gl_render), 33);
	
}

// Called when the window is resized.
bool
scene::on_configure_event(GdkEventConfigure* event)
{
	// The only task here is to pull off the width and height data for
	// glViewPort.
	Glib::RefPtr<Gdk::GL::Window> gl_window = get_gl_window();
	gl_window->gl_begin(get_gl_context());
	glViewport(0, 0, event->width, event->height);
	gl_window->gl_end();
	return true;
}

bool
scene::gl_render()
{
	// Draw the scene
	get_gl_window()->gl_begin(get_gl_context());
	// glClear(GL_COLOR_BUFFER_BIT);
	get_gl_window()->swap_buffers();
	return true;
}

// Called when the window needs to be redrawn due to another window passing
// in front of it on the screen.
bool
scene::on_expose_event( GdkEventExpose*)
{
	gl_render();
}

// The wrapping application.
class simple : public Gtk::Window
{
 private:
	scene m_scene;
	
 public:
	simple();
	virtual ~simple();
};

simple::simple()
{
	// Sets the title of this window.
	set_title( "Mouse test");
	m_scene.set_size_request( 200, 200);
	add(m_scene);
	show_all();
}

simple::~simple()
{
}

int
main( int argc, char** argv)
{
	// Initialize Gtkmm.
	Gtk::Main kit(&argc, &argv);
	// Initialize GtkGLExt
	Gdk::GL::init(&argc, &argv);
	
	// Create the Main Window
	simple app;
	
	// Enter the main loop - return when the window is closed.
	kit.run(app);
	return 0;	
}

Reply to: