summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-03-13 22:16:37 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-03-13 22:16:37 +0000
commitb496d18b85917106c48e8e6f74115b3122b603d1 (patch)
tree4d96befa4377a81c89c6a32f4d66220199572938 /src
parent30756ae3500a62bd8f63b4df3eb3ca8f6b8b0b70 (diff)
Fixed 'flush()' code for single, double, and overlay buffering
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11359 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl.cxx8
-rw-r--r--src/Fl_Double_Window.cxx40
-rw-r--r--src/Fl_Overlay_Window.cxx17
-rw-r--r--src/Fl_Printer.cxx2
-rw-r--r--src/Fl_Single_Window.cxx6
-rw-r--r--src/Fl_Window.cxx40
-rw-r--r--src/Fl_Window_Driver.cxx62
-rw-r--r--src/Fl_cocoa.mm2
-rw-r--r--src/Fl_win32.cxx2
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H9
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx120
-rw-r--r--src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx26
-rw-r--r--src/drivers/Pico/Fl_Pico_Window_Driver.H7
-rw-r--r--src/drivers/Pico/Fl_Pico_Window_Driver.cxx45
-rw-r--r--src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx11
-rw-r--r--src/drivers/PicoSDL/Fl_PicoSDL_Screen_Driver.cxx42
-rw-r--r--src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.H6
-rw-r--r--src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.cxx30
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H8
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx84
-rw-r--r--src/drivers/X11/Fl_X11_Window_Driver.H7
-rw-r--r--src/drivers/X11/Fl_X11_Window_Driver.cxx212
22 files changed, 593 insertions, 193 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 88f82a151..5e725cfcc 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -1826,13 +1826,7 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) {
}
Fl::damage(FL_DAMAGE_CHILD);
}
-void Fl_Window::flush() {
- if (!shown()) return;
- make_current();
-//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this;
- fl_clip_region(i->region); i->region = 0;
- draw();
-}
+
#ifdef WIN32
# include "Fl_win32.cxx"
diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx
index 49e890e22..701f53274 100644
--- a/src/Fl_Double_Window.cxx
+++ b/src/Fl_Double_Window.cxx
@@ -56,40 +56,6 @@ void Fl_Double_Window::show() {
}*/
-/**
- Forces the window to be redrawn.
-*/
-void Fl_Double_Window::flush()
-{
- flush(0);
-}
-
-
-/**
- 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) {
- if (!shown()) return;
- make_current(); // make sure fl_gc is non-zero
- Fl_X *myi = Fl_X::i(this);
- if (!myi) return; // window not yet created
- int retval = driver()->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);
- }
-}
-
-
void Fl_Double_Window::resize(int X,int Y,int W,int H) {
int ow = w();
int oh = h();
@@ -108,6 +74,12 @@ void Fl_Double_Window::hide() {
}
+void Fl_Double_Window::flush()
+{
+ driver()->flush_double();
+}
+
+
/**
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
diff --git a/src/Fl_Overlay_Window.cxx b/src/Fl_Overlay_Window.cxx
index c1ae2728e..07065fbb0 100644
--- a/src/Fl_Overlay_Window.cxx
+++ b/src/Fl_Overlay_Window.cxx
@@ -53,20 +53,9 @@ void Fl_Overlay_Window::hide() {
Fl_Double_Window::hide();
}
-void Fl_Overlay_Window::flush() {
-#ifdef BOXX_BUGS
- if (overlay_ && overlay_ != this && overlay_->shown()) {
- // all drawing to windows hidden by overlay windows is ignored, fix this
- XUnmapWindow(fl_display, fl_xid(overlay_));
- Fl_Double_Window::flush(0);
- XMapWindow(fl_display, fl_xid(overlay_));
- return;
- }
-#endif
- int erase_overlay = (damage()&FL_DAMAGE_OVERLAY) | (overlay_ == this);
- clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY));
- Fl_Double_Window::flush(erase_overlay);
- if (overlay_ == this) draw_overlay();
+void Fl_Overlay_Window::flush()
+{
+ driver()->flush_overlay();
}
void Fl_Overlay_Window::resize(int X, int Y, int W, int H) {
diff --git a/src/Fl_Printer.cxx b/src/Fl_Printer.cxx
index 58db4cca8..47ae9748d 100644
--- a/src/Fl_Printer.cxx
+++ b/src/Fl_Printer.cxx
@@ -63,6 +63,8 @@ const char *Fl_Printer::property_cancel = NULL;
#else
+#include "Fl_GDI_Printer.cxx"
+
// print dialog customization strings
/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_title = "Print";
diff --git a/src/Fl_Single_Window.cxx b/src/Fl_Single_Window.cxx
index fd871a3b8..c5e37fabc 100644
--- a/src/Fl_Single_Window.cxx
+++ b/src/Fl_Single_Window.cxx
@@ -31,12 +31,6 @@ void Fl_Single_Window::show()
}
-void Fl_Single_Window::flush()
-{
- Fl_Window::flush();
-}
-
-
Fl_Single_Window::Fl_Single_Window(int W, int H, const char *l)
: Fl_Window(W,H,l)
{
diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx
index 97045174b..98882591e 100644
--- a/src/Fl_Window.cxx
+++ b/src/Fl_Window.cxx
@@ -435,6 +435,46 @@ int Fl_Window::decorated_h()
}
+void Fl_Window::flush()
+{
+ driver()->flush_single();
+}
+
+
+void Fl_Window::draw()
+{
+ pWindowDriver->draw_begin();
+
+ // The following is similar to Fl_Group::draw(), but ...
+ //
+ // - draws the box at (0,0), i.e. with x=0 and y=0 instead of x() and y()
+ // - does NOT draw the label (text)
+ // - draws the image only if FL_ALIGN_INSIDE is set
+ //
+ // Note: The label (text) of top level windows is drawn in the title bar.
+ // Other windows do not draw their labels at all, unless drawn by their
+ // parent widgets or by special draw() methods (derived classes).
+
+ if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing
+ draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0
+
+ if (image() && (align() & FL_ALIGN_INSIDE)) { // draw the image only
+ Fl_Label l1;
+ memset(&l1,0,sizeof(l1));
+ l1.align_ = align();
+ l1.image = image();
+ if (!active_r() && l1.image && l1.deimage) l1.image = l1.deimage;
+ l1.type = labeltype();
+ l1.draw(0,0,w(),h(),align());
+ }
+ }
+ draw_children();
+
+ pWindowDriver->draw_end();
+}
+
+
+
//
// End of "$Id$".
//
diff --git a/src/Fl_Window_Driver.cxx b/src/Fl_Window_Driver.cxx
index 9908fde9d..eda8c2901 100644
--- a/src/Fl_Window_Driver.cxx
+++ b/src/Fl_Window_Driver.cxx
@@ -22,6 +22,7 @@
#include "config_lib.h"
#include <FL/Fl_Window_Driver.H>
#include <FL/Fl.H>
+#include <FL/Fl_Overlay_Window.H>
#include <FL/fl_draw.H>
@@ -37,41 +38,47 @@ Fl_Window_Driver::~Fl_Window_Driver()
}
-/*
- Used in Fl::focus(Fl_Window).
- Default implementation does not need to do anything.
- - reimplemented for OS X Cocoa
- - reimplemented for X11
- */
void Fl_Window_Driver::take_focus()
{
+ // nothing to do
}
-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.
- */
+void Fl_Window_Driver::flush_single()
+{
Fl_X *i = Fl_X::i(pWindow);
-
- if (!i->other_xid) {
- i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
- pWindow->clear_damage(FL_DAMAGE_ALL);
- }
- if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
- fl_clip_region(i->region); i->region = 0;
- fl_begin_offscreen(i->other_xid);
- fl_graphics_driver->clip_region( 0 );
- draw();
- fl_end_offscreen();
- }
- return 0;
+ if (!i) return;
+ fl_clip_region(i->region);
+ i->region = 0;
+ pWindow->draw();
}
+
+void Fl_Window_Driver::flush_double()
+{
+ flush_single();
+}
+
+
+void Fl_Window_Driver::flush_overlay()
+{
+ flush_single();
+}
+
+
+void Fl_Window_Driver::draw_begin()
+{
+ // nothing to do
+}
+
+
+void Fl_Window_Driver::draw_end()
+{
+ // nothing to do
+}
+
+
+
void Fl_Window_Driver::destroy_double_buffer() {
Fl_X *i = Fl_X::i(pWindow);
/* This is a working, platform-independent implementation.
@@ -113,7 +120,6 @@ void Fl_Window_Driver::draw() {
# endif
}
-void Fl_Window::draw() {pWindowDriver->draw();}
/** Assigns a non-rectangular shape to the window.
This function gives an arbitrary shape (not just a rectangular region) to an Fl_Window.
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index 94ade1d9e..821ef57bf 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -84,7 +84,7 @@ static unsigned make_current_counts = 0; // if > 0, then Fl_Window::make_current
static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y, int w, int h);
// make this available on all platforms to make code maintainability easier
-class Fl_Widget *fl_selection_requestor;
+extern class Fl_Widget *fl_selection_requestor;
int fl_mac_os_version = Fl_X::calc_mac_os_version(); // the version number of the running Mac OS X (e.g., 100604 for 10.6.4)
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index 0caf501f1..b1715edb2 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -86,7 +86,7 @@
*/
// make this available on all platforms to make code maintainability easier
-class Fl_Widget *fl_selection_requestor;
+extern class Fl_Widget *fl_selection_requestor;
// Internal functions
static void fl_clipboard_notify_target(HWND wnd);
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
index 419469df7..8a5c8d42e 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
+++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
@@ -52,11 +52,13 @@ struct Fl_Window_Driver::shape_data_type {
CGImageRef mask;
};
+
class FL_EXPORT Fl_Cocoa_Window_Driver : public Fl_Window_Driver
{
private:
void shape_bitmap_(Fl_Image* b);
void shape_alpha_(Fl_Image* img, int offset);
+
public:
Fl_Cocoa_Window_Driver(Fl_Window*);
~Fl_Cocoa_Window_Driver();
@@ -65,7 +67,14 @@ public:
virtual int decorated_w();
virtual int decorated_h();
+ // --- window management
virtual void take_focus();
+ virtual void flush_single();
+ virtual void flush_double();
+ virtual void flush_overlay();
+ virtual void draw_begin();
+ virtual void draw_end();
+
virtual void shape(const Fl_Image* img);
virtual void draw();
// that one is implemented in Fl_Cocoa.mm because it uses Objective-c
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
index 6a4e141d7..0285af9df 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
@@ -20,25 +20,14 @@
#include "../../config_lib.h"
#include "Fl_Cocoa_Window_Driver.h"
#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Overlay_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
-// class used for Fl_Double_Window but not for Fl_Overlay_Window
-class Fl_Cocoa_Double_Window_Driver : public Fl_Cocoa_Window_Driver {
-public:
- Fl_Cocoa_Double_Window_Driver(Fl_Window *w) : Fl_Cocoa_Window_Driver(w) {}
- int double_flush(int eraseoverlay) {
- draw();
- return 0;
- }
-};
Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w)
{
- if (w->as_double_window() && !w->as_double_window()->as_overlay_window())
- return new Fl_Cocoa_Double_Window_Driver(w);
- else
- return new Fl_Cocoa_Window_Driver(w);
+ return new Fl_Cocoa_Window_Driver(w);
}
@@ -47,6 +36,7 @@ Fl_Cocoa_Window_Driver::Fl_Cocoa_Window_Driver(Fl_Window *win)
{
}
+
Fl_Cocoa_Window_Driver::~Fl_Cocoa_Window_Driver()
{
if (shape_data_) {
@@ -57,8 +47,6 @@ Fl_Cocoa_Window_Driver::~Fl_Cocoa_Window_Driver()
}
}
-extern Fl_Window *fl_xfocus;
-
void Fl_Cocoa_Window_Driver::take_focus()
{
@@ -67,6 +55,108 @@ void Fl_Cocoa_Window_Driver::take_focus()
}
+void Fl_Cocoa_Window_Driver::flush_single()
+{
+ if (!pWindow->shown()) return;
+ pWindow->make_current();
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return; // window not yet created
+ fl_clip_region(i->region); i->region = 0;
+ pWindow->draw();
+}
+
+
+void Fl_Cocoa_Window_Driver::flush_double()
+{
+ if (!pWindow->shown()) return;
+ pWindow->make_current();
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return; // window not yet created
+ fl_clip_region(i->region); i->region = 0;
+ pWindow->draw();
+}
+
+
+void Fl_Cocoa_Window_Driver::flush_overlay()
+{
+ Fl_Overlay_Window *oWindow = pWindow->as_overlay_window();
+ if (!oWindow) return flush_single();
+
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return; // window not yet created
+
+ int erase_overlay = (pWindow->damage()&FL_DAMAGE_OVERLAY);
+ pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY));
+
+ if (!i->other_xid) {
+ i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
+ pWindow->clear_damage(FL_DAMAGE_ALL);
+ }
+ if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
+ fl_clip_region(i->region); i->region = 0;
+ if ( i->other_xid ) {
+ fl_begin_offscreen( i->other_xid );
+ fl_clip_region( 0 );
+ draw();
+ fl_end_offscreen();
+ } else {
+ draw();
+ }
+ }
+ if (erase_overlay) fl_clip_region(0);
+
+ int X,Y,W,H; fl_clip_box(0,0,pWindow->w(),pWindow->h(),X,Y,W,H);
+ if (i->other_xid) fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
+
+ if (oWindow->overlay_ == oWindow) oWindow->draw_overlay();
+}
+
+
+void Fl_Cocoa_Window_Driver::draw_begin()
+{
+ if (shape_data_) {
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (shape_data_->mask && (&CGContextClipToMask != NULL)) {
+ CGContextClipToMask(fl_gc, CGRectMake(0,0,pWindow->w(),pWindow->h()), shape_data_->mask); // requires Mac OS 10.4
+ }
+ CGContextSaveGState(fl_gc);
+# endif
+ }
+}
+
+
+void Fl_Cocoa_Window_Driver::draw_end()
+{
+ // on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
+ // corner. This code draws a little ribbed triangle for dragging.
+ if (fl_mac_os_version < 100700 && fl_gc && !pWindow->parent() && pWindow->resizable() &&
+ (!pWindow->size_range_set || pWindow->minh!=pWindow->maxh || pWindow->minw!=pWindow->maxw)) {
+ int dx = Fl::box_dw(pWindow->box())-Fl::box_dx(pWindow->box());
+ int dy = Fl::box_dh(pWindow->box())-Fl::box_dy(pWindow->box());
+ if (dx<=0) dx = 1;
+ if (dy<=0) dy = 1;
+ int x1 = pWindow->w()-dx-1, x2 = x1, y1 = pWindow->h()-dx-1, y2 = y1;
+ Fl_Color c[4] = {
+ pWindow->color(),
+ fl_color_average(pWindow->color(), FL_WHITE, 0.7f),
+ fl_color_average(pWindow->color(), FL_BLACK, 0.6f),
+ fl_color_average(pWindow->color(), FL_BLACK, 0.8f),
+ };
+ int i;
+ for (i=dx; i<12; i++) {
+ fl_color(c[i&3]);
+ fl_line(x1--, y1, x2, y2--);
+ }
+ }
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (shape_data_) CGContextRestoreGState(fl_gc);
+# endif
+}
+
+
+
static void MyProviderReleaseData (void *info, const void *data, size_t size) {
delete[] (uchar*)data;
}
diff --git a/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx b/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx
index 914fdafd3..3968ea756 100644
--- a/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx
+++ b/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx
@@ -35,10 +35,10 @@ void Fl_Pico_Graphics_Driver::point(int x, int y)
void Fl_Pico_Graphics_Driver::rect(int x, int y, int w, int h)
{
- line(x, y, x+w, y);
- line(x+w, y, x+w, y+h);
- line(x+w, y+h, x, y+h);
- line(x, y+h, x, y);
+ line(x, y, x+w-1, y);
+ line(x+w-1, y, x+w-1, y+h-1);
+ line(x+w-1, y+h-1, x, y+h-1);
+ line(x, y+h-1, x, y);
}
void Fl_Pico_Graphics_Driver::rectf(int x, int y, int w, int h)
@@ -231,10 +231,20 @@ static const char *font_data[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* */0, /*!*/"\31\34\100\35\36", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, /*B*/"\43\54\45\15\11\41\52\43\13", 0, 0, /*E*/"\51\11\15\55\100\13\43", 0, 0,
- /*H*/"\11\15\100\61\65\100\13\63", 0, 0, 0, 0, 0, 0, 0,
+ /*0*/"\62\51\21\12\14\25\55\64\62\100\52\61",
+ /*1*/"\22\31\35\100\25\45",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0,
+ /*A*/"\15\31\55\100\23\43",
+ /*B*/"\43\54\45\15\11\41\52\43\13",
+ /*C*/"\62\51\21\12\14\25\55\64",
+ /*D*/"\11\51\62\64\55\15\11",
+ /*E*/"\61\11\15\65\100\13\43",
+ /*F*/"\61\11\15\100\13\43",
+ /*G*/"\62\51\21\12\14\25\55\64\100\65\63\33",
+ /*H*/"\11\15\100\61\65\100\13\63",
+ /*I*/"\21\41\100\31\35\100\25\45", 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, /*T*/"\11\71\100\41\45", 0, 0, /*W*/"\01\15\33\55\61",
/*X*/"\15\51\100\11\55", 0, 0, 0, 0, 0, 0, 0,
diff --git a/src/drivers/Pico/Fl_Pico_Window_Driver.H b/src/drivers/Pico/Fl_Pico_Window_Driver.H
index 51e9db920..40d6457fa 100644
--- a/src/drivers/Pico/Fl_Pico_Window_Driver.H
+++ b/src/drivers/Pico/Fl_Pico_Window_Driver.H
@@ -37,6 +37,13 @@ public:
// --- window data
virtual int decorated_w();
virtual int decorated_h();
+
+ // --- window management
+ virtual void flush_single();
+ virtual void flush_double();
+ virtual void flush_overlay();
+ virtual void draw_begin();
+ virtual void draw_end();
};
diff --git a/src/drivers/Pico/Fl_Pico_Window_Driver.cxx b/src/drivers/Pico/Fl_Pico_Window_Driver.cxx
index b14696d6f..bb5b4e612 100644
--- a/src/drivers/Pico/Fl_Pico_Window_Driver.cxx
+++ b/src/drivers/Pico/Fl_Pico_Window_Driver.cxx
@@ -25,14 +25,6 @@
-// TODO: move this to Fl_Window_Driver
-void Fl_X::flush()
-{
- w->driver()->flush();
-}
-
-
-
Fl_Pico_Window_Driver::Fl_Pico_Window_Driver(Fl_Window *win)
: Fl_Window_Driver(win)
{
@@ -58,6 +50,43 @@ int Fl_Pico_Window_Driver::decorated_h()
}
+// --- window management
+void Fl_Pico_Window_Driver::flush_single()
+{
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return;
+ fl_clip_region(i->region);
+ i->region = 0;
+ pWindow->draw();
+}
+
+
+void Fl_Pico_Window_Driver::flush_double()
+{
+ flush_single();
+}
+
+
+void Fl_Pico_Window_Driver::flush_overlay()
+{
+ flush_single();
+}
+
+
+
+
+void Fl_Pico_Window_Driver::draw_begin()
+{
+ // nothing to do
+}
+
+
+void Fl_Pico_Window_Driver::draw_end()
+{
+ // nothing to do
+}
+
+
//
// End of "$Id: Fl_Pico_Window_Driver.cxx 11253 2016-03-01 00:54:21Z matt $".
// \ No newline at end of file
diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx
index 6e06c85ab..17957312e 100644
--- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx
+++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx
@@ -95,6 +95,17 @@ Fl_X *Fl_PicoAndroid_Window_Driver::makeWindow()
#include <FL/fl_draw.h>
+
+void Fl_Window_Driver::draw_begin()
+{
+}
+
+
+void Fl_Window_Driver::draw_end()
+{
+}
+
+
void Fl_PicoAndroid_Window_Driver::flush()
{
Fl_PicoAndroid_Screen_Driver *scr = (Fl_PicoAndroid_Screen_Driver*)Fl::screen_driver();
diff --git a/src/drivers/PicoSDL/Fl_PicoSDL_Screen_Driver.cxx b/src/drivers/PicoSDL/Fl_PicoSDL_Screen_Driver.cxx
index 82d94dcd5..942c5a523 100644
--- a/src/drivers/PicoSDL/Fl_PicoSDL_Screen_Driver.cxx
+++ b/src/drivers/PicoSDL/Fl_PicoSDL_Screen_Driver.cxx
@@ -52,24 +52,27 @@ double Fl_PicoSDL_Screen_Driver::wait(double time_to_wait)
switch (e.type) {
case SDL_QUIT:
exit(0);
- case SDL_WINDOWEVENT_EXPOSED:
- case SDL_WINDOWEVENT_SHOWN:
- { // not happening!
- //event->window.windowID
- if ( !window ) break;;
- Fl_X *i = Fl_X::i(Fl::first_window());
- i->wait_for_expose = 0;
-
- if ( i->region ) {
- XDestroyRegion(i->region);
- i->region = 0;
+ case SDL_WINDOWEVENT:
+ switch (e.window.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ case SDL_WINDOWEVENT_SHOWN:
+ {
+ //event->window.windowID
+ if ( !window ) break;;
+ Fl_X *i = Fl_X::i(Fl::first_window());
+ i->wait_for_expose = 0;
+
+ if ( i->region ) {
+ XDestroyRegion(i->region);
+ i->region = 0;
+ }
+ window->clear_damage(FL_DAMAGE_ALL);
+ i->flush();
+ window->clear_damage();
+ Fl_X::first->wait_for_expose = 0;
+ }
+ break;
}
- window->clear_damage(FL_DAMAGE_ALL);
- i->flush();
- window->clear_damage();
- Fl_X::first->wait_for_expose = 0;
- }
- break;
case SDL_MOUSEBUTTONDOWN:
if (!window) break;
Fl::e_is_click = e.button.clicks;
@@ -204,6 +207,11 @@ void Fl::remove_fd(int)
{
}
+void Fl_X::flush()
+{
+ w->flush();
+}
+
//
// End of "$Id: Fl_PicoSDL_Screen_Driver.cxx 11253 2016-03-01 00:54:21Z matt $".
diff --git a/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.H b/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.H
index cc4fb81c4..7cb2e7c43 100644
--- a/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.H
+++ b/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.H
@@ -40,7 +40,11 @@ public:
virtual ~Fl_PicoSDL_Window_Driver();
virtual Fl_X *makeWindow();
- virtual void flush();
+
+ // --- window management
+ virtual void flush_single();
+ virtual void flush_double();
+ virtual void flush_overlay();
};
diff --git a/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.cxx b/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.cxx
index a9a7fc95f..346eea241 100644
--- a/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.cxx
+++ b/src/drivers/PicoSDL/Fl_PicoSDL_Window_Driver.cxx
@@ -72,7 +72,7 @@ Fl_X *Fl_PicoSDL_Window_Driver::makeWindow()
pWindow->set_visible();
pWindow->redraw();
- flush();
+ pWindow->flush();
int old_event = Fl::e_number;
pWindow->handle(Fl::e_number = FL_SHOW);
Fl::e_number = old_event;
@@ -81,14 +81,34 @@ Fl_X *Fl_PicoSDL_Window_Driver::makeWindow()
}
-void Fl_PicoSDL_Window_Driver::flush()
+void Fl_PicoSDL_Window_Driver::flush_single()
{
- SDL_RenderClear((SDL_Renderer*)fl_window);
- pWindow->flush();
- SDL_RenderPresent((SDL_Renderer*)fl_window);
+ if (!pWindow->shown()) return;
+ pWindow->make_current();
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return;
+ fl_clip_region(i->region);
+ i->region = 0;
+// SDL_RenderClear((SDL_Renderer*)i->xid);
+ pWindow->draw();
+ SDL_RenderPresent((SDL_Renderer*)i->xid);
+}
+
+
+void Fl_PicoSDL_Window_Driver::flush_double()
+{
+ flush_single();
}
+void Fl_PicoSDL_Window_Driver::flush_overlay()
+{
+ flush_single();
+ // draw_overlay();
+}
+
+
+
//
// End of "$Id: Fl_PicoSDL_Window_Driver.cxx 11253 2016-03-01 00:54:21Z matt $".
// \ No newline at end of file
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H
index f4521b5e7..ebcf72440 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H
+++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H
@@ -72,8 +72,14 @@ public:
virtual int decorated_w();
virtual int decorated_h();
+ // --- window management
+ virtual void flush_single();
+ virtual void flush_double();
+ virtual void flush_overlay();
+ virtual void draw_begin();
+ virtual void draw_end();
+
virtual void shape(const Fl_Image* img);
- virtual void draw();
virtual void icons(const Fl_RGB_Image *icons[], int count);
virtual const void *icon() const;
virtual void icon(const void * ic);
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx
index 6e7d546da..c1893b841 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx
@@ -18,11 +18,13 @@
#include "../../config_lib.h"
+#include <FL/fl_draw.H>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Bitmap.H>
#include <FL/Fl_Window.H>
+#include <FL/Fl_Overlay_Window.H>
#include <FL/x.H>
#include "Fl_WinAPI_Window_Driver.H"
#include <windows.h>
@@ -40,6 +42,7 @@ Fl_WinAPI_Window_Driver::Fl_WinAPI_Window_Driver(Fl_Window *win)
memset(icon_, 0, sizeof(Fl_Window_Driver::icon_data));
}
+
Fl_WinAPI_Window_Driver::~Fl_WinAPI_Window_Driver()
{
if (shape_data_) {
@@ -96,6 +99,7 @@ int Fl_WinAPI_Window_Driver::decorated_h()
}
+// --- window management
@@ -235,7 +239,8 @@ static HRGN bitmap2region(Fl_Image* image) {
}
-void Fl_WinAPI_Window_Driver::draw() {
+void Fl_WinAPI_Window_Driver::draw_begin()
+{
if (shape_data_) {
if ((shape_data_->lw_ != pWindow->w() || shape_data_->lh_ != pWindow->h()) && shape_data_->shape_) {
// size of window has changed since last time
@@ -246,9 +251,84 @@ void Fl_WinAPI_Window_Driver::draw() {
SetWindowRgn(fl_xid(pWindow), region, TRUE); // the system deletes the region when it's no longer needed
delete temp;
}
- } Fl_Window_Driver::draw();
+ }
+}
+
+
+void Fl_WinAPI_Window_Driver::draw_end()
+{
}
+
+void Fl_WinAPI_Window_Driver::flush_single()
+{
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return;
+ fl_clip_region(i->region);
+ i->region = 0;
+ pWindow->draw();
+}
+
+
+void Fl_WinAPI_Window_Driver::flush_double()
+{
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return; // window not yet created
+
+ if (!i->other_xid) {
+ i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
+ pWindow->clear_damage(FL_DAMAGE_ALL);
+ }
+ if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
+ fl_clip_region(i->region); i->region = 0;
+ fl_begin_offscreen(i->other_xid);
+ fl_graphics_driver->clip_region( 0 );
+ draw();
+ fl_end_offscreen();
+ }
+
+ int X,Y,W,H; fl_clip_box(0,0,pWindow->w(),pWindow->h(),X,Y,W,H);
+ if (i->other_xid) fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
+}
+
+
+void Fl_WinAPI_Window_Driver::flush_overlay()
+{
+ Fl_Overlay_Window *oWindow = pWindow->as_overlay_window();
+ if (!oWindow) return flush_single();
+
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return; // window not yet created
+
+ int eraseoverlay = (pWindow->damage()&FL_DAMAGE_OVERLAY);
+ pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY));
+
+ if (!i->other_xid) {
+ i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
+ pWindow->clear_damage(FL_DAMAGE_ALL);
+ }
+ if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
+ fl_clip_region(i->region); i->region = 0;
+ fl_begin_offscreen(i->other_xid);
+ fl_graphics_driver->clip_region(0);
+ draw();
+ fl_end_offscreen();
+ }
+
+ if (eraseoverlay) fl_clip_region(0);
+ int X, Y, W, H; fl_clip_box(0, 0, pWindow->w(), pWindow->h(), X, Y, W, H);
+ if (i->other_xid) fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
+
+ if (oWindow->overlay_ == oWindow) oWindow->draw_overlay();
+}
+
+
void Fl_WinAPI_Window_Driver::icons(const Fl_RGB_Image *icons[], int count) {
free_icons();
diff --git a/src/drivers/X11/Fl_X11_Window_Driver.H b/src/drivers/X11/Fl_X11_Window_Driver.H
index 02c0de989..126f4b103 100644
--- a/src/drivers/X11/Fl_X11_Window_Driver.H
+++ b/src/drivers/X11/Fl_X11_Window_Driver.H
@@ -75,7 +75,14 @@ public:
virtual int decorated_w();
virtual int decorated_h();
+ // --- window management
virtual void take_focus();
+ virtual void flush_single();
+ virtual void flush_double();
+ virtual void flush_overlay();
+ virtual void draw_begin();
+ virtual void draw_end();
+
virtual void shape(const Fl_Image* img);
virtual void draw();
virtual void icons(const Fl_RGB_Image *icons[], int count);
diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx
index 6ff2158c2..b8ca36480 100644
--- a/src/drivers/X11/Fl_X11_Window_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx
@@ -19,7 +19,9 @@
#include "../../config_lib.h"
#include "Fl_X11_Window_Driver.H"
+
#include <FL/Fl_Shared_Image.H>
+#include <FL/Fl_Overlay_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
#include <string.h>
@@ -32,26 +34,37 @@
#if USE_XDBE
#include <X11/extensions/Xdbe.h>
-static int can_xdbe(); // forward
+// whether the Xdbe extension is usable
+// DO NOT call this if the window is not mapped!
+static int can_xdbe()
+{
+ static int tried = 0;
+ static int use_xdbe = 0;
+ if (!tried) {
+ tried = 1;
+ int event_base, error_base;
+ fl_open_display();
+ 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;
+}
-// 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 // USE_XDBE
Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w)
{
-#if USE_XDBE
- if (w->as_double_window() && can_xdbe())
- return new Fl_X11_Dbe_Window_Driver(w);
- else
-#endif
- return new Fl_X11_Window_Driver(w);
+ return new Fl_X11_Window_Driver(w);
}
@@ -123,63 +136,172 @@ void Fl_X11_Window_Driver::take_focus()
Fl_X::activate_window(i->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;
- fl_open_display();
- 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;
- }
+void Fl_X11_Window_Driver::draw_begin()
+{
+ if (shape_data_) {
+ if (( shape_data_->lw_ != pWindow->w() || shape_data_->lh_ != pWindow->h() ) && shape_data_->shape_) {
+ // size of window has changed since last time
+ combine_mask();
}
- XdbeFreeVisualInfo(a);
}
- return use_xdbe;
}
-int Fl_X11_Dbe_Window_Driver::double_flush(int eraseoverlay) {
+
+void Fl_X11_Window_Driver::draw_end()
+{
+}
+
+
+void Fl_X11_Window_Driver::flush_single()
+{
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
+ Fl_X *i = Fl_X::i(pWindow);
+ if (!i) return;
+ fl_clip_region(i->region);
+ i->region = 0;
+ pWindow->draw();
+}
+
+
+void Fl_X11_Window_Driver::flush_double()
+{
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
Fl_X *i = Fl_X::i(pWindow);
- if (!i->other_xid) {
- i->other_xid = XdbeAllocateBackBufferName(fl_display, i->xid, XdbeCopied);
+ if (!i) return; // window not yet created
+ if (!i->other_xid) {
+#if USE_XDBE
+ if (can_xdbe()) {
+ i->other_xid = XdbeAllocateBackBufferName(fl_display, fl_xid(pWindow), XdbeCopied);
i->backbuffer_bad = 1;
- pWindow->clear_damage(FL_DAMAGE_ALL);
- }
- if (i->backbuffer_bad || eraseoverlay) {
+ } else
+#endif
+ i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
+ pWindow->clear_damage(FL_DAMAGE_ALL);
+ }
+#if USE_XDBE
+ if (can_xdbe()) {
+ if (i->backbuffer_bad) {
// Make sure we do a complete redraw...
if (i->region) {XDestroyRegion(i->region); i->region = 0;}
pWindow->clear_damage(FL_DAMAGE_ALL);
i->backbuffer_bad = 0;
}
+
// Redraw as needed...
if (pWindow->damage()) {
fl_clip_region(i->region); i->region = 0;
fl_window = i->other_xid;
- draw();
+ pWindow->draw();
fl_window = i->xid;
}
+
// Copy contents of back buffer to window...
XdbeSwapInfo s;
- s.swap_window = i->xid;
+ s.swap_window = fl_xid(pWindow);
s.swap_action = XdbeCopied;
XdbeSwapBuffers(fl_display, &s, 1);
- return 1;
+ return;
+ } else
+#endif
+ if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
+ fl_clip_region(i->region); i->region = 0;
+ fl_window = i->other_xid;
+ pWindow->draw();
+ fl_window = i->xid;
+ }
+ int X,Y,W,H; fl_clip_box(0,0,pWindow->w(),pWindow->h(),X,Y,W,H);
+ if (i->other_xid) fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
}
-void Fl_X11_Dbe_Window_Driver::destroy_double_buffer() {
+
+void Fl_X11_Window_Driver::flush_overlay()
+{
+ Fl_Overlay_Window *oWindow = pWindow->as_overlay_window();
+ if (!oWindow) return flush_single();
+
+ if (!pWindow->shown()) return;
+ pWindow->make_current(); // make sure fl_gc is non-zero
Fl_X *i = Fl_X::i(pWindow);
- XdbeDeallocateBackBufferName(fl_display, i->other_xid);
- i->other_xid = 0;
+ if (!i) return; // window not yet created
+
+#ifdef BOXX_BUGS
+ if (oWindow->overlay_ && oWindow->overlay_ != oWindow && oWindow->overlay_->shown()) {
+ // all drawing to windows hidden by overlay windows is ignored, fix this
+ XUnmapWindow(fl_display, fl_xid(oWindow->overlay_));
+ flush_double();
+ XMapWindow(fl_display, fl_xid(oWindow->overlay_));
+ return;
+ }
+#endif
+
+ int erase_overlay = (pWindow->damage()&FL_DAMAGE_OVERLAY);
+ pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY));
+
+ if (!i->other_xid) {
+#if USE_XDBE
+ if (can_xdbe()) {
+ i->other_xid = XdbeAllocateBackBufferName(fl_display, fl_xid(pWindow), XdbeCopied);
+ i->backbuffer_bad = 1;
+ } else
+#endif
+ i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
+ pWindow->clear_damage(FL_DAMAGE_ALL);
+ }
+#if USE_XDBE
+ if (can_xdbe()) {
+ if (i->backbuffer_bad || erase_overlay) {
+ // Make sure we do a complete redraw...
+ if (i->region) {XDestroyRegion(i->region); i->region = 0;}
+ pWindow->clear_damage(FL_DAMAGE_ALL);
+ i->backbuffer_bad = 0;
+ }
+
+ // Redraw as needed...
+ if (pWindow->damage()) {
+ fl_clip_region(i->region); i->region = 0;
+ fl_window = i->other_xid;
+ pWindow->draw();
+ fl_window = i->xid;
+ }
+
+ // Copy contents of back buffer to window...
+ XdbeSwapInfo s;
+ s.swap_window = fl_xid(pWindow);
+ s.swap_action = XdbeCopied;
+ XdbeSwapBuffers(fl_display, &s, 1);
+
+ pWindow->make_current();
+ if (erase_overlay) fl_clip_region(0);
+ if (oWindow->overlay_ == oWindow) oWindow->draw_overlay();
+
+ return;
+ } else
+#endif
+ if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
+ fl_clip_region(i->region); i->region = 0;
+ fl_window = i->other_xid;
+ pWindow->draw();
+ fl_window = i->xid;
+ }
+ if (erase_overlay) fl_clip_region(0);
+ int X,Y,W,H; fl_clip_box(0,0,pWindow->w(),pWindow->h(),X,Y,W,H);
+ if (i->other_xid) fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
+
+ if (oWindow->overlay_ == oWindow) oWindow->draw_overlay();
}
+
+
+
+#if USE_XDBE
+
+//void Fl_X11_Dbe_Window_Driver::destroy_double_buffer() {
+// Fl_X *i = Fl_X::i(pWindow);
+// XdbeDeallocateBackBufferName(fl_display, i->other_xid);
+// i->other_xid = 0;
+//}
#endif // USE_XDBE