summaryrefslogtreecommitdiff
path: root/src/drivers/X11
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 /src/drivers/X11
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
Diffstat (limited to 'src/drivers/X11')
-rw-r--r--src/drivers/X11/Fl_X11_Window_Driver.cxx76
1 files changed, 75 insertions, 1 deletions
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$".