From 62b84c466d25e47ad3836c0875e41902913fdf8d Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Fri, 19 Jan 2007 12:15:12 +0000 Subject: [PATCH] - set tags in the resulting image - remove an unused variable --- Changes | 2 ++ Screenshot.pm | 44 ++++++++++++++++++++++++++++++++++++++++++-- scwin32.c | 6 ++++++ scx11.c | 9 +++++++-- t/10win32.t | 34 +++++++++++++++++++++++++++++++++- t/20x11.t | 27 ++++++++++++++++++++++++++- 6 files changed, 116 insertions(+), 6 deletions(-) diff --git a/Changes b/Changes index 27c9be7..49a0b30 100755 --- a/Changes +++ b/Changes @@ -1,4 +1,6 @@ 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!) diff --git a/Screenshot.pm b/Screenshot.pm index 28b6e24..79159cf 100644 --- a/Screenshot.pm +++ b/Screenshot.pm @@ -264,6 +264,44 @@ Closes a display returned by Imager::Screenshot::x11_open(). =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 +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 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 @@ -274,8 +312,10 @@ Under Win32, if there's a screesaver running, then you grab the 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 diff --git a/scwin32.c b/scwin32.c index 13c726d..3d9f8c2 100644 --- a/scwin32.c +++ b/scwin32.c @@ -101,6 +101,12 @@ imss_win32(unsigned hwnd_u, int include_decor, int left, int top, 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); diff --git a/scx11.c b/scx11.c index 64df505..d58cd4f 100644 --- a/scx11.c +++ b/scx11.c @@ -19,7 +19,6 @@ imss_x11(unsigned long display_ul, int window_id, 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; @@ -46,7 +45,7 @@ imss_x11(unsigned long display_ul, int window_id, if (!window_id) { int screen = DefaultScreen(display); - window_id = RootWindow(display, 0); + window_id = RootWindow(display, screen); } if (!XGetWindowAttributes(display, window_id, &attr)) { @@ -124,6 +123,12 @@ imss_x11(unsigned long display_ul, int window_id, 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; } diff --git a/t/10win32.t b/t/10win32.t index f1db421..5a50359 100644 --- a/t/10win32.t +++ b/t/10win32.t @@ -2,17 +2,35 @@ 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 @@ -21,3 +39,17 @@ plan tests => 2; 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"); +} diff --git a/t/20x11.t b/t/20x11.t index 80e9e97..0b49538 100644 --- a/t/20x11.t +++ b/t/20x11.t @@ -11,7 +11,7 @@ Imager::Screenshot->have_x11 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 @@ -19,6 +19,15 @@ plan tests => 5; 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"); } { @@ -42,4 +51,20 @@ plan tests => 5; "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); -- 2.39.2