diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2019-06-06 18:28:49 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2019-06-06 18:28:49 +0200 |
| commit | 94fffb701ce88adf7398fb37a007a04c08f1ca6f (patch) | |
| tree | 39c02278fa18939ebf7d5df8e1459e5297c086ea | |
| parent | 50b1c0878085b5f231616d78f1f1775874b1c9ae (diff) | |
Add one argument to Fl_Screen_Driver::read_win_rectangle()
The new argument gives the window to be captured, or NULL to indicate capture
from the current offscreen.
Calling this function becomes easier because less dependent on global variables.
| -rw-r--r-- | src/Fl_Screen_Driver.H | 4 | ||||
| -rw-r--r-- | src/Fl_Screen_Driver.cxx | 3 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 8 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 6 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H | 4 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 8 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 17 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Window_Driver.cxx | 16 | ||||
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/fl_overlay.cxx | 8 | ||||
| -rw-r--r-- | src/fl_read_image.cxx | 2 |
15 files changed, 42 insertions, 44 deletions
diff --git a/src/Fl_Screen_Driver.H b/src/Fl_Screen_Driver.H index 8ae19a816..511f892d2 100644 --- a/src/Fl_Screen_Driver.H +++ b/src/Fl_Screen_Driver.H @@ -150,8 +150,10 @@ public: 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 Fl_XXX_Window_Driver::capture_titlebar_and_borders(). + + 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) {return NULL;} + virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win) {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 4f4bbff7f..93d0a23ea 100644 --- a/src/Fl_Screen_Driver.cxx +++ b/src/Fl_Screen_Driver.cxx @@ -196,8 +196,7 @@ Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, int x, in full_img = plugin->rectangle_capture(g, x, y, w, h); } else if ( g->as_window() ) { - if (Fl_Window::current() != g) g->as_window()->make_current(); - full_img = Fl::screen_driver()->read_win_rectangle(x, y, w, h); + full_img = Fl::screen_driver()->read_win_rectangle(x, y, w, h, g->as_window()); } if (!full_img) return NULL; float full_img_scale = (full_img && w > 0 ? float(full_img->data_w())/w : 1); diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index bc2cb5d90..d056d71d6 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -2719,14 +2719,14 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image *&top, F // capture the 4 window sides from screen Fl_WinAPI_Screen_Driver *dr = (Fl_WinAPI_Screen_Driver *)Fl::screen_driver(); if (htop) { - top = dr->read_win_rectangle_unscaled(r.left, r.top, r.right - r.left, htop); + top = dr->read_win_rectangle_unscaled(r.left, r.top, r.right - r.left, htop, 0); if (scaling != 1) top->scale(ww, htop / scaling, 0, 1); } if (wsides) { - left = dr->read_win_rectangle_unscaled(r.left, r.top + htop, wsides, h() * scaling); - right = dr->read_win_rectangle_unscaled(r.right - wsides, r.top + htop, wsides, h() * scaling); - bottom = dr->read_win_rectangle_unscaled(r.left, r.bottom - hbottom, ww, hbottom); + left = dr->read_win_rectangle_unscaled(r.left, r.top + htop, wsides, h() * scaling, 0); + right = dr->read_win_rectangle_unscaled(r.right - wsides, r.top + htop, wsides, h() * scaling, 0); + bottom = dr->read_win_rectangle_unscaled(r.left, r.bottom - hbottom, ww, hbottom, 0); if (scaling != 1) { left->scale(wsides, h(), 0, 1); right->scale(wsides, h(), 0, 1); diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H index b472dff8e..2b329367b 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); + virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win); private: float scale_; }; diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index a918d1104..d3ec31fdf 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx @@ -339,11 +339,11 @@ 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_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *window) { int bpp, bpr, depth = 4; uchar *base, *p; - if (!fl_window) { // read from offscreen buffer + if (!window) { // read from offscreen buffer float s = 1; CGContextRef src = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc(); // get bitmap context base = (uchar *)CGBitmapContextGetData(src); // get data @@ -373,7 +373,7 @@ 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(Fl_Window::current()); + Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(window); CGImageRef cgimg = d->CGImage_from_window_rect(X, Y, w, h, false); if (!cgimg) { return NULL; diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx index 5c03621cb..9308936d3 100644 --- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx @@ -89,7 +89,7 @@ void Fl_GDI_Image_Surface_Driver::untranslate() { Fl_RGB_Image* Fl_GDI_Image_Surface_Driver::image() { - Fl_RGB_Image *image = Fl::screen_driver()->read_win_rectangle( 0, 0, width, height); + Fl_RGB_Image *image = Fl::screen_driver()->read_win_rectangle( 0, 0, width, height, 0); return image; } diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H index 16bf3ebdf..605f3bffd 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H @@ -75,8 +75,8 @@ 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_RGB_Image *read_win_rectangle_unscaled(int X, int Y, int w, int h); + virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win); + 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(); virtual void disable_im(); diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx index 147933446..f390a4f50 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx @@ -501,7 +501,8 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle( int X, // I - Left position int Y, // I - Top position int w, // I - Width of area to read - int h) // I - Height 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 { float s = Fl_Surface_Device::surface()->driver()->scale(); int ws, hs; @@ -512,10 +513,10 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle( if (ws < 1) ws = 1; if (hs < 1) hs = 1; } - return read_win_rectangle_unscaled(X*s, Y*s, ws, hs); + return read_win_rectangle_unscaled(X*s, Y*s, ws, hs, win); } -Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, int w, int h) +Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, int w, int h, Fl_Window *win) { int d = 3; // Depth of image int alpha = 0; uchar *p = NULL; @@ -569,6 +570,7 @@ Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, bi.bmiHeader.biClrImportant = 0; // copy bitmap from original DC (Window, Fl_Offscreen, ...) + if (win && Fl_Window::current() != win) win->make_current(); HDC gc = (HDC)fl_graphics_driver->gc(); HDC hdc = CreateCompatibleDC(gc); HBITMAP hbm = CreateCompatibleBitmap(gc,w,h); diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H index b348dfc3e..7b14d4375 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); + virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win); 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 43482bb1a..ed703f78d 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_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win) { XImage *image; // Captured image int i, maxindex; // Looping vars @@ -772,12 +772,14 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int int allow_outside = w < 0; // negative w allows negative X or Y, that is, window frame if (w < 0) w = - w; - float s = allow_outside ? Fl::screen_driver()->scale(Fl_Window::current()->screen_num()) : Fl_Surface_Device::surface()->driver()->scale(); + Window xid = (win && !allow_outside ? fl_xid(win) : fl_window); + + float s = allow_outside ? Fl::screen_driver()->scale(win->screen_num()) : Fl_Surface_Device::surface()->driver()->scale(); int ws = w * s, hs = h * s, Xs = X*s, Ys = Y*s; # ifdef __sgi if (XReadDisplayQueryExtension(fl_display, &i, &i)) { - image = XReadDisplay(fl_display, fl_window, Xs, Ys, ws, hs, 0, NULL); + image = XReadDisplay(fl_display, xid, Xs, Ys, ws, hs, 0, NULL); } else # else image = 0; @@ -788,11 +790,8 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int int dx, dy, sx, sy, sw, sh; Window child_win; - Fl_Window *win; - if (allow_outside) win = Fl_Window::current(); - else win = fl_find(fl_window); if (win) { - XTranslateCoordinates(fl_display, fl_window, + XTranslateCoordinates(fl_display, xid, RootWindow(fl_display, fl_screen), Xs, Ys, &dx, &dy, &child_win); // screen dimensions Fl::screen_xywh(sx, sy, sw, sh, Fl_Window_Driver::driver(win)->screen_num()); @@ -811,7 +810,7 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int // however, if the window is obscured etc. the function will still fail. Make sure we // catch the error and continue, otherwise an exception will be thrown. XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler); - image = XGetImage(fl_display, fl_window, Xs, Ys, ws, hs, AllPlanes, ZPixmap); + image = XGetImage(fl_display, xid, Xs, Ys, ws, hs, AllPlanes, ZPixmap); XSetErrorHandler(old_handler); } else { // image is crossing borders, determine visible region @@ -831,7 +830,7 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int } XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler); - XImage *subimg = XGetSubImage(fl_display, fl_window, Xs + noffx, Ys + noffy, + XImage *subimg = XGetSubImage(fl_display, xid, Xs + noffx, Ys + noffy, nw, nh, AllPlanes, ZPixmap, image, noffx, noffy); XSetErrorHandler(old_handler); if (!subimg) { diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx index e2ed5d073..1de2e5297 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx @@ -392,16 +392,14 @@ void Fl_X11_Window_Driver::free_icons() { This function exploits a feature of Fl_X11_Screen_Driver::read_win_rectangle() which, when called with negative 3rd argument, captures the window decoration. - Other requirements to capture the window decoration: - - fl_window is the parent window of the top window - - Fl_Window::current() is the top window + Other requirement to capture the window decoration: + fl_window is the parent window of the top window */ void Fl_X11_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) { top = left = bottom = right = NULL; if (pWindow->decorated_h() == h()) return; Window from = fl_window; - Fl_Window *oldcurrent = Fl_Window::current(); Window root, parent, *children, child_win, xid = fl_xid(pWindow); unsigned n = 0; int do_it; @@ -414,25 +412,23 @@ void Fl_X11_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_R float s = Fl::screen_driver()->scale(screen_num()); htop /= s; wsides /= s; fl_window = parent; - current(pWindow); if (htop) { - top = Fl::screen_driver()->read_win_rectangle(0, 0, - (w() + 2 * wsides), htop); + top = Fl::screen_driver()->read_win_rectangle(0, 0, - (w() + 2 * wsides), htop, pWindow); if (top) top->scale(w() + 2 * wsides, htop, 0, 1); } if (wsides) { - left = Fl::screen_driver()->read_win_rectangle(0, htop, -wsides, h()); + left = Fl::screen_driver()->read_win_rectangle(0, htop, -wsides, h(), pWindow); if (left) { left->scale(wsides, h(), 0, 1); } - right = Fl::screen_driver()->read_win_rectangle(w() + wsides, htop, -wsides, h()); + right = Fl::screen_driver()->read_win_rectangle(w() + wsides, htop, -wsides, h(), pWindow); if (right) { right->scale(wsides, h(), 0, 1); } - bottom = Fl::screen_driver()->read_win_rectangle(0, htop + h(), -(w() + 2*wsides), hbottom); + bottom = Fl::screen_driver()->read_win_rectangle(0, htop + h(), -(w() + 2*wsides), hbottom, pWindow); if (bottom) { bottom->scale(w() + 2*wsides, wsides, 0, 1); } } - current(oldcurrent); fl_window = from; } diff --git a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx index 5818eb2a5..4e9466952 100644 --- a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx @@ -64,7 +64,7 @@ Fl_Xlib_Copy_Surface_Driver::~Fl_Xlib_Copy_Surface_Driver() { driver()->pop_clip(); bool need_push = !is_current(); if (need_push) Fl_Surface_Device::push_current(this); - Fl_RGB_Image *rgb = Fl::screen_driver()->read_win_rectangle(0, 0, width, height); + Fl_RGB_Image *rgb = Fl::screen_driver()->read_win_rectangle(0, 0, width, height, 0); if (need_push) Fl_Surface_Device::pop_current(); Fl_X11_Screen_Driver::copy_image(rgb->array, rgb->w(), rgb->h(), 1); delete rgb; diff --git a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx index 1a9e7796d..54b246955 100644 --- a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx @@ -74,7 +74,7 @@ void Fl_Xlib_Image_Surface_Driver::untranslate() { Fl_RGB_Image* Fl_Xlib_Image_Surface_Driver::image() { - Fl_RGB_Image *image = Fl::screen_driver()->read_win_rectangle(0, 0, width, height); + Fl_RGB_Image *image = Fl::screen_driver()->read_win_rectangle(0, 0, width, height, 0); return image; } diff --git a/src/fl_overlay.cxx b/src/fl_overlay.cxx index 6adfce286..5ba1be467 100644 --- a/src/fl_overlay.cxx +++ b/src/fl_overlay.cxx @@ -68,19 +68,19 @@ static void draw_current_rect() { if (s_bgE) { delete s_bgE; s_bgE = 0; } if (s_bgW) { delete s_bgW; s_bgW = 0; } if (pw>0 && ph>0) { - s_bgE = Fl::screen_driver()->read_win_rectangle( px+pw-1, py, 1, ph); + s_bgE = Fl::screen_driver()->read_win_rectangle( px+pw-1, py, 1, ph, Fl_Window::current()); if(s_bgE && s_bgE->w() && s_bgE->h()) { s_bgE->scale(1, ph,0,1); } - s_bgW = Fl::screen_driver()->read_win_rectangle( px, py, 1, ph); + s_bgW = Fl::screen_driver()->read_win_rectangle( px, py, 1, ph, Fl_Window::current()); if(s_bgW && s_bgW->w() && s_bgW->h()) { s_bgW->scale(1, ph,0,1); } - s_bgS = Fl::screen_driver()->read_win_rectangle( px, py+ph-1, pw, 1); + s_bgS = Fl::screen_driver()->read_win_rectangle( px, py+ph-1, pw, 1, Fl_Window::current()); if(s_bgS && s_bgS->w() && s_bgS->h()) { s_bgS->scale(pw, 1,0,1); } - s_bgN = Fl::screen_driver()->read_win_rectangle( px, py, pw, 1); + s_bgN = Fl::screen_driver()->read_win_rectangle( px, py, pw, 1, Fl_Window::current()); if(s_bgN && s_bgN->w() && s_bgN->h()) { s_bgN->scale(pw, 1,0,1); } diff --git a/src/fl_read_image.cxx b/src/fl_read_image.cxx index 8ce43871b..92f117a8f 100644 --- a/src/fl_read_image.cxx +++ b/src/fl_read_image.cxx @@ -43,7 +43,7 @@ uchar *fl_read_image(uchar *p, int X, int Y, int w, int h, int alpha) { uchar *image_data = NULL; Fl_RGB_Image *img; if (fl_find(fl_window) == 0) { // read from off_screen buffer - img = Fl::screen_driver()->read_win_rectangle(X, Y, w, h); + img = Fl::screen_driver()->read_win_rectangle(X, Y, w, h, 0); if (!img) { return NULL; } |
