0.004
+ - set tags in the resulting image
+ - remove an unused variable
- add support for getting a subimage of the window
- include the interface header in the implementations so we
get errors when they don't match (doh!)
=back
+=head1 TAGS
+
+screenshot() sets a number of tags in the images it returns, these are:
+
+=over
+
+=item *
+
+ss_left - the distance between the left side of the window and the
+left side of the captured area. The same value as the I<left>
+parameter when that is positive.
+
+=item *
+
+ss_top - the distance between the top side of the window the top side
+of the captured area. The same value at the I<top> parameter when
+that is positive.
+
+=item *
+
+ss_window_width - the full width of the window.
+
+=item *
+
+ss_window_height - the full height of the window.
+
+=item *
+
+ss_type - the type of capture done, either "Win32" or "X11".
+
+=back
+
+To cheaply get the window size you can capture a single pixel:
+
+ my $im = screenshot(right => 1, bottom => 1);
+ my $window_width = $im->tags(name => 'ss_window_width');
+ my $window_height = $im->tags(name => 'ss_window_height');
+
=head1 CAVEATS
It's possible to have more than one grab driver available, for
results of the screensaver.
Grabbing the root window on a rootless server (eg. Cygwin/X) may not
-grab the background. In fact, when I tested under Cygwin/X I got the
-xterm window contents even when the Windows screensaver was running.
+grab the background that you see. In fact, when I tested under
+Cygwin/X I got the xterm window contents even when the Windows
+screensaver was running. The root window captured appeared to be that
+generated by my window manager.
=head1 LICENSE
myfree(line);
}
+ i_tags_setn(&result->tags, "ss_window_width", window_width);
+ i_tags_setn(&result->tags, "ss_window_height", window_height);
+ i_tags_set(&result->tags, "ss_type", "Win32", 5);
+ i_tags_setn(&result->tags, "ss_left", left);
+ i_tags_setn(&result->tags, "ss_top", top);
+
/* clean up */
myfree(di_bits);
SelectObject(bmdc, old_dc_bmp);
int left, int top, int right, int bottom) {
Display *display = (Display *)display_ul;
int own_display = 0; /* non-zero if we connect */
- GC gc;
XImage *image;
XWindowAttributes attr;
i_img *result;
if (!window_id) {
int screen = DefaultScreen(display);
- window_id = RootWindow(display, 0);
+ window_id = RootWindow(display, screen);
}
if (!XGetWindowAttributes(display, window_id, &attr)) {
if (own_display)
XCloseDisplay(display);
+ i_tags_setn(&result->tags, "ss_window_width", attr.width);
+ i_tags_setn(&result->tags, "ss_window_height", attr.height);
+ i_tags_set(&result->tags, "ss_type", "X11", 3);
+ i_tags_setn(&result->tags, "ss_left", left);
+ i_tags_setn(&result->tags, "ss_top", top);
+
return result;
}
use strict;
use Test::More;
+# you might be looking at this test code and wondering why it doesn't
+# try to check the images themselves - the reason is that in many
+# cases the build and tests are being done in an automated build, and
+# it may be possible that the user is running a screensaver, which
+# will be what's returned instead of what we expect.
+#
+# this applies for the sub-image tests too, since the screen saver may
+# have changed the screen between the two grabs
+
use Imager::Screenshot 'screenshot';
Imager::Screenshot->have_win32
or plan skip_all => "No Win32 support";
-plan tests => 2;
+plan tests => 13;
{
my $im = screenshot(hwnd => 0);
ok($im, "got a screenshot");
+
+ # check the size matches the tags
+ is($im->tags(name => 'ss_window_width'), $im->getwidth,
+ "check ss_window_width tag");
+ is($im->tags(name => 'ss_window_height'), $im->getheight,
+ "check ss_window_height tag");
+ is($im->tags(name => 'ss_left'), 0, "check ss_left tag");
+ is($im->tags(name => 'ss_top'), 0, "check ss_top tag");
+ is($im->tags(name => 'ss_type'), 'Win32', "check ss_type tag");
}
{ # as a method
ok($im, "call as a method");
}
+{ # try our subimage options
+ my $im = screenshot(hwnd => 0, left => 70, top => 30,
+ right => -35, bottom => -17);
+ ok($im, "call with left, top, etc");
+
+ # make sure tags set as expected
+ is($im->tags(name => 'ss_left'), 70, "check left value");
+ is($im->tags(name => 'ss_top'), 30, "check top value");
+ is($im->tags(name => 'ss_type'), 'Win32', "check ss_type");
+ is($im->tags(name => 'ss_window_width'), 70 + $im->getwidth + 35,
+ "check image width against window size");
+ is($im->tags(name => 'ss_window_height'), 30 + $im->getheight + 17,
+ "check image height against window size");
+}
my $display = Imager::Screenshot::x11_open()
or plan skip_all => "Cannot connect to a display: ".Imager->errstr;
-plan tests => 5;
+plan tests => 16;
{
# should automatically connect and grab the root window
or print "# ", Imager->errstr, "\n";
ok($im, "got a root screenshot, no display");
+
+ # check the size matches the tags
+ is($im->tags(name => 'ss_window_width'), $im->getwidth,
+ "check ss_window_width tag");
+ is($im->tags(name => 'ss_window_height'), $im->getheight,
+ "check ss_window_height tag");
+ is($im->tags(name => 'ss_left'), 0, "check ss_left tag");
+ is($im->tags(name => 'ss_top'), 0, "check ss_top tag");
+ is($im->tags(name => 'ss_type'), 'X11', "check ss_type tag");
}
{
"check error");
}
+
+{ # try our subimage options
+ my $im = screenshot(display => $display, id => 0,
+ left => 70, top => 30, right => -35, bottom => -17);
+ ok($im, "call with left, top, etc");
+
+ # make sure tags set as expected
+ is($im->tags(name => 'ss_left'), 70, "check left value");
+ is($im->tags(name => 'ss_top'), 30, "check top value");
+ is($im->tags(name => 'ss_type'), 'X11', "check ss_type");
+ is($im->tags(name => 'ss_window_width'), 70 + $im->getwidth + 35,
+ "check image width against window size");
+ is($im->tags(name => 'ss_window_height'), 30 + $im->getheight + 17,
+ "check image height against window size");
+}
+
Imager::Screenshot::x11_close($display);