diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2016-03-13 22:16:37 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2016-03-13 22:16:37 +0000 |
| commit | b496d18b85917106c48e8e6f74115b3122b603d1 (patch) | |
| tree | 4d96befa4377a81c89c6a32f4d66220199572938 /src/drivers/Cocoa | |
| parent | 30756ae3500a62bd8f63b4df3eb3ca8f6b8b0b70 (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/drivers/Cocoa')
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H | 9 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx | 120 |
2 files changed, 114 insertions, 15 deletions
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; } |
