diff --git a/FL/Fl_Window.H b/FL/Fl_Window.H index 2888b85fc..e1b0ee479 100644 --- a/FL/Fl_Window.H +++ b/FL/Fl_Window.H @@ -580,8 +580,6 @@ public: */ int decorated_h(); - // Captures the titlebar and borders of the window, if they exist. - void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right); Fl_Window_Driver *driver() { return pWindowDriver; } /** diff --git a/FL/Fl_Window_Driver.H b/FL/Fl_Window_Driver.H index d36774535..629d7ad86 100644 --- a/FL/Fl_Window_Driver.H +++ b/FL/Fl_Window_Driver.H @@ -30,7 +30,7 @@ class Fl_Window; class Fl_X; class Fl_Image; - +class Fl_Shared_Image; /** \brief A base class for platform specific window handling code. @@ -63,6 +63,7 @@ public: virtual const void *icon() const {return NULL;} virtual void icon(const void * ic) {} virtual void free_icons() {} + virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right); }; diff --git a/src/Fl_Widget_Surface.cxx b/src/Fl_Widget_Surface.cxx index 8f792565f..e7c783dc5 100644 --- a/src/Fl_Widget_Surface.cxx +++ b/src/Fl_Widget_Surface.cxx @@ -20,6 +20,7 @@ #include #include #include +#include /** The constructor. @@ -193,7 +194,7 @@ int Fl_Widget_Surface::printable_rect(int *w, int *h) {return 1;} void Fl_Widget_Surface::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset) { Fl_Shared_Image *top, *left, *bottom, *right; - win->capture_titlebar_and_borders(top, left, bottom, right); + win->driver()->capture_titlebar_and_borders(top, left, bottom, right); int wsides = left ? left->w() : 0; int toph = top ? top->h() : 0; if (top) { diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx index 7c2131341..53b300817 100644 --- a/src/Fl_Window.cxx +++ b/src/Fl_Window.cxx @@ -433,15 +433,6 @@ void Fl_Window::wait_for_expose() { } } -#if defined(FL_PORTING) -# pragma message "FL_PORTING: implement Fl_Window::capture_titlebar_and_borders" -void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) -{ - top = left = bottom = right = NULL; -} -#endif - - #endif // ! __APPLE__ // PORTME: Fl_Window_Driver - platform window driver // diff --git a/src/Fl_Window_Driver.cxx b/src/Fl_Window_Driver.cxx index de8760f90..de121107a 100644 --- a/src/Fl_Window_Driver.cxx +++ b/src/Fl_Window_Driver.cxx @@ -156,8 +156,9 @@ void Fl_Window_Driver::shape_pixmap_(Fl_Image* pixmap) { delete rgba; } - - +void Fl_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) { + top = left = bottom = right = NULL; +} // // End of "$Id$". diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 256569a04..f4c57659e 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -41,8 +41,9 @@ extern "C" { #include #include #include -#include "drivers/Quartz/Fl_Quartz_Graphics_Driver.h" -#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.h" +#include "drivers/Quartz/Fl_Quartz_Graphics_Driver.H" +#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H" +#include "drivers/Cocoa/Fl_Cocoa_Window_Driver.H" #include #include #include @@ -4338,30 +4339,30 @@ static void draw_layer_to_context(CALayer *layer, CGContextRef gc, int w, int h) /* Returns images of the capture of the window title-bar. On the Mac OS platform, left, bottom and right are returned NULL; top is returned with depth 4. */ -void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) +void Fl_Cocoa_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) { left = bottom = right = NULL; - int htop = decorated_h() - h(); - CALayer *layer = get_titlebar_layer(this); + int htop = pWindow->decorated_h() - pWindow->h(); + CALayer *layer = get_titlebar_layer(pWindow); CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB(); - uchar *rgba = new uchar[4 * w() * htop * 4]; - CGContextRef auxgc = CGBitmapContextCreate(rgba, 2 * w(), 2 * htop, 8, 8 * w(), cspace, kCGImageAlphaPremultipliedLast); + uchar *rgba = new uchar[4 * pWindow->w() * htop * 4]; + CGContextRef auxgc = CGBitmapContextCreate(rgba, 2 * pWindow->w(), 2 * htop, 8, 8 * pWindow->w(), cspace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(cspace); CGContextScaleCTM(auxgc, 2, 2); if (layer) { - draw_layer_to_context(layer, auxgc, w(), htop); + draw_layer_to_context(layer, auxgc, pWindow->w(), htop); } else { - CGImageRef img = Fl_X::CGImage_from_window_rect(this, 0, -htop, w(), htop); + CGImageRef img = Fl_X::CGImage_from_window_rect(pWindow, 0, -htop, pWindow->w(), htop); CGContextSaveGState(auxgc); - Fl_X::clip_to_rounded_corners(auxgc, w(), htop); - CGContextDrawImage(auxgc, CGRectMake(0, 0, w(), htop), img); + Fl_X::clip_to_rounded_corners(auxgc, pWindow->w(), htop); + CGContextDrawImage(auxgc, CGRectMake(0, 0, pWindow->w(), htop), img); CGContextRestoreGState(auxgc); CFRelease(img); } - Fl_RGB_Image *top_rgb = new Fl_RGB_Image(rgba, 2 * w(), 2 * htop, 4); + Fl_RGB_Image *top_rgb = new Fl_RGB_Image(rgba, 2 * pWindow->w(), 2 * htop, 4); top_rgb->alloc_array = 1; top = Fl_Shared_Image::get(top_rgb); - top->scale(w(),htop); + top->scale(pWindow->w(),htop); CGContextRelease(auxgc); } @@ -4413,7 +4414,7 @@ void Fl_System_Printer::draw_decorated_window(Fl_Window *win, int x_offset, int Fl::check(); // capture the window title bar with no title Fl_Shared_Image *top, *left, *bottom, *right; - win->capture_titlebar_and_borders(top, left, bottom, right); + win->driver()->capture_titlebar_and_borders(top, left, bottom, right); win->label(title); // put back the window title this->set_current(); // back to the Fl_Paged_Device top->draw(x_offset, y_offset); // print the title bar diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 1c2548782..c15717b0f 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -2556,22 +2556,22 @@ int Fl_Window::decorated_h() On the WIN32 platform, this function exploits a feature of fl_read_image() which, when called with NULL first argument and when fl_gc is set to the screen device context, captures the window decoration. */ -void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) +void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) { Fl_RGB_Image *r_top, *r_left, *r_bottom, *r_right; top = left = bottom = right = NULL; - if (!shown() || parent() || !border() || !visible()) return; + if (!pWindow->shown() || pWindow->parent() || !pWindow->border() || !pWindow->visible()) return; int wsides, hbottom, bt; - RECT r = border_width_title_bar_height(this, wsides, hbottom, bt); + RECT r = border_width_title_bar_height(pWindow, wsides, hbottom, bt); int htop = bt + hbottom; Fl_Surface_Device *previous = Fl_Surface_Device::surface(); Window save_win = fl_window; Fl_Display_Device::display_device()->set_current(); - show(); + pWindow->show(); Fl::check(); void* save_gc = fl_graphics_driver->gc(); fl_graphics_driver->gc(GetDC(NULL)); - int ww = w() + 2 * wsides; + int ww = pWindow->w() + 2 * wsides; // capture the 4 window sides from screen fl_window = NULL; // force use of read_win_rectangle() by fl_read_image() uchar *rgb; @@ -2582,12 +2582,12 @@ void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Im top = Fl_Shared_Image::get(r_top); } if (wsides) { - rgb = fl_read_image(NULL, r.left, r.top + htop, wsides, h()); - r_left = new Fl_RGB_Image(rgb, wsides, h(), 3); + rgb = fl_read_image(NULL, r.left, r.top + htop, wsides, pWindow->h()); + r_left = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3); r_left->alloc_array = 1; left = Fl_Shared_Image::get(r_left); - rgb = fl_read_image(NULL, r.right - wsides, r.top + htop, wsides, h()); - r_right = new Fl_RGB_Image(rgb, wsides, h(), 3); + rgb = fl_read_image(NULL, r.right - wsides, r.top + htop, wsides, pWindow->h()); + r_right = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3); r_right->alloc_array = 1; right = Fl_Shared_Image::get(r_right); rgb = fl_read_image(NULL, r.left, r.bottom-hbottom, ww, hbottom); diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index f2092296b..b0469c36b 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -2983,60 +2983,6 @@ int Fl_Window::decorated_w() return w; } -/* Returns images of the captures of the window title-bar, and the left, bottom and right window borders - (or NULL if a particular border is absent). - Returned images can be deleted after use. Their depth and size may be platform-dependent. - The top and bottom images extend from left of the left border to right of the right border. - - On the X11 platform, this function exploits a feature of fl_read_image() which, when called - with negative 4th argument, captures the window decoration. - */ -void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) -{ - Fl_RGB_Image *r_top, *r_left, *r_bottom, *r_right; - top = left = bottom = right = NULL; - if (decorated_h() == h()) return; - Window from = fl_window; - Fl_Surface_Device *previous = Fl_Surface_Device::surface(); - Fl_Display_Device::display_device()->set_current(); - show(); - Fl::check(); - make_current(); - Window root, parent, *children, child_win; - unsigned n = 0; - int do_it; - int wsides, htop; - do_it = (XQueryTree(fl_display, fl_window, &root, &parent, &children, &n) != 0 && - XTranslateCoordinates(fl_display, fl_window, parent, 0, 0, &wsides, &htop, &child_win) == True); - if (n) XFree(children); - if (!do_it) wsides = htop = 0; - int hbottom = wsides; - fl_window = parent; - uchar *rgb; - if (htop) { - rgb = fl_read_image(NULL, 0, 0, - (w() + 2 * wsides), htop); - r_top = new Fl_RGB_Image(rgb, w() + 2 * wsides, htop, 3); - r_top->alloc_array = 1; - top = Fl_Shared_Image::get(r_top); - } - if (wsides) { - rgb = fl_read_image(NULL, 0, htop, -wsides, h()); - r_left = new Fl_RGB_Image(rgb, wsides, h(), 3); - r_left->alloc_array = 1; - left = Fl_Shared_Image::get(r_left); - rgb = fl_read_image(NULL, w() + wsides, htop, -wsides, h()); - r_right = new Fl_RGB_Image(rgb, wsides, h(), 3); - r_right->alloc_array = 1; - right = Fl_Shared_Image::get(r_right); - rgb = fl_read_image(NULL, 0, htop + h(), -(w() + 2*wsides), hbottom); - r_bottom = new Fl_RGB_Image(rgb, w() + 2*wsides, hbottom, 3); - r_bottom->alloc_array = 1; - bottom = Fl_Shared_Image::get(r_bottom); - } - fl_window = from; - previous->Fl_Surface_Device::set_current(); -} - #ifdef USE_PRINT_BUTTON // to test the Fl_Printer class creating a "Print front window" button in a separate window // contains also preparePrintFront call above diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H index d8a34fc1b..36be7ee7d 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H +++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H @@ -63,6 +63,8 @@ public: virtual void take_focus(); virtual void shape(const Fl_Image* img); virtual void draw(); + // that one is implemented in Fl_Cocoa.mm because it uses Objective-c + virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right); }; diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H index 605a0547c..53c00cad4 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H @@ -73,6 +73,8 @@ public: virtual void icon(const void * ic); virtual void free_icons(); void icons(HICON big_icon, HICON small_icon); + // this one is implemented in Fl_win32.cxx + virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right); }; diff --git a/src/drivers/X11/Fl_X11_Window_Driver.H b/src/drivers/X11/Fl_X11_Window_Driver.H index e4f8862bd..1eb161e0b 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.H +++ b/src/drivers/X11/Fl_X11_Window_Driver.H @@ -73,6 +73,7 @@ public: virtual const void *icon() const; virtual void icon(const void * ic); virtual void free_icons(); + virtual void capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right); }; diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx index d1f377793..32ac787a2 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 #include +#include #include #if HAVE_DLFCN_H #include @@ -275,6 +277,60 @@ void Fl_X11_Window_Driver::free_icons() { } +/* Returns images of the captures of the window title-bar, and the left, bottom and right window borders + (or NULL if a particular border is absent). + Returned images can be deleted after use. Their depth and size may be platform-dependent. + The top and bottom images extend from left of the left border to right of the right border. + + On the X11 platform, this function exploits a feature of fl_read_image() which, when called + with negative 4th argument, captures the window decoration. + */ +void Fl_X11_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Image*& left, Fl_Shared_Image*& bottom, Fl_Shared_Image*& right) +{ + Fl_RGB_Image *r_top, *r_left, *r_bottom, *r_right; + top = left = bottom = right = NULL; + if (pWindow->decorated_h() == pWindow->h()) return; + Window from = fl_window; + Fl_Surface_Device *previous = Fl_Surface_Device::surface(); + Fl_Display_Device::display_device()->set_current(); + pWindow->show(); + Fl::check(); + pWindow->make_current(); + Window root, parent, *children, child_win; + unsigned n = 0; + int do_it; + int wsides, htop; + do_it = (XQueryTree(fl_display, fl_window, &root, &parent, &children, &n) != 0 && + XTranslateCoordinates(fl_display, fl_window, parent, 0, 0, &wsides, &htop, &child_win) == True); + if (n) XFree(children); + if (!do_it) wsides = htop = 0; + int hbottom = wsides; + fl_window = parent; + uchar *rgb; + if (htop) { + rgb = fl_read_image(NULL, 0, 0, - (pWindow->w() + 2 * wsides), htop); + r_top = new Fl_RGB_Image(rgb, pWindow->w() + 2 * wsides, htop, 3); + r_top->alloc_array = 1; + top = Fl_Shared_Image::get(r_top); + } + if (wsides) { + rgb = fl_read_image(NULL, 0, htop, -wsides, pWindow->h()); + r_left = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3); + r_left->alloc_array = 1; + left = Fl_Shared_Image::get(r_left); + rgb = fl_read_image(NULL, pWindow->w() + wsides, htop, -wsides, pWindow->h()); + r_right = new Fl_RGB_Image(rgb, wsides, pWindow->h(), 3); + r_right->alloc_array = 1; + right = Fl_Shared_Image::get(r_right); + rgb = fl_read_image(NULL, 0, htop + pWindow->h(), -(pWindow->w() + 2*wsides), hbottom); + r_bottom = new Fl_RGB_Image(rgb, pWindow->w() + 2*wsides, hbottom, 3); + r_bottom->alloc_array = 1; + bottom = Fl_Shared_Image::get(r_bottom); + } + fl_window = from; + previous->Fl_Surface_Device::set_current(); +} + // // End of "$Id$". //