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 /src/drivers | |
| 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.
Diffstat (limited to 'src/drivers')
| -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 |
10 files changed, 29 insertions, 32 deletions
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; } |
