Re: Bug (?) in Gtk::FileChooserDialog



Am Donnerstag, den 08.09.2005, 12:46 +0200 schrieb Murray Cumming:
> On Tue, 2005-09-06 at 18:26 +0200, Sean Farrell wrote:
> > Hi there,
> > 
> > what is the fundamental difference between the FileSelection and the
> > FileChooserDialog? 
> 
> They look different and have different capabilities. FileSelection is
> deprecated.
> 
> > The problem I have is the following:
> > 
> > I am using Gtk::GL:DrawingArea (gtkglexmm 1.1) to render openGL
> > geometries and stuff. Now when I invoke a FileChooserDialog the
> > DrawingArea crashes with a segmentation fault. It shows the following 
> > error: "GdkGLExt-WARNING **: glXMakeCurrent() failed" just beforehand. 
> > 
> > When I use (old) FileSelection dialog all runs fine; with any other
> > dialog too. 
> 
> It would probably be best to create a simple-as-possible test case. Then
> you could try getting the same error without OpenGL, or try it with a
> GtkFileChooser with C instead of a Gtk::FileChooser. I suspect that
> gtkmm has not influence on the problem, so it might be in GTK+ or
> gtkglex.
> 
> valgrind or gdb's backtrace might also help.
> 

Sorry I hit the wrong button

/*
    12 Sep. 2005
    
    Sean Farrell <farrell baw de>
                 <rioki users sf net>

    This is an example that demonstrates the Bug in Gtk::GL::DrawingArea with
    Gtk::FileChooser. 
    
    Bug description:
    
    The mere presence of the FileChooserDialog causes to invalidate the 
    openGL context and the DrawingArea.
    
    In the expose events: 
    First it DA prompts: GdkGLExt-WARNING **: glXMakeCurrent() failed
    and then segfaults. I believe that either the gl-context or the gl-window
    are invalid. Both are still valid addresses and valgrind dose not want to 
    work with GTK properly.
    
    Any other dialogs and windows do not cause the bug.
    
    ToDo:
    
    Write the whole stuff in C. Unfortunately I have never used GTK (in C) 
    and hence it might take a while to do it. Any help?
    
    Dependencies:
    
    GTKMM 2.4 / 2.6 
    gtkglextmm 1.1 (1.2 interface) (gtkglext.sf.net)
    
    Compile:
    
     g++ -g -Wall `pkg-config gtkglextmm-1.2 --cflags --libs` da_filechooser_bug.cpp
    

*/


#include <gtkmm.h>
#include <gtkglmm.h>

#include <iostream>
#include <cassert>

#include <GL/gl.h>
#include <GL/glu.h>

using std::cout;
using std::cerr;
using std::endl;
//using std::assert;

// a openGL drawing area
Gtk::GL::DrawingArea* gl_area;

// the stuff we need to make a mini menu
Glib::RefPtr<Gtk::UIManager> ui_manager;
Glib::RefPtr<Gtk::ActionGroup> action_group;


// get / create the openGL config we can use
Glib::RefPtr<Gdk::GL::Config> create_gl_config() {
  Glib::RefPtr<Gdk::GL::Config> glconfig;

  // Try double-buffered visual
  glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB    |
                                     Gdk::GL::MODE_DEPTH  |
                                     Gdk::GL::MODE_DOUBLE);
  if (!glconfig) {  
    cerr << "*** Cannot find the double-buffered visual.\n"
         << "*** Trying single-buffered visual.\n";

    // Try single-buffered visual
    glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB   |
                                       Gdk::GL::MODE_DEPTH);
    if (!glconfig) {
      cerr << "*** Cannot find any OpenGL-capable visual.\n";
      exit(1);
    }
  }
  
  return glconfig;
}

// setup the openGL 
// general stuff for openGL 
void setup_opengl() {
  
  Glib::RefPtr<Gdk::GL::Window> glwindow = gl_area->get_gl_window();

  if (!glwindow->gl_begin(gl_area->get_gl_context())) {
    return;
  }
  
  glClearColor(1, 1, 1, 1);
  glClearDepth(1.0);
    
  glViewport(0, 0, gl_area->get_width(), gl_area->get_height());
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  
  float ratio = static_cast<float>(gl_area->get_width())/static_cast<float>(gl_area->get_height());
  gluPerspective(40.0, ratio, 1.0, 100.0);

  glMatrixMode(GL_MODELVIEW);
    
  glShadeModel(GL_SMOOTH);
  
  glwindow->gl_end();
}

// draw a triangle... anything
bool draw_stuff(GdkEventExpose*) {

  Glib::RefPtr<Gdk::GL::Window> glwindow = gl_area->get_gl_window();

  if (!glwindow->gl_begin(gl_area->get_gl_context())) {
    return false;
  }
  
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();  
    
  glTranslatef(0.0,0.0,-6.0);
  
  glBegin(GL_TRIANGLES);
    
    glColor3f(0.5,0.5,1.0);
    glVertex3f(0.0,1.0,0.0);
    
    glColor3f(0.5,1.0,0.5);
    glVertex3f(-1.0,0.0,0.0);
    
    glColor3f(1.0,0.5,0.5);
    glVertex3f(1.0,0.0,0.0);
  
  glEnd();
  
  if (glwindow->is_double_buffered()) {
      glwindow->swap_buffers();
  }
  else {
    glFlush();
  }
  
  glwindow->gl_end();
  
  return true;
}

// react on resize 
// reset the viewport and view ratio
bool on_resize(GdkEventConfigure* event) {

  Glib::RefPtr<Gdk::GL::Window> glwindow = gl_area->get_gl_window();

  if (!glwindow->gl_begin(gl_area->get_gl_context())) {
    return true;
  }

  glViewport(0, 0, gl_area->get_width(), gl_area->get_height());
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  
  float ratio = static_cast<float>(gl_area->get_width())/static_cast<float>(gl_area->get_height());
  gluPerspective(40.0, ratio, 1.0, 100.0);

  glMatrixMode(GL_MODELVIEW);

  glwindow->gl_end();
  
  return true;
}

void on_open_file_chooser() {

  Gtk::FileChooserDialog dialog("FileChooserDialog");
  
  dialog.run();
}

void on_open_file_selection() {
  Gtk::FileSelection dialog("FileSelection");
  
  dialog.run();
}

void on_open_other_dialog() {

  Gtk::MessageDialog dialog("Hello there!");
  
  dialog.run();
}

void make_menu(Gtk::VBox& seperator, Gtk::Window& main_window) {
  
  action_group = Gtk::ActionGroup::create();
    
  action_group->add(Gtk::Action::create("open_file_chooser", "File Chooser"),
                          sigc::ptr_fun(&on_open_file_chooser));
  action_group->add(Gtk::Action::create("open_file_selection", "File Selection"),
                          sigc::ptr_fun(&on_open_file_selection));
  action_group->add(Gtk::Action::create("open_other_dialog", "Other Dialog"),
                          sigc::ptr_fun(&on_open_other_dialog));
        
  ui_manager = Gtk::UIManager::create();
  ui_manager->insert_action_group(action_group);
    
  main_window.add_accel_group(ui_manager->get_accel_group());
    
  Glib::ustring ui_string = "<ui>"
                      "  <toolbar name='main_toolbar'>" 
                      "    <toolitem action='open_file_chooser' />"
                      "    <toolitem action='open_file_selection' />"
                      "    <toolitem action='open_other_dialog' />"
                      "  </toolbar>"
                      "</ui>";
                      
  try {                   
    ui_manager->add_ui_from_string(ui_string);
  } catch (Glib::Error& err) {
    cerr << err.what() << endl;
  }                       
  
  seperator.pack_start(*ui_manager->get_widget("/main_toolbar"), Gtk::PACK_SHRINK);
  
}

void make_drawing_area(Gtk::VBox& seperator, Gtk::Window& main_window) {
  // create the drawing area
  gl_area = Gtk::manage(new Gtk::GL::DrawingArea(create_gl_config()));

  seperator.pack_start(*gl_area, Gtk::PACK_EXPAND_WIDGET);
  
  // attach the necessary events
  gl_area->signal_realize().connect(sigc::ptr_fun(&setup_opengl), false);
  gl_area->signal_expose_event().connect(sigc::ptr_fun(&draw_stuff), false);
  gl_area->signal_configure_event().connect(sigc::ptr_fun(&on_resize), false);
  
}


int main(int argc, char** argv) {
  // init the bunch
  Gtk::Main gtk_main(argc, argv);
  Gtk::GL::init(argc, argv);

  // the main window
  Gtk::Window main_window;
  
  // and its main seperator
  Gtk::VBox seperator(0,false);

  main_window.add(seperator);
  
  // make the window
  make_menu(seperator, main_window);   
  make_drawing_area(seperator, main_window);
  
  main_window.set_default_size(300,300);
  main_window.show_all_children();
  
  // go into the gtk event loop
  gtk_main.run(main_window);

  return 0;
}




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