summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Fl_Screen_Driver.H22
-rw-r--r--src/Fl_Screen_Driver.cxx5
-rw-r--r--src/Fl_cocoa.mm8
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H2
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx6
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H2
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx3
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.H2
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx2
9 files changed, 30 insertions, 22 deletions
diff --git a/src/Fl_Screen_Driver.H b/src/Fl_Screen_Driver.H
index 511f892d2..05924812c 100644
--- a/src/Fl_Screen_Driver.H
+++ b/src/Fl_Screen_Driver.H
@@ -136,16 +136,17 @@ public:
// we no longer need the on-screen keyboard; it's up to the system to hide it
virtual void release_keyboard() { }
- // read raw image from a window or an offscreen buffer
- /* Member function read_win_rectangle() supports the public function
- fl_read_image() which captures pixel data either from
- the current window or from an offscreen buffer.
-
- With fl_read_image() and for capture from a window, the returned pixel array
- also contains data from any embedded sub-window.
+ /* Member function read_win_rectangle() supports public functions
+ fl_read_image() and fl_capture_window_part() which capture pixel data from
+ a window (or also from an offscreen buffer with fl_read_image).
- In the case of read_win_rectangle() and for capture from a window, only data
- from the current window is collected.
+ If 'may_capture_subwins' is true, an implementation may or may not capture
+ also the content of subwindows embedded in 'win'. If subwindows were captured,
+ *'did_capture_subwins' is returned set to true. If read_win_rectangle()
+ is called with 'may_capture_subwins' set to true, 'did_capture_subwins' should
+ be set before the call to the address of a boolean set to false.
+ The implementation of this virtual function for the macOS platform has the
+ capability of capturing subwindows when asked for.
A platform may also use its read_win_rectangle() implementation to capture
window decorations (e.g., title bar). In that case, it is called by
@@ -153,7 +154,8 @@ public:
win is the window to capture from, or NULL to capture from the current offscreen
*/
- virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win) {return NULL;}
+ virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win,
+ bool may_capture_subwins = false, bool *did_capture_subwins = NULL) {return NULL;}
static void write_image_inside(Fl_RGB_Image *to, Fl_RGB_Image *from, int to_x, int to_y);
static Fl_RGB_Image *traverse_to_gl_subwindows(Fl_Group *g, int x, int y, int w, int h,
Fl_RGB_Image *full_img);
diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx
index cc54d53cb..c18cd40d3 100644
--- a/src/Fl_Screen_Driver.cxx
+++ b/src/Fl_Screen_Driver.cxx
@@ -190,17 +190,18 @@ Image depths can differ between "to" and "from".
Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, int x, int y, int w, int h,
Fl_RGB_Image *full_img)
{
+ bool captured_subwin = false;
if ( g->as_gl_window() ) {
Fl_Device_Plugin *plugin = Fl_Device_Plugin::opengl_plugin();
if (!plugin) return full_img;
full_img = plugin->rectangle_capture(g, x, y, w, h);
}
else if ( g->as_window() ) {
- full_img = Fl::screen_driver()->read_win_rectangle(x, y, w, h, g->as_window());
+ full_img = Fl::screen_driver()->read_win_rectangle(x, y, w, h, g->as_window(), true, &captured_subwin);
}
if (!full_img) return NULL;
float full_img_scale = (full_img && w > 0 ? float(full_img->data_w())/w : 1);
- int n = g->children();
+ int n = (captured_subwin ? 0 : g->children());
for (int i = 0; i < n; i++) {
Fl_Widget *c = g->child(i);
if ( !c->visible() || !c->as_group()) continue;
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index c99d73aab..226d093e3 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -4255,13 +4255,13 @@ static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y,
#endif
}
}
- if (!bitmap) return nil;
+ if (!capture_subwins || !bitmap) return bitmap;
// capture also subwindows
NSArray *children = [fl_xid(win) childWindows]; // 10.2
NSEnumerator *enumerator = [children objectEnumerator];
id child;
- while (capture_subwins && ((child = [enumerator nextObject]) != nil)) {
+ while ((child = [enumerator nextObject]) != nil) {
if (![child isKindOfClass:[FLWindow class]]) continue;
Fl_Window *sub = [(FLWindow*)child getFl_Window];
CGRect rsub = CGRectMake(sub->x(), win->h() -(sub->y()+sub->h()), sub->w(), sub->h());
@@ -4272,7 +4272,9 @@ static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y,
win->h() - clip.origin.y - sub->y() - clip.size.height, clip.size.width, clip.size.height);
if (childbitmap) {
// if bitmap is high res and childbitmap is not, childbitmap must be rescaled
- if ([bitmap pixelsWide] > w && [childbitmap pixelsWide] == clip.size.width) childbitmap = scale_nsbitmapimagerep(childbitmap, 2);
+ if (!win->as_gl_window() && Fl_Cocoa_Window_Driver::driver(win)->mapped_to_retina() && sub->as_gl_window() && !Fl::use_high_res_GL()) {
+ childbitmap = scale_nsbitmapimagerep(childbitmap, 2);
+ }
write_bitmap_inside(bitmap, w*s, childbitmap,
(clip.origin.x - x)*s, (win->h() - clip.origin.y - clip.size.height - y)*s );
}
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
index 2b329367b..faf5b8520 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
@@ -99,7 +99,7 @@ public:
virtual APP_SCALING_CAPABILITY rescalable() { return SYSTEMWIDE_APP_SCALING; }
virtual float scale(int n) {return scale_;}
virtual void scale(int n, float f) { scale_ = f;}
- virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win);
+ virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins);
private:
float scale_;
};
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
index d3ec31fdf..34e1c80fd 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
@@ -339,7 +339,8 @@ void Fl_Cocoa_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &h
height = CGBitmapContextGetHeight(off);
}
-Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *window)
+Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *window,
+ bool may_capture_subwins, bool *did_capture_subwins)
{
int bpp, bpr, depth = 4;
uchar *base, *p;
@@ -374,7 +375,8 @@ Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, in
bpr = 0;
} else { // read from window
Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(window);
- CGImageRef cgimg = d->CGImage_from_window_rect(X, Y, w, h, false);
+ CGImageRef cgimg = d->CGImage_from_window_rect(X, Y, w, h, may_capture_subwins);
+ if (did_capture_subwins) *did_capture_subwins = may_capture_subwins;
if (!cgimg) {
return NULL;
}
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
index 09beb1108..11a923331 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
@@ -75,7 +75,7 @@ public:
virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp);
virtual int dnd(int unused);
virtual int compose(int &del);
- virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win);
+ virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins);
Fl_RGB_Image *read_win_rectangle_unscaled(int X, int Y, int w, int h, Fl_Window *win);
virtual int get_mouse(int &x, int &y);
virtual void enable_im();
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
index 5eff35d9d..edbfba577 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
@@ -488,7 +488,8 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(
int Y, // I - Top position
int w, // I - Width of area to read
int h, // I - Height of area to read
- Fl_Window *win) // I - window to capture from or NULL to capture from current offscreen
+ Fl_Window *win, // I - window to capture from or NULL to capture from current offscreen
+ bool may_capture_subwins, bool *did_capture_subwins)
{
float s = Fl_Surface_Device::surface()->driver()->scale();
int ws, hs;
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H
index 7b14d4375..09b043c71 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.H
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.H
@@ -95,7 +95,7 @@ public:
virtual int compose(int &del);
virtual void compose_reset();
virtual int text_display_can_leak();
- virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win);
+ virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins);
virtual int get_mouse(int &x, int &y);
virtual void enable_im();
virtual void disable_im();
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
index ed703f78d..d13562ea9 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -745,7 +745,7 @@ extern "C" {
}
}
-Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win)
+Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins)
{
XImage *image; // Captured image
int i, maxindex; // Looping vars