diff --git a/FL/Fl_Graphics_Driver.H b/FL/Fl_Graphics_Driver.H index 08ef5694c..51859b5c1 100644 --- a/FL/Fl_Graphics_Driver.H +++ b/FL/Fl_Graphics_Driver.H @@ -114,6 +114,7 @@ protected: public: Fl_Graphics_Driver(); virtual ~Fl_Graphics_Driver() {} + static Fl_Graphics_Driver &default_driver(); virtual char can_do_alpha_blending() { return 0; } // --- implementation is in src/fl_rect.cxx which includes src/drivers/xxx/Fl_xxx_Graphics_Driver_rect.cxx virtual void point(int x, int y) = 0; @@ -245,9 +246,9 @@ public: virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win); virtual void reset_spot(); // each platform implements these 3 functions its own way - static void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); - static Fl_Region XRectangleRegion(int x, int y, int w, int h); - static void XDestroyRegion(Fl_Region r); + virtual void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); + virtual Fl_Region XRectangleRegion(int x, int y, int w, int h); + virtual void XDestroyRegion(Fl_Region r); protected: // --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx diff --git a/src/Fl.cxx b/src/Fl.cxx index 26e7d4080..38b9434b5 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -686,7 +686,10 @@ void Fl::flush() { if (!wi->visible_r()) continue; if (wi->damage()) {i->flush(); wi->clear_damage();} // destroy damage regions for windows that don't use them: - if (i->region) {Fl_Graphics_Driver::XDestroyRegion(i->region); i->region = 0;} + if (i->region) { + fl_graphics_driver->XDestroyRegion(i->region); + i->region = 0; + } } } screen_driver()->flush(); @@ -1491,7 +1494,10 @@ void Fl_Widget::damage(uchar fl) { // damage entire window by deleting the region: Fl_X* i = Fl_X::i((Fl_Window*)this); if (!i) return; // window not mapped, so ignore it - if (i->region) {Fl_Graphics_Driver::XDestroyRegion(i->region); i->region = 0;} + if (i->region) { + fl_graphics_driver->XDestroyRegion(i->region); + i->region = 0; + } damage_ |= fl; Fl::damage(FL_DAMAGE_CHILD); } @@ -1525,13 +1531,13 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) { if (wi->damage()) { // if we already have damage we must merge with existing region: if (i->region) { - Fl_Graphics_Driver::add_rectangle_to_region(i->region, X, Y, W, H); + fl_graphics_driver->add_rectangle_to_region(i->region, X, Y, W, H); } wi->damage_ |= fl; } else { // create a new region: - if (i->region) Fl_Graphics_Driver::XDestroyRegion(i->region); - i->region = Fl_Graphics_Driver::XRectangleRegion(X,Y,W,H); + if (i->region) fl_graphics_driver->XDestroyRegion(i->region); + i->region = fl_graphics_driver->XRectangleRegion(X,Y,W,H); wi->damage_ = fl; } Fl::damage(FL_DAMAGE_CHILD); diff --git a/src/Fl_Graphics_Driver.cxx b/src/Fl_Graphics_Driver.cxx index 72f52427f..510852b5b 100644 --- a/src/Fl_Graphics_Driver.cxx +++ b/src/Fl_Graphics_Driver.cxx @@ -37,6 +37,18 @@ Fl_Graphics_Driver::Fl_Graphics_Driver() { font_descriptor_ = NULL; }; + +Fl_Graphics_Driver &Fl_Graphics_Driver::default_driver() +{ + static Fl_Graphics_Driver *pMainDriver = 0L; + if (!pMainDriver) { + pMainDriver = Fl_Display_Device::display_device()->driver(); + } + return *pMainDriver; +} + + + void Fl_Graphics_Driver::text_extents(const char*t, int n, int& dx, int& dy, int& w, int& h) { w = (int)width(t, n); @@ -100,6 +112,25 @@ void Fl_Graphics_Driver::free_color(Fl_Color i, int overlay) } +void Fl_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h) +{ + // nothing to do, reimplement in driver if needed +} + + +Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) +{ + // nothing to do, reimplement in driver if needed + return 0; +} + + +void Fl_Graphics_Driver::XDestroyRegion(Fl_Region r) +{ + // nothing to do, reimplement in driver if needed +} + + // // End of "$Id$". // diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 6de963cdf..4a205b03a 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -1936,7 +1936,7 @@ static void handleUpdateEvent( Fl_Window *window ) i->wait_for_expose = 0; if ( i->region ) { - Fl_Graphics_Driver::XDestroyRegion(i->region); + Fl_Graphics_Driver::default_driver().XDestroyRegion(i->region); i->region = 0; } window->clear_damage(FL_DAMAGE_ALL); diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx index 2e49d9dd1..a96039918 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx @@ -239,7 +239,7 @@ void Fl_Cocoa_Window_Driver::hide() { q_release_context(this); if ( ip->xid == fl_window ) fl_window = 0; - if (ip->region) Fl_Graphics_Driver::XDestroyRegion(ip->region); + if (ip->region) Fl_Graphics_Driver::default_driver().XDestroyRegion(ip->region); ip->destroy(); delete ip; } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H index fa5b517e3..eec35dea2 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H @@ -78,6 +78,9 @@ public: void copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy); #endif void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); + void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); + Fl_Region XRectangleRegion(int x, int y, int w, int h); + void XDestroyRegion(Fl_Region r); protected: void transformed_vertex0(int x, int y); void fixloop(); diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx index f208b979f..47cc9383c 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx @@ -144,7 +144,7 @@ void Fl_Translated_GDI_Graphics_Driver::untranslate_all() { SetWindowOrgEx((HDC)gc(), origins[depth].x, origins[depth].y, NULL); } -void Fl_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { +void Fl_GDI_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { Fl_Region R = XRectangleRegion(X, Y, W, H); CombineRgn(r, r, R, RGN_OR); XDestroyRegion(R); @@ -166,7 +166,7 @@ void Fl_GDI_Graphics_Driver::fixloop() { // remove equal points from closed pat while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--; } -Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { +Fl_Region Fl_GDI_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) return CreateRectRgn(x,y,x+w,y+h); // because rotation may apply, the rectangle becomes a polygon in device coords POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} }; @@ -174,16 +174,16 @@ Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { return CreatePolygonRgn(pt, 4, ALTERNATE); } -void Fl_Graphics_Driver::XDestroyRegion(Fl_Region r) { +void Fl_GDI_Graphics_Driver::XDestroyRegion(Fl_Region r) { DeleteObject(r); } -void Fl_Graphics_Driver::reset_spot() +void Fl_GDI_Graphics_Driver::reset_spot() { } -void Fl_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) +void Fl_GDI_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) { if (!win) return; Fl_Window* tw = win; diff --git a/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.cxx b/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.cxx index 16e845cd2..6f68f5edc 100644 --- a/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.cxx +++ b/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.cxx @@ -32,12 +32,6 @@ extern Window fl_window; -void Fl_Graphics_Driver::XDestroyRegion(void*) { } -//void Fl_Graphics_Driver::clip_region(void*) { } -Fl_Region Fl_Graphics_Driver::XRectangleRegion(int, int, int, int) { } -void Fl_Graphics_Driver::add_rectangle_to_region(void*, int, int, int, int) { } - - /* * By linking this module, the following static method will instantiate the * PicoSDL Graphics driver as the main display driver. diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H index 30cb8d984..d022ff1df 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H @@ -64,6 +64,9 @@ public: void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); void draw_CGImage(CGImageRef cgimg, int x, int y, int w, int h, int srcx, int srcy, int sw, int sh); static CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h); + void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); + Fl_Region XRectangleRegion(int x, int y, int w, int h); + void XDestroyRegion(Fl_Region r); protected: void transformed_vertex0(float x, float y); void fixloop(); diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx index 90b4d5a8c..8d5cff37b 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx @@ -76,7 +76,7 @@ CGRect Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(int x, int y, int w, int h return CGRectMake(x - 0.5, y - 0.5, w, h); } -void Fl_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { +void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { CGRect arg = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(X, Y, W, H); int j; // don't add a rectangle totally inside the Fl_Region for(j = 0; j < r->count; j++) { @@ -88,7 +88,7 @@ void Fl_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int } } -Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { +Fl_Region Fl_Quartz_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { Fl_Region R = (Fl_Region)malloc(sizeof(*R)); R->count = 1; R->rects = (CGRect *)malloc(sizeof(CGRect)); @@ -96,7 +96,7 @@ Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { return R; } -void Fl_Graphics_Driver::XDestroyRegion(Fl_Region r) { +void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r) { if(r) { free(r->rects); free(r); diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx index be31149f9..d61c7ad7e 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx @@ -202,7 +202,7 @@ void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, in // intersects current and x,y,w,h rectangle and returns result as a new Fl_Region static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, int h) { - if (current == NULL) return Fl_Graphics_Driver::XRectangleRegion(x,y,w,h); + if (current == NULL) return Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h); CGRect r = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); Fl_Region outr = (Fl_Region)malloc(sizeof(*outr)); outr->count = current->count; @@ -217,8 +217,8 @@ static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, outr->rects = (CGRect*)realloc(outr->rects, outr->count * sizeof(CGRect)); } else { - Fl_Graphics_Driver::XDestroyRegion(outr); - outr = Fl_Graphics_Driver::XRectangleRegion(0,0,0,0); + Fl_Graphics_Driver::default_driver().XDestroyRegion(outr); + outr = Fl_Graphics_Driver::default_driver().XRectangleRegion(0,0,0,0); } return outr; } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H index 1e7bd43d8..26f5ff2b9 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H @@ -79,6 +79,9 @@ public: #if ! defined(FL_DOXYGEN) void copy_offscreen_with_alpha(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); #endif + void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); + Fl_Region XRectangleRegion(int x, int y, int w, int h); + void XDestroyRegion(Fl_Region r); protected: void transformed_vertex0(short x, short y); void fixloop(); diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index 2406468d2..2181e43e0 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx @@ -96,7 +96,7 @@ void Fl_Xlib_Graphics_Driver::copy_offscreen_with_alpha(int x, int y, int w, int #endif -void Fl_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { +void Fl_Xlib_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { XRectangle R; R.x = X; R.y = Y; R.width = W; R.height = H; XUnionRectWithRegion(&R, r, r); diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx index a584bf8e6..0df68049b 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx @@ -150,7 +150,7 @@ static int clip_x (int x) { // Missing X call: (is this the fastest way to init a 1-rectangle region?) // MSWindows equivalent exists, implemented inline in win32.H -Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { +Fl_Region Fl_Xlib_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { XRectangle R; clip_to_short(x, y, w, h); R.x = x; R.y = y; R.width = w; R.height = h; @@ -159,7 +159,7 @@ Fl_Region Fl_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { return r; } -void Fl_Graphics_Driver::XDestroyRegion(Fl_Region r) { +void Fl_Xlib_Graphics_Driver::XDestroyRegion(Fl_Region r) { ::XDestroyRegion(r); } diff --git a/src/fl_color.cxx b/src/fl_color.cxx index 3c7dece44..71619d8ff 100644 --- a/src/fl_color.cxx +++ b/src/fl_color.cxx @@ -69,13 +69,13 @@ void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) { void Fl::set_color(Fl_Color i, unsigned int c) { - fl_graphics_driver->set_color(i, c); + Fl_Graphics_Driver::default_driver().set_color(i, c); } void Fl::free_color(Fl_Color i, int overlay) { - fl_graphics_driver->free_color(i, overlay); + Fl_Graphics_Driver::default_driver().free_color(i, overlay); } diff --git a/src/fl_font.cxx b/src/fl_font.cxx index 530030874..ef4743c85 100644 --- a/src/fl_font.cxx +++ b/src/fl_font.cxx @@ -53,12 +53,12 @@ void fl_draw(const char* str, int l, float x, float y) { void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) { - fl_graphics_driver->set_spot(font, size, X, Y, W, H, win); + Fl_Graphics_Driver::default_driver().set_spot(font, size, X, Y, W, H, win); } void fl_reset_spot() { - fl_graphics_driver->reset_spot(); + Fl_Graphics_Driver::default_driver().reset_spot(); } // diff --git a/src/gl_start.cxx b/src/gl_start.cxx index 9eaf36c05..bfb50e3ce 100644 --- a/src/gl_start.cxx +++ b/src/gl_start.cxx @@ -89,7 +89,7 @@ void gl_start() { int x, y, w, h; if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(), x, y, w, h)) { - fl_clip_region(Fl_Graphics_Driver::XRectangleRegion(x,y,w,h)); + fl_clip_region(Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h)); glScissor(x, Fl_Window::current()->h()-(y+h), w, h); glEnable(GL_SCISSOR_TEST); } else {