Hello,

I experienced crash with a program that calls Fl_Double_Window::flush() too 
soon so that the myi pointer is NULL.

I added a global null test in the methode to prevent this case... I think this 
should be added to trunk (1.3)

Regards

/**
  Forces the window to be redrawn.
  \param[in] eraseoverlay non-zero to erase overlay, zero to ignore

  Fl_Overlay_Window relies on flush(1) copying the back buffer to the
  front everywhere, even if damage() == 0, thus erasing the overlay,
  and leaving the clip region set to the entire window.
*/
void Fl_Double_Window::flush(int eraseoverlay) {
  make_current(); // make sure fl_gc is non-zero
  Fl_X *myi = Fl_X::i(this);
  if (myi != 0)
  {
          if (!myi->other_xid) {
        #if USE_XDBE
                if (can_xdbe()) {
                  myi->other_xid = XdbeAllocateBackBufferName(fl_display, 
fl_xid(this), XdbeCopied);
                  myi->backbuffer_bad = 1;
                } else
        #endif
        #if defined(USE_X11) || defined(WIN32)
                myi->other_xid = fl_create_offscreen(w(), h());
                clear_damage(FL_DAMAGE_ALL);
        #elif defined(__APPLE_QUARTZ__)
                if (force_doublebuffering_) {
                  myi->other_xid = fl_create_offscreen(w(), h());
                  clear_damage(FL_DAMAGE_ALL);
                }
        #else
        # error unsupported platform
        #endif
          }
        #if USE_XDBE
          if (use_xdbe) {
                if (myi->backbuffer_bad || eraseoverlay) {
                  // Make sure we do a complete redraw...
                  if (myi->region) {XDestroyRegion(myi->region); myi->region = 
0;}
                  clear_damage(FL_DAMAGE_ALL);
                  myi->backbuffer_bad = 0;
                }

                // Redraw as needed...
                if (damage()) {
                  fl_clip_region(myi->region); myi->region = 0;
                  fl_window = myi->other_xid;
                  draw();
                  fl_window = myi->xid;
                }

                // Copy contents of back buffer to window...
                XdbeSwapInfo s;
                s.swap_window = fl_xid(this);
                s.swap_action = XdbeCopied;
                XdbeSwapBuffers(fl_display, &s, 1);
                return;
          } else
        #endif
          if (damage() & ~FL_DAMAGE_EXPOSE) {
                fl_clip_region(myi->region); myi->region = 0;
        #ifdef WIN32
                HDC _sgc = fl_gc;
                fl_gc = fl_makeDC(myi->other_xid);
                int save = SaveDC(fl_gc);
                fl_restore_clip(); // duplicate region into new gc
                draw();
                RestoreDC(fl_gc, save);
                DeleteDC(fl_gc);
                fl_gc = _sgc;
                //# if defined(FLTK_USE_CAIRO)
                //if Fl::cairo_autolink_context() Fl::cairo_make_current(this); 
// capture gc changes automatically to update the cairo context adequately
                //# endif
        #elif defined(__APPLE__)
                if ( myi->other_xid ) {
                  fl_begin_offscreen( myi->other_xid );
                  fl_clip_region( 0 );
                  draw();
                  fl_end_offscreen();
                } else {
                  draw();
                }
        #else // X:
                fl_window = myi->other_xid;
                draw();
                fl_window = myi->xid;
        #endif
          }
          if (eraseoverlay) fl_clip_region(0);
          // on Irix (at least) it is faster to reduce the area copied to
          // the current clip region:
          int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H);
          if (myi->other_xid) fl_copy_offscreen(X, Y, W, H, myi->other_xid, X, 
Y);
  }
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to