summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-03-06 21:33:07 +0000
committerManolo Gouy <Manolo>2016-03-06 21:33:07 +0000
commitacfeee6d78fd8d6b5bfeb094a09241885af143fc (patch)
tree878f2d6db08935efe4e0709c8f12139e2233f469
parent7e2dc9daf53c9a9d95b59505491df77daa3f1fc4 (diff)
New, driver-based Fl_Double_Window implementation.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11303 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--FL/Fl_Double_Window.H6
-rw-r--r--FL/Fl_Image_Surface.H2
-rw-r--r--FL/Fl_Overlay_Window.H1
-rw-r--r--FL/Fl_Window_Driver.H3
-rw-r--r--src/Fl_Copy_Surface.cxx1
-rw-r--r--src/Fl_Double_Window.cxx182
-rw-r--r--src/Fl_Image_Surface.cxx1
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx11
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.h1
-rw-r--r--src/drivers/X11/Fl_X11_Window_Driver.cxx76
10 files changed, 143 insertions, 141 deletions
diff --git a/FL/Fl_Double_Window.H b/FL/Fl_Double_Window.H
index e4ef883f5..46dd106f2 100644
--- a/FL/Fl_Double_Window.H
+++ b/FL/Fl_Double_Window.H
@@ -40,11 +40,11 @@
class FL_EXPORT Fl_Double_Window : public Fl_Window {
protected:
void flush(int eraseoverlay);
+public:
/**
- Force double buffering, even if the OS already buffers windows
- (overlays need that on MacOS and Windows2000)
+ Return non-null if this is an Fl_Overlay_Window object.
*/
- char force_doublebuffering_;
+ virtual Fl_Double_Window *as_overlay_window() {return NULL; }
public:
void show();
void show(int a, char **b) {Fl_Window::show(a,b);}
diff --git a/FL/Fl_Image_Surface.H b/FL/Fl_Image_Surface.H
index f556ed549..fa98a4bcd 100644
--- a/FL/Fl_Image_Surface.H
+++ b/FL/Fl_Image_Surface.H
@@ -53,7 +53,6 @@ class FL_EXPORT Fl_Image_Surface : public Fl_Widget_Surface {
private:
class Helper;
Helper *platform_surface;
- Fl_Offscreen offscreen();
protected:
void translate(int x, int y);
void untranslate();
@@ -69,6 +68,7 @@ public:
void origin(int x, int y);
int printable_rect(int *w, int *h);
Fl_Offscreen get_offscreen_before_delete();
+ Fl_Offscreen offscreen();
};
#endif // Fl_Image_Surface_H
diff --git a/FL/Fl_Overlay_Window.H b/FL/Fl_Overlay_Window.H
index de45b6c17..5114d3029 100644
--- a/FL/Fl_Overlay_Window.H
+++ b/FL/Fl_Overlay_Window.H
@@ -72,6 +72,7 @@ protected:
Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0);
public:
void show(int a, char **b) {Fl_Double_Window::show(a,b);}
+ virtual Fl_Double_Window *as_overlay_window() {return this; }
};
#endif
diff --git a/FL/Fl_Window_Driver.H b/FL/Fl_Window_Driver.H
index dea792669..540b6971f 100644
--- a/FL/Fl_Window_Driver.H
+++ b/FL/Fl_Window_Driver.H
@@ -40,6 +40,9 @@ public:
static Fl_Window_Driver *newWindowDriver(Fl_Window *);
virtual void take_focus() { }
+ virtual int double_flush(int eraseoverlay);
+ virtual void destroy_double_buffer();
+ void draw() {w->draw();}
};
diff --git a/src/Fl_Copy_Surface.cxx b/src/Fl_Copy_Surface.cxx
index 475ee902e..53985e080 100644
--- a/src/Fl_Copy_Surface.cxx
+++ b/src/Fl_Copy_Surface.cxx
@@ -26,6 +26,7 @@
#include <src/drivers/GDI/Fl_GDI_Copy_Surface.H>
#elif defined(USE_SDL)
+#include <src/drivers/SDL/Fl_SDL_Copy_Surface.H>
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement class Fl_Copy_Surface::Helper for your platform"
diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx
index 243101f96..be9b016cc 100644
--- a/src/Fl_Double_Window.cxx
+++ b/src/Fl_Double_Window.cxx
@@ -19,58 +19,28 @@
Fl_Double_Window implementation.
*/
-#include "config_lib.h"
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Overlay_Window.H>
#include <FL/Fl_Printer.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
+#include <FL/Fl_Window_Driver.H>
// On systems that support double buffering "naturally" the base
// Fl_Window class will probably do double-buffer and this subclass
// does nothing.
-#if USE_XDBE
-
-#include <X11/extensions/Xdbe.h>
-
-static int use_xdbe;
-
-static int can_xdbe() {
- static int tried;
- if (!tried) {
- tried = 1;
- int event_base, error_base;
- if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
- Drawable root = RootWindow(fl_display,fl_screen);
- int numscreens = 1;
- XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
- if (!a) return 0;
- for (int j = 0; j < a->count; j++) {
- if (a->visinfo[j].visual == fl_visual->visualid
- /*&& a->visinfo[j].perflevel > 0*/) {
- use_xdbe = 1; break;
- }
- }
- XdbeFreeVisualInfo(a);
- }
- return use_xdbe;
-}
-#endif
-
Fl_Double_Window::Fl_Double_Window(int W, int H, const char *l)
-: Fl_Window(W,H,l),
- force_doublebuffering_(0)
+: Fl_Window(W,H,l)
{
type(FL_DOUBLE_WINDOW);
}
Fl_Double_Window::Fl_Double_Window(int X, int Y, int W, int H, const char *l)
-: Fl_Window(X,Y,W,H,l),
- force_doublebuffering_(0)
+: Fl_Window(X,Y,W,H,l)
{
type(FL_DOUBLE_WINDOW);
}
@@ -111,126 +81,68 @@ void Fl_Double_Window::flush() {flush(0);}
void Fl_Double_Window::flush(int eraseoverlay) {
if (!shown()) return;
make_current(); // make sure fl_gc is non-zero
- Fl_X *myi = Fl_X::i(this);
+ Fl_Window_Driver *myi = (Fl_Window_Driver*)Fl_X::i(this);
if (!myi) return; // window not yet created
- 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__) // PORTME: platform double buffering
- if (force_doublebuffering_) {
- myi->other_xid = fl_create_offscreen(w(), h());
- clear_damage(FL_DAMAGE_ALL);
- }
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: Fl_Window_Driver - call a function to clear any graphics port damage flags"
-#else
-# error unsupported platform
-#endif
+ int retval = myi->double_flush(eraseoverlay);
+ if (retval) return;
+ if (eraseoverlay) fl_clip_region(0);
+ // on Irix (at least) it is faster to reduce the area copied to
+ // the current clip region:
+ if (myi->other_xid) {
+ int X,Y,W,H; fl_graphics_driver->clip_box(0,0,w(),h(),X,Y,W,H);
+ fl_graphics_driver->copy_offscreen(X, Y, W, H, myi->other_xid, X, Y);
}
-#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
- void* _sgc = fl_graphics_driver->gc();
- HDC gc = fl_makeDC(myi->other_xid);
- fl_graphics_driver->gc(gc);
- int save = SaveDC(gc);
- fl_restore_clip(); // duplicate region into new gc
- draw();
- RestoreDC(gc, save);
- DeleteDC(gc);
- fl_graphics_driver->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__) // PORTME: Fl_Window_Driver - platform double buffering
- if ( myi->other_xid ) {
- fl_begin_offscreen( myi->other_xid );
- fl_clip_region( 0 );
- draw();
- fl_end_offscreen();
- } else {
- draw();
- }
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: manage double buffered drawing"
-#else // X:
- fl_window = myi->other_xid;
+int Fl_Window_Driver::double_flush(int eraseoverlay) {
+ /* This is a working, platform-independent implementation.
+ Some platforms may re-implement it for their own logic:
+ - on Mac OS, the system double buffers all windows, so it is
+ reimplemented to do the same as Fl_Window::flush(), except for
+ Fl_Overlay_Window's which fall back on this implementation.
+ - on Xlib, it is reimplemented if the Xdbe extension is available.
+ */
+ if (!other_xid) {
+ other_xid = fl_create_offscreen(w->w(), w->h());
+ w->clear_damage(FL_DAMAGE_ALL);
+ }
+ if (w->damage() & ~FL_DAMAGE_EXPOSE) {
+ fl_clip_region(region); region = 0;
+ fl_begin_offscreen(other_xid);
+ fl_graphics_driver->clip_region( 0 );
draw();
- fl_window = myi->xid;
-#endif
+ fl_end_offscreen();
}
- 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_graphics_driver->copy_offscreen(X, Y, W, H, myi->other_xid, X, Y);
+ return 0;
}
void Fl_Double_Window::resize(int X,int Y,int W,int H) {
int ow = w();
int oh = h();
Fl_Window::resize(X,Y,W,H);
-#if USE_XDBE
- if (use_xdbe) {
- Fl_X* myi = Fl_X::i(this);
- if (myi && myi->other_xid && (ow < w() || oh < h())) {
- // STR #2152: Deallocate the back buffer to force creation of a new one.
- XdbeDeallocateBackBufferName(fl_display,myi->other_xid);
- myi->other_xid = 0;
- }
- return;
- }
-#endif
- Fl_X* myi = Fl_X::i(this);
- if (myi && myi->other_xid && (ow != w() || oh != h())) {
- fl_delete_offscreen(myi->other_xid);
- myi->other_xid = 0;
- }
+ Fl_Window_Driver *myi = (Fl_Window_Driver*)Fl_X::i(this);
+ if (myi && myi->other_xid && (ow < w() || oh < h()))
+ myi->destroy_double_buffer();
}
void Fl_Double_Window::hide() {
- Fl_X* myi = Fl_X::i(this);
+ Fl_Window_Driver *myi = (Fl_Window_Driver*)Fl_X::i(this);
if (myi && myi->other_xid) {
-#if USE_XDBE
- if (!use_xdbe)
-#endif
- fl_delete_offscreen(myi->other_xid);
+ myi->destroy_double_buffer();
}
Fl_Window::hide();
}
+void Fl_Window_Driver::destroy_double_buffer() {
+ /* This is a working, platform-independent implementation.
+ Some platforms may re-implement it for their own logic:
+ - on Xlib, it is reimplemented if the Xdbe extension is available.
+ */
+ fl_delete_offscreen(other_xid);
+ other_xid = 0;
+}
+
+
/**
The destructor <I>also deletes all the children</I>. This allows a
whole tree to be deleted at once, without having to keep a pointer to
@@ -245,7 +157,6 @@ Fl_Overlay_Window::Fl_Overlay_Window(int W, int H, const char *l)
: Fl_Double_Window(W,H,l)
{
overlay_ = 0;
- force_doublebuffering_=1;
image(0);
}
@@ -254,7 +165,6 @@ Fl_Overlay_Window::Fl_Overlay_Window(int X, int Y, int W, int H, const char *l)
: Fl_Double_Window(X,Y,W,H,l)
{
overlay_ = 0;
- force_doublebuffering_=1;
image(0);
}
diff --git a/src/Fl_Image_Surface.cxx b/src/Fl_Image_Surface.cxx
index 53663554a..de7c7a9f0 100644
--- a/src/Fl_Image_Surface.cxx
+++ b/src/Fl_Image_Surface.cxx
@@ -27,6 +27,7 @@
#include <src/drivers/GDI/Fl_GDI_Image_Surface.H>
#elif defined(USE_SDL)
+#include <src/drivers/SDL/Fl_SDL_Image_Surface.H>
#elif defined(FL_PORTING)
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
index 4a665a871..08a3184b9 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
@@ -19,6 +19,8 @@
#include "../../config_lib.h"
#include "Fl_Cocoa_Window_Driver.h"
+#include <FL/Fl_Double_Window.H>
+#include <FL/fl_draw.H>
Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w)
@@ -41,6 +43,15 @@ void Fl_Cocoa_Window_Driver::take_focus()
set_key_window();
}
+int Fl_Cocoa_Window_Driver::double_flush(int eraseoverlay) {
+ if ( ((Fl_Double_Window*)w)->as_overlay_window() ) {
+ Fl_Window_Driver::double_flush(eraseoverlay);
+ } else {
+ draw();
+ }
+ return 0;
+}
+
//
// End of "$Id$".
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.h b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.h
index b0c756aa1..e7f683689 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.h
+++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.h
@@ -47,6 +47,7 @@ class FL_EXPORT Fl_Cocoa_Window_Driver : public Fl_Window_Driver
public:
Fl_Cocoa_Window_Driver(Fl_Window*);
virtual void take_focus();
+ int double_flush(int eraseoverlay);
};
diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx
index 0da90b246..2912169a9 100644
--- a/src/drivers/X11/Fl_X11_Window_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx
@@ -19,11 +19,29 @@
#include "../../config_lib.h"
#include "Fl_X11_Window_Driver.H"
+#include <FL/fl_draw.H>
+#if USE_XDBE
+#include <X11/extensions/Xdbe.h>
+static int can_xdbe(); // forward
+
+// class to be used only if Xdbe is used
+class Fl_X11_Dbe_Window_Driver : public Fl_X11_Window_Driver {
+public:
+ Fl_X11_Dbe_Window_Driver(Fl_Window *w) : Fl_X11_Window_Driver(w) {}
+ virtual int double_flush(int eraseoverlay);
+ virtual void destroy_double_buffer();
+};
+#endif
Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w)
{
- return new Fl_X11_Window_Driver(w);
+#if USE_XDBE
+ if (can_xdbe()) // strictly necessary only for Fl_Double_Window, but does no harm for Fl_Window
+ return new Fl_X11_Dbe_Window_Driver(w);
+ else
+#endif
+ return new Fl_X11_Window_Driver(w);
}
@@ -41,6 +59,62 @@ void Fl_X11_Window_Driver::take_focus()
Fl_X::activate_window(xid);
}
+#if USE_XDBE
+
+static int can_xdbe() { // whether the Xdbe extension is usable
+ static int tried;
+ static int use_xdbe = 0;
+ if (!tried) {
+ tried = 1;
+ int event_base, error_base;
+ if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
+ Drawable root = RootWindow(fl_display,fl_screen);
+ int numscreens = 1;
+ XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+ if (!a) return 0;
+ for (int j = 0; j < a->count; j++) {
+ if (a->visinfo[j].visual == fl_visual->visualid) {
+ use_xdbe = 1; break;
+ }
+ }
+ XdbeFreeVisualInfo(a);
+ }
+ return use_xdbe;
+}
+
+int Fl_X11_Dbe_Window_Driver::double_flush(int eraseoverlay) {
+ if (!other_xid) {
+ other_xid = XdbeAllocateBackBufferName(fl_display, xid, XdbeCopied);
+ backbuffer_bad = 1;
+ w->clear_damage(FL_DAMAGE_ALL);
+ }
+ if (backbuffer_bad || eraseoverlay) {
+ // Make sure we do a complete redraw...
+ if (region) {XDestroyRegion(region); region = 0;}
+ w->clear_damage(FL_DAMAGE_ALL);
+ backbuffer_bad = 0;
+ }
+ // Redraw as needed...
+ if (w->damage()) {
+ fl_clip_region(region); region = 0;
+ fl_window = other_xid;
+ draw();
+ fl_window = xid;
+ }
+ // Copy contents of back buffer to window...
+ XdbeSwapInfo s;
+ s.swap_window = xid;
+ s.swap_action = XdbeCopied;
+ XdbeSwapBuffers(fl_display, &s, 1);
+ return 1;
+}
+
+void Fl_X11_Dbe_Window_Driver::destroy_double_buffer() {
+ XdbeDeallocateBackBufferName(fl_display, other_xid);
+ other_xid = 0;
+}
+
+#endif // USE_XDBE
//
// End of "$Id$".