From 0267781cec8c0bb59689c8b1bad59f98fd3283f9 Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Tue, 23 Aug 2016 09:38:46 +0000 Subject: Change return type of Fl_Screen_Driver::read_win_rectangle() to Fl_RGB_Image* git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11884 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- FL/Fl_Screen_Driver.H | 2 +- src/Fl_Screen_Driver.cxx | 21 ++++++++++++------- src/Fl_win32.cxx | 16 ++++---------- src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H | 2 +- src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 10 ++++++--- src/drivers/X11/Fl_X11_Screen_Driver.H | 2 +- src/drivers/X11/Fl_X11_Screen_Driver.cxx | 7 +++++-- src/drivers/X11/Fl_X11_Window_Driver.cxx | 29 ++++++++++++-------------- 8 files changed, 46 insertions(+), 43 deletions(-) diff --git a/FL/Fl_Screen_Driver.H b/FL/Fl_Screen_Driver.H index 8e041b25f..853798dac 100644 --- a/FL/Fl_Screen_Driver.H +++ b/FL/Fl_Screen_Driver.H @@ -129,7 +129,7 @@ public: # pragma message "FL_PORTING: implement code to read RGB data from screen" #endif virtual uchar *read_image(uchar *p, int x, int y, int w, int h, int alpha); - virtual uchar *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha) {return NULL;} + virtual Fl_RGB_Image *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha) {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, uchar *p, int x, int y, int w, int h, int alpha, Fl_RGB_Image *full_img); diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx index 54da28ef9..c331ed525 100644 --- a/src/Fl_Screen_Driver.cxx +++ b/src/Fl_Screen_Driver.cxx @@ -154,12 +154,21 @@ void Fl_Screen_Driver::compose_reset() { } uchar *Fl_Screen_Driver::read_image(uchar *p, int X, int Y, int w, int h, int alpha) { + uchar *image_data; + Fl_RGB_Image *img; if (fl_find(fl_window) == 0) { // read from off_screen buffer - return read_win_rectangle(p, X, Y, w, h, alpha); + img = read_win_rectangle(p, X, Y, w, h, alpha); + img->alloc_array = 1; + } else { + img = traverse_to_gl_subwindows(Fl_Window::current(), p, X, Y, w, h, alpha, NULL); + } + if (img->w() > w) { + Fl_RGB_Image *img2 = (Fl_RGB_Image*)img->copy(w, h); + delete img; + img = img2; } - Fl_RGB_Image *img = traverse_to_gl_subwindows(Fl_Window::current(), p, X, Y, w, h, alpha, NULL); - uchar *image_data = (uchar*)img->array; img->alloc_array = 0; + image_data = (uchar*)img->array; delete img; return image_data; } @@ -228,13 +237,11 @@ Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, uchar *p, else if ( g->as_window() && (!full_img || (g->window() && g->window()->as_gl_window())) ) { // the starting window or one inside a GL window if (full_img) g->as_window()->make_current(); - uchar *image_data; int alloc_img = (full_img != NULL || p == NULL); // false means use p, don't alloc new memory for image // on Darwin + X11, read_win_rectangle() sometimes returns NULL when there are subwindows, // thus the call is repeated - do image_data = Fl::screen_driver()->read_win_rectangle( (alloc_img ? NULL : p), x, y, w, h, alpha); while (!image_data); - full_img = new Fl_RGB_Image(image_data, w, h, alpha?4:3); - if (alloc_img) full_img->alloc_array = 1; + do full_img = Fl::screen_driver()->read_win_rectangle( (alloc_img ? NULL : p), x, y, w, h, alpha); + while (!full_img); } int n = g->children(); for (int i = 0; i < n; i++) { diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 92e0b1897..b6f01ea7c 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -2404,23 +2404,15 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top // capture the 4 window sides from screen uchar *rgb; if (htop) { - rgb = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top, ww, htop, 0); - r_top = new Fl_RGB_Image(rgb, ww, htop, 3); - r_top->alloc_array = 1; + r_top = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top, ww, htop, 0); top = Fl_Shared_Image::get(r_top); } if (wsides) { - rgb = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top + htop, wsides, h(), 0); - r_left = new Fl_RGB_Image(rgb, wsides, h(), 3); - r_left->alloc_array = 1; + r_left = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.top + htop, wsides, h(), 0); left = Fl_Shared_Image::get(r_left); - rgb = Fl::screen_driver()->read_win_rectangle(NULL, r.right - wsides, r.top + htop, wsides, h(), 0); - r_right = new Fl_RGB_Image(rgb, wsides, h(), 3); - r_right->alloc_array = 1; + r_right = Fl::screen_driver()->read_win_rectangle(NULL, r.right - wsides, r.top + htop, wsides, h(), 0); right = Fl_Shared_Image::get(r_right); - rgb = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.bottom-hbottom, ww, hbottom, 0); - r_bottom = new Fl_RGB_Image(rgb, ww, hbottom, 3); - r_bottom->alloc_array = 1; + r_bottom = Fl::screen_driver()->read_win_rectangle(NULL, r.left, r.bottom-hbottom, ww, hbottom, 0); bottom = Fl_Shared_Image::get(r_bottom); } ReleaseDC(NULL, (HDC)fl_graphics_driver->gc()); diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H index fc741d113..61a34dd2d 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H @@ -71,7 +71,7 @@ public: virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp); virtual int dnd(int unused); virtual int compose(int &del); - virtual uchar *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha); + virtual Fl_RGB_Image *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha); virtual void 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 86aa78a32..5c3388ce3 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -553,7 +554,7 @@ void Fl_Screen_Driver::font_name(int num, const char *name) { } -uchar * // O - Pixel buffer or NULL if failed +Fl_RGB_Image * // O - Pixel buffer or NULL if failed Fl_WinAPI_Screen_Driver::read_win_rectangle(uchar *p, // I - Pixel buffer or NULL to allocate int X, // I - Left position int Y, // I - Top position @@ -566,6 +567,7 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(uchar *p, // I - Pixel buffer or NU // Allocate the image data array as needed... d = alpha ? 4 : 3; + const uchar *oldp = p; if (!p) p = new uchar[w * h * d]; // Initialize the default colors/alpha in the whole image... @@ -593,7 +595,7 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(uchar *p, // I - Pixel buffer or NU Y = 0; } - if (h < 1 || w < 1) return p; // nothing to copy + if (h < 1 || w < 1) return 0/*p*/; // nothing to copy int line_size = ((3*w+3)/4) * 4; // each line is aligned on a DWORD (4 bytes) uchar *dib = new uchar[line_size*h]; // create temporary buffer to read DIB @@ -649,7 +651,9 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(uchar *p, // I - Pixel buffer or NU DeleteObject(hbm); delete[] dib; // delete DIB temporary buffer - return p; + Fl_RGB_Image *rgb = new Fl_RGB_Image(p, w, h, d); + if (!oldp) rgb->alloc_array = 1; + return rgb; } // diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H index 0d1bcaf0e..2585cb972 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.H +++ b/src/drivers/X11/Fl_X11_Screen_Driver.H @@ -79,7 +79,7 @@ public: virtual int compose(int &del); virtual void compose_reset(); virtual int text_display_can_leak(); - virtual uchar *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha); + virtual Fl_RGB_Image *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha); virtual void 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 5eeb2a1b6..f8bf520b1 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -750,7 +750,7 @@ extern "C" { } } -uchar *Fl_X11_Screen_Driver::read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha) +Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha) { XImage *image; // Captured image int i, maxindex; // Looping vars @@ -858,6 +858,7 @@ uchar *Fl_X11_Screen_Driver::read_win_rectangle(uchar *p, int X, int Y, int w, i d = alpha ? 4 : 3; // Allocate the image data array as needed... + const uchar *oldp = p; if (!p) p = new uchar[w * h * d]; // Initialize the default colors/alpha in the whole image... @@ -1157,7 +1158,9 @@ uchar *Fl_X11_Screen_Driver::read_win_rectangle(uchar *p, int X, int Y, int w, i // Destroy the X image we've read and return the RGB(A) image... XDestroyImage(image); - return p; + Fl_RGB_Image *rgb = new Fl_RGB_Image(p, w, h, d); + if (!oldp) rgb->alloc_array = 1; + return rgb; } // diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx index 07f9c5407..6fc76e325 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx @@ -402,26 +402,23 @@ void Fl_X11_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, F if (!do_it) wsides = htop = 0; int hbottom = wsides; fl_window = parent; - uchar *rgb; if (htop) { - rgb = Fl::screen_driver()->read_win_rectangle(NULL, 0, 0, - (w() + 2 * wsides), htop, 0); - r_top = new Fl_RGB_Image(rgb, w() + 2 * wsides, htop, 3); - r_top->alloc_array = 1; + r_top = Fl::screen_driver()->read_win_rectangle(NULL, 0, 0, - (w() + 2 * wsides), htop, 0); top = Fl_Shared_Image::get(r_top); } if (wsides) { - rgb = Fl::screen_driver()->read_win_rectangle(NULL, 0, htop, -wsides, h(), 0); - r_left = new Fl_RGB_Image(rgb, wsides, h(), 3); - r_left->alloc_array = 1; - left = Fl_Shared_Image::get(r_left); - rgb = Fl::screen_driver()->read_win_rectangle(NULL, w() + wsides, htop, -wsides, h(), 0); - r_right = new Fl_RGB_Image(rgb, wsides, h(), 3); - r_right->alloc_array = 1; - right = Fl_Shared_Image::get(r_right); - rgb = Fl::screen_driver()->read_win_rectangle(NULL, 0, htop + h(), -(w() + 2*wsides), hbottom, 0); - r_bottom = new Fl_RGB_Image(rgb, w() + 2*wsides, hbottom, 3); - r_bottom->alloc_array = 1; - bottom = Fl_Shared_Image::get(r_bottom); + r_left = Fl::screen_driver()->read_win_rectangle(NULL, 0, htop, -wsides, h(), 0); + if (r_left) { + left = Fl_Shared_Image::get(r_left); + } + r_right = Fl::screen_driver()->read_win_rectangle(NULL, w() + wsides, htop, -wsides, h(), 0); + if (r_right) { + right = Fl_Shared_Image::get(r_right); + } + r_bottom = Fl::screen_driver()->read_win_rectangle(NULL, 0, htop + h(), -(w() + 2*wsides), hbottom, 0); + if (r_bottom) { + bottom = Fl_Shared_Image::get(r_bottom); + } } fl_window = from; previous->Fl_Surface_Device::set_current(); -- cgit v1.2.3