]> git.imager.perl.org - imager-screenshot.git/blobdiff - Screenshot.pm
0.014 release
[imager-screenshot.git] / Screenshot.pm
index abb226e8703d8aefaf926319b8eb79e9895f6818..9963de66b4ff0e77e1d9719e50df7fba5a678cd8 100644 (file)
@@ -10,17 +10,10 @@ push @ISA, 'Exporter';
 BEGIN {
   require Exporter;
   @ISA = qw(Exporter);
-  $VERSION = '0.007';
-  eval {
-    # try XSLoader first, DynaLoader has annoying baggage
-    require XSLoader;
-    XSLoader::load('Imager::Screenshot' => $VERSION);
-    1;
-  } or do {
-    require DynaLoader;
-    push @ISA, 'DynaLoader';
-    bootstrap Imager::Screenshot $VERSION;
-  }
+  $VERSION = '0.014';
+
+  require XSLoader;
+  XSLoader::load('Imager::Screenshot' => $VERSION);
 }
 
 sub screenshot {
@@ -35,6 +28,8 @@ sub screenshot {
      top => 0,
      right => 0,
      bottom => 0,
+     monitor => 0,
+     direct => 0,
      @_);
 
   my $result;
@@ -42,13 +37,19 @@ sub screenshot {
     defined &_win32
       or die "Win32 driver not enabled\n";
     $result = _win32($opts{hwnd}, $opts{decor}, $opts{left}, $opts{top},
-                    $opts{right}, $opts{bottom});
+                    $opts{right}, $opts{bottom}, $opts{monitor});
   }
   elsif (defined $opts{id}) { # X11 window id
+    exists $opts{display} or $opts{display} = 0;
     defined &_x11
       or die "X11 driver not enabled\n";
     $result = _x11($opts{display}, $opts{id}, $opts{left}, $opts{top},
-                  $opts{right}, $opts{bottom});
+                  $opts{right}, $opts{bottom}, $opts{direct});
+  }
+  elsif (defined $opts{darwin}) { # as long as it's there
+    defined &_darwin
+      or die "Darwin driver not enabled\n";
+    $result = _darwin($opts{left}, $opts{top}, $opts{right}, $opts{bottom});
   }
   elsif ($opts{widget}) {
     # Perl/Tk widget
@@ -82,8 +83,10 @@ sub screenshot {
   else {
     $result =
       defined &_win32 ? _win32(0, $opts{decor}, $opts{left}, $opts{top},
-                              $opts{right}, $opts{bottom}) :
-       defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
+                              $opts{right}, $opts{bottom}, $opts{monitor}) :
+      defined &_darwin ? _darwin($opts{left}, $opts{top},
+                                $opts{right}, $opts{bottom}) :
+      defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
                             $opts{right}, $opts{bottom}) :
           die "No drivers enabled\n";
   }
@@ -106,6 +109,10 @@ sub have_x11 {
   defined &_x11;
 }
 
+sub have_darwin {
+  defined &_darwin;
+}
+
 sub x11_open {
   my $display = _x11_open(@_);
   unless ($display) {
@@ -151,6 +158,9 @@ Imager::Screenshot - screenshot to an Imager image
   # test for x11 support
   if (Imager::Screenshot->have_x11) { ... }
   
+  # test for Darwin (Mac OS X) support
+  if (Imager::Screenshot->have_darwin) { ... }
+  
 
 =head1 DESCRIPTION
 
@@ -165,12 +175,36 @@ Currently the image is always returned as a 24-bit image.
 
 =item screenshot hwnd => I<window handle>, decor => <capture decorations>
 
+=item screenshot hwnd => "active"
+
 Retrieve a screenshot under Win32, if I<window handle> is zero,
 capture the desktop.
 
 By default, window decorations are not captured, if the C<decor>
 parameter is set to true then window decorations are included.
 
+As of 0.010 hwnd can also be C<"active"> to capture the active (or
+"foreground") window.
+
+=item screenshot hwnd => 0
+
+Retrieve a screeshot of the default desktop under Win32.
+
+=item screenshot hwnd => 0, monitor => -1
+
+Retrieve a screenshot of all attached monitors under Win32.
+
+Note: this returns an image with an alpha channel, since there can be
+regions in the bounding rectangle of all monitors that no particular
+monitor covers.
+
+=item screenshot hwnd => 0, monitor => I<index>
+
+Retrieve a screenshot from a particular monitor under Win32.  A
+I<monitor> of zero is always treated as the primary monitor.
+
+If the given monitor is not active screenshot() will fail.
+
 =item screenshot id => I<window id>
 
 =item screenshot id => I<window id>, display => I<display object>
@@ -180,8 +214,28 @@ window.  I<display object> is a integer version of an X11 C< Display *
 >, if this isn't supplied C<screenshot()> will attempt connect to the
 the display specified by $ENV{DISPLAY}.
 
+By default this works by always capturing from the root window,
+adjusting for the position of the supplied window if one is supplied.
+
+To capture directly from the window, which returns a completely black
+image on some platforms, supply a C<< direct => 1 >> parameter.
+
 Note: taking a screenshot of a remote display is slow.
 
+=item screenshot darwin => 0
+
+Retrieve a screenshot under Mac OS X.  The only supported value for
+the C<darwin> parameter is C<0>.
+
+For a screen capture to be taken, the current user using
+Imager:Screenshot must be the currently logged in user on the display.
+
+If you're using fast user switching, the current user must be the
+active user.
+
+Note: this means you can ssh into a Mac OS X box and screenshot from
+the ssh session, if you're the current user on the display.
+
 =item screenshot widget => I<widget>
 
 =item screenshot widget => I<widget>, display => I<display>
@@ -207,6 +261,10 @@ if Win32 support is compiled, return screenshot(hwnd => 0).
 
 =item *
 
+if Darwin support is compiled, return screenshot(darwin => 0).
+
+=item *
+
 if X11 support is compiled, return screenshot(id => 0).
 
 =item *
@@ -255,6 +313,11 @@ So setting all 4 values to 0 retrieves the whole window.
   # 10x10 pixel at the bottom right corner
   my $bott_right_10 = screenshot(left => -10, top => -10, ...);
 
+If screenshot() fails, it will return nothing, and the cause of the
+failure can be retrieved via Imager->errstr, so typical use could be:
+
+  my $img = screenshot(...) or die Imager->errstr;
+
 =item have_win32
 
 Returns true if Win32 support is available.
@@ -263,6 +326,10 @@ Returns true if Win32 support is available.
 
 Returns true if X11 support is available.
 
+=item have_darwin
+
+Returns true if Darwin support is available.
+
 =item Imager::Screenshot::x11_open
 
 =item Imager::Screenshot::x11_open I<display name>
@@ -321,8 +388,12 @@ It's possible to have more than one grab driver available, for
 example, Win32 and X11, and which is used can have an effect on the
 result.
 
-Under Win32, if there's a screesaver running, then you grab the
-results of the screensaver.
+Under Win32 or OS X, if there's a screesaver running, then you grab
+the results of the screensaver.
+
+On OS X, you can grab the display from an ssh session as long as the
+ssh session is under the same user as the currently active user on the
+display.
 
 Grabbing the root window on a rootless server (eg. Cygwin/X) may not
 grab the background that you see.  In fact, when I tested under
@@ -348,12 +419,6 @@ Future plans include:
 
 =item *
 
-OS X support - I need to find out which APIs to use to do this.  I
-found some information on the APIs used for this, but don't have a Mac
-I can test on.
-
-=item *
-
 window name searches - currently screenshot() requires a window
 identifier of some sort, it would be more usable if we could supply
 some other identifier, either a window title or a window class name.