Fix crash when Fl_Window::flush() is called before show() (STR #3028).

The fix is twofold:
 (1) if Fl_Window::flush() is called, this is ignored silently
 (2) if Fl_Window::make_current() is called directly, but the window
     is currently not shown(), then the program will be terminated
     with an error message.
The latter is necessary because returning from make_current() would
leave the program in a state where it would expect to have a valid
drawing context.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10095 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Albrecht Schlosser 2014-02-07 00:09:52 +00:00
parent 74aeae38cb
commit ef952dfa53
6 changed files with 10 additions and 0 deletions

View File

@ -1,5 +1,6 @@
CHANGES IN FLTK 1.3.3 RELEASED: MMM DD YYYY CHANGES IN FLTK 1.3.3 RELEASED: MMM DD YYYY
- fix crash if Fl_Window::flush() was called, but window not shown() (STR #3028).
- new method Fl::scheme_is(const char *name) returns 1 if current scheme is name. - new method Fl::scheme_is(const char *name) returns 1 if current scheme is name.
- Fixed recent MinGW build WRT configure not finding strcasecmp() (STR #2994). - Fixed recent MinGW build WRT configure not finding strcasecmp() (STR #2994).
Note: This fix is temporary and should be revisited later. Note: This fix is temporary and should be revisited later.

View File

@ -1750,6 +1750,7 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) {
Fl::damage(FL_DAMAGE_CHILD); Fl::damage(FL_DAMAGE_CHILD);
} }
void Fl_Window::flush() { void Fl_Window::flush() {
if (!shown()) return;
make_current(); make_current();
//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this; //if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this;
fl_clip_region(i->region); i->region = 0; fl_clip_region(i->region); i->region = 0;

View File

@ -369,6 +369,7 @@ void Fl_Double_Window::flush() {flush(0);}
and leaving the clip region set to the entire window. and leaving the clip region set to the entire window.
*/ */
void Fl_Double_Window::flush(int eraseoverlay) { void Fl_Double_Window::flush(int eraseoverlay) {
if (!shown()) return;
make_current(); // make sure fl_gc is non-zero make_current(); // make sure fl_gc is non-zero
Fl_X *myi = Fl_X::i(this); Fl_X *myi = Fl_X::i(this);
if (!myi) return; // window not yet created if (!myi) return; // window not yet created

View File

@ -292,6 +292,7 @@ int fl_overlay_depth = 0;
void Fl_Gl_Window::flush() { void Fl_Gl_Window::flush() {
if (!shown()) return;
uchar save_valid = valid_f_ & 1; uchar save_valid = valid_f_ & 1;
#if HAVE_GL_OVERLAY && defined(WIN32) #if HAVE_GL_OVERLAY && defined(WIN32)
uchar save_valid_f = valid_f_; uchar save_valid_f = valid_f_;

View File

@ -54,6 +54,7 @@ void Fl_Menu_Window::show() {
} }
void Fl_Menu_Window::flush() { void Fl_Menu_Window::flush() {
if (!shown()) return;
#if HAVE_OVERLAY #if HAVE_OVERLAY
if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;} if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;}
Fl_X *myi = Fl_X::i(this); Fl_X *myi = Fl_X::i(this);

View File

@ -34,6 +34,7 @@
# include <FL/Fl_Tooltip.H> # include <FL/Fl_Tooltip.H>
# include <FL/fl_draw.H> # include <FL/fl_draw.H>
# include <FL/Fl_Paged_Device.H> # include <FL/Fl_Paged_Device.H>
# include <FL/fl_ask.H>
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
# include "flstring.h" # include "flstring.h"
@ -2339,6 +2340,10 @@ GC fl_gc;
// make X drawing go into this window (called by subclass flush() impl.) // make X drawing go into this window (called by subclass flush() impl.)
void Fl_Window::make_current() { void Fl_Window::make_current() {
static GC gc; // the GC used by all X windows static GC gc; // the GC used by all X windows
if (!shown()) {
fl_alert("Fl_Window::make_current(), but window is not shown().");
Fl::fatal("Fl_Window::make_current(), but window is not shown().");
}
if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0); if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
fl_window = i->xid; fl_window = i->xid;
fl_gc = gc; fl_gc = gc;