-0.001 1 Jan 2007\r
- - Initial release with X11 and Win32 support\r
+0.001 1 Jan 2007
+ - Initial release with X11 and Win32 support
Changes History
-imss.h Declarations of the functions the XS gives access to
-Makefile.PL Build script
MANIFEST This list of files
MANIFEST.SKIP Files not to include in the MANIFEST
+Makefile.PL Build script
Screenshot.pm Main perl implementation
Screenshot.xs Interface to C code
+examples/win32_fw.pl Example - get a window by name on win32 and grab it
+imss.h Declarations of the functions the XS gives access to
scwin32.c Win32 implementation
scx11.c X11 implementation
t/00load.t Test - can we load the modules
-#!perl -w\r
-use strict;\r
-use ExtUtils::MakeMaker;\r
-use Imager::ExtUtils;\r
-use Config;\r
-use File::Spec;\r
-\r
-my @objs = qw/Screenshot.o/;\r
-my @cflags;\r
-my @lflags;\r
-my $X11_lib = $^O eq 'cygwin' ? 'X11.dll' : 'X11';\r
-if (find_header("X11/Xlib.h") and find_lib($X11_lib)) {\r
- push @objs, 'scx11.o';\r
- push @cflags, '-DSS_X11';\r
- push @lflags, '-l'.$X11_lib;\r
- print "Found X11\n";\r
-}\r
-if (find_header('windows.h') and find_lib('gdi32')) {\r
- push @objs, 'scwin32.o';\r
- push @cflags, '-DSS_WIN32';\r
- if ($^O eq 'cygwin') {\r
- push @lflags, '-L/usr/lib/w32api', '-lgdi32';\r
- }\r
- print "Found Win32\n";\r
-}\r
-\r
-unless (@objs > 1) {\r
- die "Sorry, I can't find headers or libraries for a supported GUI\n"\r
-}\r
-\r
-my %opts = \r
- (\r
- NAME => 'Imager::Screenshot',\r
- VERSION_FROM => 'Screenshot.pm',\r
- OBJECT => "@objs",\r
- PREREQ_PM => {\r
- 'Imager' => 0.54,\r
- },\r
- INC => Imager::ExtUtils->includes,\r
- TYPEMAPS => [ Imager::ExtUtils->typemap ],\r
- );\r
-\r
-$opts{LIBS} = "@lflags" if @lflags;\r
-$opts{INC} .= " @cflags" if @cflags;\r
-\r
-if ($ExtUtils::MakeMaker::VERSION > 6.06) {\r
- $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>';\r
- $opts{ABSTRACT} = 'Screen/Window capture to Imager images';\r
-}\r
-\r
-WriteMakefile(%opts);\r
-\r
-my @incs;\r
-sub header_search_path {\r
- @incs and return @incs;\r
-\r
- push @incs, '/usr/include'\r
- unless $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/;\r
- push @incs, split /\Q$Config{path_sep}/, $ENV{INCLUDE}\r
- if $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/ and $ENV{INCLUDE};\r
- push @incs, split ' ', $Config{locincpth}\r
- if $Config{locincpth};\r
- push @incs, split /\Q$Config{path_sep}/, $Config{incpath}\r
- if $Config{incpath};\r
- push @incs, '/usr/include/w32api', '/usr/X11R6/include'\r
- if $^O eq 'cygwin';\r
-\r
- @incs = grep -d, @incs;\r
-\r
- @incs;\r
-}\r
-\r
-my @libs;\r
-sub library_search_path {\r
- @libs and return @libs;\r
-\r
- push @libs, '/usr/lib'\r
- unless $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/;\r
- push @libs, split /\Q$Config{path_sep}/, $ENV{LIB}\r
- if $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/ and $ENV{LIB};\r
- push @libs, split ' ', $Config{loclibpth}\r
- if $Config{loclibpth};\r
- push @libs, split /\Q$Config{path_sep}/, $Config{libpth}\r
- if $Config{libpth};\r
- push @libs, '/usr/lib/w32api', '/usr/X11R6/lib'\r
- if $^O eq 'cygwin';\r
-\r
- @libs = grep -d, @libs;\r
-\r
- @libs;\r
-}\r
-\r
-\r
-sub _find_file {\r
- my ($name, @where) = @_;\r
-\r
- grep -f File::Spec->catfile($_, $name), @where;\r
-}\r
-\r
-sub find_header {\r
- _find_file($_[0], header_search_path());\r
-}\r
-\r
-sub find_lib {\r
- my $name = shift;\r
- my @found;\r
- if ($^O eq 'MSWin32' && $Config{_a} eq '.lib') {\r
- @found = _find_file($name . $Config{_a}, library_search_path());\r
- }\r
- else {\r
- @found = _find_file("lib" . $name . $Config{_a}, library_search_path());\r
- }\r
- if (@found) {\r
- push @lflags, "-L$_" for @found;\r
- }\r
- @found;\r
-}\r
+#!perl -w
+use strict;
+use ExtUtils::MakeMaker;
+use Imager::ExtUtils;
+use Config;
+use File::Spec;
+
+my @objs = qw/Screenshot.o/;
+my @cflags;
+my @lflags;
+my $X11_lib = $^O eq 'cygwin' ? 'X11.dll' : 'X11';
+if (find_header("X11/Xlib.h") and find_lib($X11_lib)) {
+ push @objs, 'scx11.o';
+ push @cflags, '-DSS_X11';
+ push @lflags, '-l'.$X11_lib;
+ print "Found X11\n";
+}
+if (find_header('windows.h') and find_lib('gdi32')) {
+ push @objs, 'scwin32.o';
+ push @cflags, '-DSS_WIN32';
+ if ($^O eq 'cygwin') {
+ push @lflags, '-L/usr/lib/w32api', '-lgdi32';
+ }
+ print "Found Win32\n";
+}
+
+unless (@objs > 1) {
+ die "Sorry, I can't find headers or libraries for a supported GUI\n"
+}
+
+my %opts =
+ (
+ NAME => 'Imager::Screenshot',
+ VERSION_FROM => 'Screenshot.pm',
+ OBJECT => "@objs",
+ PREREQ_PM => {
+ 'Imager' => 0.54,
+ },
+ INC => Imager::ExtUtils->includes,
+ TYPEMAPS => [ Imager::ExtUtils->typemap ],
+ );
+
+$opts{LIBS} = "@lflags" if @lflags;
+$opts{INC} .= " @cflags" if @cflags;
+
+if ($ExtUtils::MakeMaker::VERSION > 6.06) {
+ $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>';
+ $opts{ABSTRACT} = 'Screen/Window capture to Imager images';
+}
+
+WriteMakefile(%opts);
+
+my @incs;
+sub header_search_path {
+ @incs and return @incs;
+
+ push @incs, '/usr/include'
+ unless $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/;
+ push @incs, split /\Q$Config{path_sep}/, $ENV{INCLUDE}
+ if $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/ and $ENV{INCLUDE};
+ push @incs, split ' ', $Config{locincpth}
+ if $Config{locincpth};
+ push @incs, split /\Q$Config{path_sep}/, $Config{incpath}
+ if $Config{incpath};
+ push @incs, '/usr/include/w32api', '/usr/X11R6/include'
+ if $^O eq 'cygwin';
+
+ @incs = grep -d, @incs;
+
+ @incs;
+}
+
+my @libs;
+sub library_search_path {
+ @libs and return @libs;
+
+ push @libs, '/usr/lib'
+ unless $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/;
+ push @libs, split /\Q$Config{path_sep}/, $ENV{LIB}
+ if $^O eq 'MSWin32' && $Config{cc} =~ /\bcl\b/ and $ENV{LIB};
+ push @libs, split ' ', $Config{loclibpth}
+ if $Config{loclibpth};
+ push @libs, split /\Q$Config{path_sep}/, $Config{libpth}
+ if $Config{libpth};
+ push @libs, '/usr/lib/w32api', '/usr/X11R6/lib'
+ if $^O eq 'cygwin';
+
+ @libs = grep -d, @libs;
+
+ @libs;
+}
+
+
+sub _find_file {
+ my ($name, @where) = @_;
+
+ grep -f File::Spec->catfile($_, $name), @where;
+}
+
+sub find_header {
+ _find_file($_[0], header_search_path());
+}
+
+sub find_lib {
+ my $name = shift;
+ my @found;
+ if ($^O eq 'MSWin32' && $Config{_a} eq '.lib') {
+ @found = _find_file($name . $Config{_a}, library_search_path());
+ }
+ else {
+ @found = _find_file("lib" . $name . $Config{_a}, library_search_path());
+ }
+ if (@found) {
+ push @lflags, "-L$_" for @found;
+ }
+ @found;
+}
--- /dev/null
+Imager::Screenshot is a module that grabs an image from a window under
+X11 or Win32.
+
+Requires:
+ Imager 0.54 or later.
+ SDK header files and libraries for Win32 support
+ X11 header files and libraries for X11 support.
+ A C compiler compatible with that used to build perl itself.
+
+Optional
+ Perl/Tk
+
+Installation:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+ (nmake or dmake on Win32)
+
+Tested under:
+
+ - Win32 (VC++ 6.0)
+ - Win32 (mingw)
+ - Win32/X11 (cygwin as of Jan 1 2007)
+ - X11 (Debian Linux)
\r
=back\r
\r
+=head1 LICENSE\r
+\r
+Imager::Screenshot is licensed under the same terms as Perl itself.\r
+\r
=head1 AUTHOR\r
\r
Tony Cook <tonyc@cpan.org>\r
-#include "EXTERN.h"\r
-#include "perl.h"\r
-#include "XSUB.h"\r
-#include "imext.h"\r
-#include "imperl.h"\r
-#include "imss.h"\r
-\r
-DEFINE_IMAGER_CALLBACKS;\r
-\r
-#define imss__x11_open imss_x11_open\r
-\r
-MODULE = Imager::Screenshot PACKAGE = Imager::Screenshot PREFIX = imss\r
-\r
-PROTOTYPES: DISABLE\r
-\r
-#ifdef SS_WIN32\r
-\r
-Imager\r
-imss_win32(hwnd, include_decor = 0)\r
- unsigned hwnd\r
- int include_decor\r
-\r
-#endif\r
-\r
-#ifdef SS_X11\r
-\r
-Imager\r
-imss_x11(display, window_id)\r
- unsigned long display\r
- int window_id\r
-\r
-unsigned long\r
-imss_x11_open(display_name = NULL)\r
- const char *display_name\r
-\r
-void\r
-imss_x11_close(display)\r
- unsigned long display\r
-\r
-#endif\r
-\r
-BOOT:\r
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "imext.h"
+#include "imperl.h"
+#include "imss.h"
+
+DEFINE_IMAGER_CALLBACKS;
+
+#define imss__x11_open imss_x11_open
+
+MODULE = Imager::Screenshot PACKAGE = Imager::Screenshot PREFIX = imss
+
+PROTOTYPES: DISABLE
+
+#ifdef SS_WIN32
+
+Imager
+imss_win32(hwnd, include_decor = 0)
+ unsigned hwnd
+ int include_decor
+
+#endif
+
+#ifdef SS_X11
+
+Imager
+imss_x11(display, window_id)
+ unsigned long display
+ int window_id
+
+unsigned long
+imss_x11_open(display_name = NULL)
+ const char *display_name
+
+void
+imss_x11_close(display)
+ unsigned long display
+
+#endif
+
+BOOT:
PERL_INITIALIZE_IMAGER_CALLBACKS;
\ No newline at end of file
--- /dev/null
+#!perl -w
+use strict;
+use Win32::API;
+use Imager;
+use Imager::Screenshot 'screenshot';
+
+# delay so I can bring the window to the front
+sleep 2;
+
+# get the API
+my $find_window = Win32::API->new('user32', 'FindWindowA', 'NP', 'N')
+ or die "Cannot import FindWindow\n";
+
+# get the window, this requires an exact match on the window title
+my $hwnd = $find_window->Call(0, "use Perl: All the Perl that's Practical to Extract and Report - Mozilla Firefox");
+
+$hwnd
+ or die "Mozilla window not found";
+
+# take a picture, including the border and title bar
+my $img = screenshot(hwnd => $hwnd, decor=>1)
+ or die Imager->errstr;
+
+# and save it
+$img->write(file=>'mozilla.ppm')
+ or die $img->errstr;
+
-#ifndef IMSS_H\r
-#define IMSS_H\r
-\r
-extern i_img *\r
-imss_win32(unsigned hwnd, int include_decor);\r
-\r
-extern i_img *\r
-imss_x11(unsigned long display, int window_id);\r
-\r
-extern unsigned long\r
-imss_x11_open(char const *display_name);\r
-extern void\r
-imss_x11_close(unsigned long display);\r
-\r
-#endif\r
+#ifndef IMSS_H
+#define IMSS_H
+
+extern i_img *
+imss_win32(unsigned hwnd, int include_decor);
+
+extern i_img *
+imss_x11(unsigned long display, int window_id);
+
+extern unsigned long
+imss_x11_open(char const *display_name);
+extern void
+imss_x11_close(unsigned long display);
+
+#endif
-#include "imext.h"\r
-#include <windows.h>\r
-#include <string.h>\r
-\r
-i_img *\r
-imss_win32(unsigned hwnd_u, int include_decor) {\r
- HWND hwnd = (HWND)hwnd_u;\r
- HDC wdc, bmdc;\r
- RECT rect;\r
- HBITMAP work_bmp, old_dc_bmp;\r
- int width, height;\r
- BITMAPINFO bmi;\r
- unsigned char *di_bits;\r
- i_img *result = NULL;\r
-\r
- i_clear_error();\r
-\r
- if (!hwnd)\r
- hwnd = GetDesktopWindow();\r
-\r
- if (include_decor) {\r
- wdc = GetWindowDC(hwnd);\r
- GetWindowRect(hwnd, &rect);\r
- }\r
- else {\r
- wdc = GetDC(hwnd);\r
- GetClientRect(hwnd, &rect);\r
- }\r
- if (!wdc) {\r
- i_push_error(0, "Cannot get window DC - invalid hwnd?");\r
- return NULL;\r
- }\r
-\r
- width = rect.right - rect.left;\r
- height = rect.bottom - rect.top;\r
- work_bmp = CreateCompatibleBitmap(wdc, width, height);\r
- bmdc = CreateCompatibleDC(wdc);\r
- old_dc_bmp = SelectObject(bmdc, work_bmp);\r
- BitBlt(bmdc, 0, 0, width, height, wdc, 0, 0, SRCCOPY);\r
-\r
- /* make a dib */\r
- memset(&bmi, 0, sizeof(bmi));\r
- bmi.bmiHeader.biSize = sizeof(bmi);\r
- bmi.bmiHeader.biWidth = width;\r
- bmi.bmiHeader.biHeight = -height;\r
- bmi.bmiHeader.biPlanes = 1;\r
- bmi.bmiHeader.biBitCount = 32;\r
- bmi.bmiHeader.biCompression = BI_RGB;\r
-\r
- di_bits = mymalloc(4 * width * height);\r
- if (GetDIBits(bmdc, work_bmp, 0, height, di_bits, &bmi, DIB_RGB_COLORS)) {\r
- i_color *line = mymalloc(sizeof(i_color) * width);\r
- i_color *cp;\r
- int x, y;\r
- unsigned char *ch_pp = di_bits;\r
- result = i_img_8_new(width, height, 3);\r
-\r
- for (y = 0; y < height; ++y) {\r
- cp = line;\r
- for (x = 0; x < width; ++x) {\r
- cp->rgb.b = *ch_pp++;\r
- cp->rgb.g = *ch_pp++;\r
- cp->rgb.r = *ch_pp++;\r
- ch_pp++;\r
- cp++;\r
- }\r
- i_plin(result, 0, width, y, line);\r
- }\r
- myfree(line);\r
- }\r
-\r
- /* clean up */\r
- myfree(di_bits);\r
- SelectObject(bmdc, old_dc_bmp);\r
- DeleteDC(bmdc);\r
- DeleteObject(work_bmp);\r
- ReleaseDC(hwnd, wdc);\r
-\r
- return result;\r
-}\r
+#include "imext.h"
+#include <windows.h>
+#include <string.h>
+
+i_img *
+imss_win32(unsigned hwnd_u, int include_decor) {
+ HWND hwnd = (HWND)hwnd_u;
+ HDC wdc, bmdc;
+ RECT rect;
+ HBITMAP work_bmp, old_dc_bmp;
+ int width, height;
+ BITMAPINFO bmi;
+ unsigned char *di_bits;
+ i_img *result = NULL;
+
+ i_clear_error();
+
+ if (!hwnd)
+ hwnd = GetDesktopWindow();
+
+ if (include_decor) {
+ wdc = GetWindowDC(hwnd);
+ GetWindowRect(hwnd, &rect);
+ }
+ else {
+ wdc = GetDC(hwnd);
+ GetClientRect(hwnd, &rect);
+ }
+ if (!wdc) {
+ i_push_error(0, "Cannot get window DC - invalid hwnd?");
+ return NULL;
+ }
+
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ work_bmp = CreateCompatibleBitmap(wdc, width, height);
+ bmdc = CreateCompatibleDC(wdc);
+ old_dc_bmp = SelectObject(bmdc, work_bmp);
+ BitBlt(bmdc, 0, 0, width, height, wdc, 0, 0, SRCCOPY);
+
+ /* make a dib */
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(bmi);
+ bmi.bmiHeader.biWidth = width;
+ bmi.bmiHeader.biHeight = -height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ di_bits = mymalloc(4 * width * height);
+ if (GetDIBits(bmdc, work_bmp, 0, height, di_bits, &bmi, DIB_RGB_COLORS)) {
+ i_color *line = mymalloc(sizeof(i_color) * width);
+ i_color *cp;
+ int x, y;
+ unsigned char *ch_pp = di_bits;
+ result = i_img_8_new(width, height, 3);
+
+ for (y = 0; y < height; ++y) {
+ cp = line;
+ for (x = 0; x < width; ++x) {
+ cp->rgb.b = *ch_pp++;
+ cp->rgb.g = *ch_pp++;
+ cp->rgb.r = *ch_pp++;
+ ch_pp++;
+ cp++;
+ }
+ i_plin(result, 0, width, y, line);
+ }
+ myfree(line);
+ }
+
+ /* clean up */
+ myfree(di_bits);
+ SelectObject(bmdc, old_dc_bmp);
+ DeleteDC(bmdc);
+ DeleteObject(work_bmp);
+ ReleaseDC(hwnd, wdc);
+
+ return result;
+}
-#!perl -w\r
-use strict;\r
-use Test::More tests => 1;\r
-\r
-use_ok('Imager::Screenshot', 'screenshot');\r
+#!perl -w
+use strict;
+use Test::More tests => 1;
+
+use_ok('Imager::Screenshot', 'screenshot');
-#!perl -w\r
-use strict;\r
-use Test::More;\r
-\r
-use Imager::Screenshot 'screenshot';\r
-\r
-Imager::Screenshot->have_win32\r
- or plan skip_all => "No Win32 support";\r
-\r
-plan tests => 2;\r
-\r
-{\r
- my $im = screenshot(hwnd => 0);\r
- \r
- ok($im, "got a screenshot");\r
-}\r
-\r
-{ # as a method\r
- my $im = Imager::Screenshot->screenshot(hwnd => 0);\r
-\r
- ok($im, "call as a method");\r
-}\r
-\r
+#!perl -w
+use strict;
+use Test::More;
+
+use Imager::Screenshot 'screenshot';
+
+Imager::Screenshot->have_win32
+ or plan skip_all => "No Win32 support";
+
+plan tests => 2;
+
+{
+ my $im = screenshot(hwnd => 0);
+
+ ok($im, "got a screenshot");
+}
+
+{ # as a method
+ my $im = Imager::Screenshot->screenshot(hwnd => 0);
+
+ ok($im, "call as a method");
+}
+
-#!perl -w\r
-use strict;\r
-use Test::More;\r
-\r
-use Imager::Screenshot 'screenshot';\r
-\r
-Imager::Screenshot->have_x11\r
- or plan skip_all => "No X11 support";\r
-\r
-# can we connect to a display\r
-my $display = Imager::Screenshot::x11_open()\r
- or plan skip_all => "Cannot connect to a display: ".Imager->errstr;\r
-\r
-plan tests => 5;\r
-\r
-{\r
- # should automatically connect and grab the root window\r
- my $im = screenshot(id => 0)\r
- or print "# ", Imager->errstr, "\n";\r
- \r
- ok($im, "got a root screenshot, no display");\r
-}\r
-\r
-{\r
- # use our supplied display\r
- my $im = screenshot(display => $display, id => 0);\r
- ok($im, "got a root screenshot, supplied display");\r
-}\r
-\r
-{\r
- # use our supplied display - as a method\r
- my $im = Imager::Screenshot->screenshot(display => $display, id => 0);\r
- ok($im, "got a root screenshot, supplied display (method)");\r
-}\r
-\r
-{\r
- # supply a junk window id\r
- my $im = screenshot(display => $display, id => 0xFFFFFFF)\r
- or print "# ", Imager->errstr, "\n";\r
- ok(!$im, "should fail to get screenshot");\r
- cmp_ok(Imager->errstr, '=~', 'BadWindow',\r
- "check error");\r
-}\r
-\r
-Imager::Screenshot::x11_close($display);\r
+#!perl -w
+use strict;
+use Test::More;
+
+use Imager::Screenshot 'screenshot';
+
+Imager::Screenshot->have_x11
+ or plan skip_all => "No X11 support";
+
+# can we connect to a display
+my $display = Imager::Screenshot::x11_open()
+ or plan skip_all => "Cannot connect to a display: ".Imager->errstr;
+
+plan tests => 5;
+
+{
+ # should automatically connect and grab the root window
+ my $im = screenshot(id => 0)
+ or print "# ", Imager->errstr, "\n";
+
+ ok($im, "got a root screenshot, no display");
+}
+
+{
+ # use our supplied display
+ my $im = screenshot(display => $display, id => 0);
+ ok($im, "got a root screenshot, supplied display");
+}
+
+{
+ # use our supplied display - as a method
+ my $im = Imager::Screenshot->screenshot(display => $display, id => 0);
+ ok($im, "got a root screenshot, supplied display (method)");
+}
+
+{
+ # supply a junk window id
+ my $im = screenshot(display => $display, id => 0xFFFFFFF)
+ or print "# ", Imager->errstr, "\n";
+ ok(!$im, "should fail to get screenshot");
+ cmp_ok(Imager->errstr, '=~', 'BadWindow',
+ "check error");
+}
+
+Imager::Screenshot::x11_close($display);
-#!perl -w\r
-use strict;\r
-use Test::More;\r
-use ExtUtils::Manifest qw(maniread);\r
-eval "use Test::Pod 1.00;";\r
-plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;\r
-my $manifest = maniread();\r
-my @pod = grep /\.(pm|pl|pod|PL)$/, keys %$manifest;\r
-plan tests => scalar(@pod);\r
-for my $file (@pod) {\r
- pod_file_ok($file, "pod ok in $file");\r
-}\r
+#!perl -w
+use strict;
+use Test::More;
+use ExtUtils::Manifest qw(maniread);
+eval "use Test::Pod 1.00;";
+plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
+my $manifest = maniread();
+my @pod = grep /\.(pm|pl|pod|PL)$/, keys %$manifest;
+plan tests => scalar(@pod);
+for my $file (@pod) {
+ pod_file_ok($file, "pod ok in $file");
+}
-#!perl -w\r
-use strict;\r
-use Test::More;\r
-eval "use Test::Pod::Coverage;";\r
-plan skip_all => "Test::Pod::Coverage required for POD coverage" if $@;\r
-\r
-plan tests => 1;\r
-pod_coverage_ok('Imager::Screenshot');\r
+#!perl -w
+use strict;
+use Test::More;
+eval "use Test::Pod::Coverage;";
+plan skip_all => "Test::Pod::Coverage required for POD coverage" if $@;
+
+plan tests => 1;
+pod_coverage_ok('Imager::Screenshot');