Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:Test
gnome-utils
gnome-utils-bnc381135-screenshot-mask-randr-are...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnome-utils-bnc381135-screenshot-mask-randr-areas.diff of Package gnome-utils
bnc381135 - Blank out invisible areas in non-rectangular multi-monitor configurations diff --git a/gnome-screenshot/screenshot-utils.c b/gnome-screenshot/screenshot-utils.c index f12c353..a80c7fb 100644 --- a/gnome-screenshot/screenshot-utils.c +++ b/gnome-screenshot/screenshot-utils.c @@ -276,6 +276,129 @@ find_wm_window (Window xid) while (TRUE); } +static GdkRegion * +make_region_with_monitors (GdkScreen *screen) +{ + GdkRegion *region; + int num_monitors; + int i; + + num_monitors = gdk_screen_get_n_monitors (screen); + + region = gdk_region_new (); + + for (i = 0; i < num_monitors; i++) + { + GdkRectangle rect; + + gdk_screen_get_monitor_geometry (screen, i, &rect); + gdk_region_union_with_rect (region, &rect); + } + + return region; +} + +static void +blank_rectangle_in_pixbuf (GdkPixbuf *pixbuf, GdkRectangle *rect) +{ + int x, y; + int x2, y2; + guchar *pixels; + int rowstride; + int n_channels; + guchar *row; + gboolean has_alpha; + + g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); + + x2 = rect->x + rect->width; + y2 = rect->y + rect->height; + + pixels = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + for (y = rect->y; y < y2; y++) + { + guchar *p; + + row = pixels + y * rowstride; + p = row + rect->x * n_channels; + + for (x = rect->x; x < x2; x++) + { + *p++ = 0; + *p++ = 0; + *p++ = 0; + + if (has_alpha) + *p++ = 255; /* opaque black */ + } + } +} + +static void +blank_region_in_pixbuf (GdkPixbuf *pixbuf, GdkRegion *region) +{ + GdkRectangle *rects; + int n_rects; + int i; + int width, height; + GdkRectangle pixbuf_rect; + + gdk_region_get_rectangles (region, &rects, &n_rects); + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + + pixbuf_rect.x = 0; + pixbuf_rect.y = 0; + pixbuf_rect.width = width; + pixbuf_rect.height = height; + + for (i = 0; i < n_rects; i++) + { + GdkRectangle dest; + + if (gdk_rectangle_intersect (rects + i, &pixbuf_rect, &dest)) + blank_rectangle_in_pixbuf (pixbuf, &dest); + } + + g_free (rects); +} + +/* When there are multiple monitors with different resolutions, the visible area + * within the root window may not be rectangular (it may have an L-shape, for + * example). In that case, mask out the areas of the root window which would + * not be visible in the monitors, so that screenshot do not end up with content + * that the user won't ever see. + */ +static void +mask_monitors (GdkPixbuf *pixbuf, GdkWindow *root_window) +{ + GdkScreen *screen; + GdkRegion *region_with_monitors; + GdkRegion *invisible_region; + GdkRectangle rect; + + screen = gdk_drawable_get_screen (GDK_DRAWABLE (root_window)); + + region_with_monitors = make_region_with_monitors (screen); + + rect.x = 0; + rect.y = 0; + rect.width = gdk_screen_get_width (screen); + rect.height = gdk_screen_get_height (screen); + + invisible_region = gdk_region_rectangle (&rect); + gdk_region_subtract (invisible_region, region_with_monitors); + + blank_region_in_pixbuf (pixbuf, invisible_region); + + gdk_region_destroy (region_with_monitors); + gdk_region_destroy (invisible_region); +} GdkPixbuf * screenshot_get_pixbuf (GdkWindow *window, @@ -334,6 +457,8 @@ screenshot_get_pixbuf (GdkWindow *window, x_orig, y_orig, 0, 0, width, height); + mask_monitors (screenshot, root); + #ifdef HAVE_X11_EXTENSIONS_SHAPE_H if (include_border) { @@ -350,7 +475,7 @@ screenshot_get_pixbuf (GdkWindow *window, ShapeBounding, &rectangle_count, &rectangle_order); - if (rectangles && rectangle_count > 0) + if (rectangles && rectangle_count > 0 && window != root) { gboolean has_alpha = gdk_pixbuf_get_has_alpha (screenshot);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor