]> git.imager.perl.org - imager-screenshot.git/blob - Screenshot.pm
cf360d7833fd05ad5925b58cefa8e7909fb3c20b
[imager-screenshot.git] / Screenshot.pm
1 package Imager::Screenshot;
2 use strict;
3 use vars qw(@ISA $VERSION @EXPORT_OK);
4 use Imager;
5 require Exporter;
6
7 push @ISA, 'Exporter';
8 @EXPORT_OK = 'screenshot';
9
10 BEGIN {
11   require Exporter;
12   @ISA = qw(Exporter);
13   $VERSION = '0.011';
14   eval {
15     # try XSLoader first, DynaLoader has annoying baggage
16     require XSLoader;
17     XSLoader::load('Imager::Screenshot' => $VERSION);
18     1;
19   } or do {
20     require DynaLoader;
21     push @ISA, 'DynaLoader';
22     bootstrap Imager::Screenshot $VERSION;
23   }
24 }
25
26 sub screenshot {
27   # lose the class if called as a method
28   @_ % 2 == 1 and shift;
29
30   my %opts = 
31     (
32      decor => 0, 
33      display => 0, 
34      left => 0, 
35      top => 0,
36      right => 0,
37      bottom => 0,
38      monitor => 0,
39      @_);
40
41   my $result;
42   if (defined $opts{hwnd}) {
43     defined &_win32
44       or die "Win32 driver not enabled\n";
45     $result = _win32($opts{hwnd}, $opts{decor}, $opts{left}, $opts{top},
46                      $opts{right}, $opts{bottom}, $opts{monitor});
47   }
48   elsif (defined $opts{id}) { # X11 window id
49     exists $opts{display} or $opts{display} = 0;
50     defined &_x11
51       or die "X11 driver not enabled\n";
52     $result = _x11($opts{display}, $opts{id}, $opts{left}, $opts{top},
53                    $opts{right}, $opts{bottom});
54   }
55   elsif (defined $opts{darwin}) { # as long as it's there
56     defined &_darwin
57       or die "Darwin driver not enabled\n";
58     $result = _darwin($opts{left}, $opts{top}, $opts{right}, $opts{bottom});
59   }
60   elsif ($opts{widget}) {
61     # Perl/Tk widget
62     my $top = $opts{widget}->toplevel;
63     my $sys = $top->windowingsystem;
64     if ($sys eq 'win32') {
65       unless (defined &_win32) {
66         Imager->_set_error("Win32 Tk and Win32 support not built");
67         return;
68       }
69       $result = _win32(hex($opts{widget}->id), $opts{decor}, 
70                        $opts{left}, $opts{top}, $opts{right}, $opts{bottom});
71     }
72     elsif ($sys eq 'x11') {
73       unless (defined &_x11) {
74         Imager->_set_error("X11 Tk and X11 support not built");
75         return;
76       }
77
78       my $id_hex = $opts{widget}->id;
79       
80       # is there a way to get the display pointer from Tk?
81       $result = _x11($opts{display}, hex($id_hex), $opts{left}, $opts{top},
82                      $opts{right}, $opts{bottom});
83     }
84     else {
85       Imager->_set_error("Unsupported windowing system '$sys'");
86       return;
87     }
88   }
89   else {
90     $result =
91       defined &_win32 ? _win32(0, $opts{decor}, $opts{left}, $opts{top},
92                                $opts{right}, $opts{bottom}, $opts{monitor}) :
93       defined &_darwin ? _darwin($opts{left}, $opts{top},
94                                  $opts{right}, $opts{bottom}) :
95       defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
96                              $opts{right}, $opts{bottom}) :
97            die "No drivers enabled\n";
98   }
99
100   unless ($result) {
101     Imager->_set_error(Imager->_error_as_msg());
102     return;
103   }
104
105   # RT #24992 - the Imager typemap entry is broken pre-0.56, so
106   # wrap it here
107   return bless { IMG => $result }, "Imager";
108 }
109
110 sub have_win32 {
111   defined &_win32;
112 }
113
114 sub have_x11 {
115   defined &_x11;
116 }
117
118 sub have_darwin {
119   defined &_darwin;
120 }
121
122 sub x11_open {
123   my $display = _x11_open(@_);
124   unless ($display) {
125     Imager->_set_error(Imager->_error_as_msg);
126     return;
127   }
128
129   return $display;
130 }
131
132 sub x11_close {
133   _x11_close(shift);
134 }
135
136 1;
137
138 __END__
139
140 =head1 NAME
141
142 Imager::Screenshot - screenshot to an Imager image
143
144 =head1 SYNOPSIS
145
146   use Imager::Screenshot 'screenshot';
147
148   # whole screen
149   my $img = screenshot();
150
151   # Win32 window
152   my $img2 = screenshot(hwnd => $hwnd);
153
154   # X11 window
155   my $img3 = screenshot(display => $display, id => $window_id);
156
157   # X11 tools
158   my $display = Imager::Screenshot::x11_open();
159   Imager::Screenshot::x11_close($display);
160
161   # test for win32 support
162   if (Imager::Screenshot->have_win32) { ... }
163
164   # test for x11 support
165   if (Imager::Screenshot->have_x11) { ... }
166   
167   # test for Darwin (Mac OS X) support
168   if (Imager::Screenshot->have_darwin) { ... }
169   
170
171 =head1 DESCRIPTION
172
173 Imager::Screenshot captures either a desktop or a specified window and
174 returns the result as an Imager image.
175
176 Currently the image is always returned as a 24-bit image.
177
178 =over
179
180 =item screenshot hwnd => I<window handle>
181
182 =item screenshot hwnd => I<window handle>, decor => <capture decorations>
183
184 =item screenshot hwnd => "active"
185
186 Retrieve a screenshot under Win32, if I<window handle> is zero,
187 capture the desktop.
188
189 By default, window decorations are not captured, if the C<decor>
190 parameter is set to true then window decorations are included.
191
192 As of 0.010 hwnd can also be C<"active"> to capture the active (or
193 "foreground") window.
194
195 =item screenshot hwnd => 0
196
197 Retrieve a screeshot of the default desktop under Win32.
198
199 =item screenshot hwnd => 0, monitor => -1
200
201 Retrieve a screenshot of all attached monitors under Win32.
202
203 Note: this returns an image with an alpha channel, since there can be
204 regions in the bounding rectangle of all monitors that no particular
205 monitor covers.
206
207 =item screenshot hwnd => 0, monitor => I<index>
208
209 Retrieve a screenshot from a particular monitor under Win32.  A
210 I<monitor> of zero is always treated as the primary monitor.
211
212 If the given monitor is not active screenshot() will fail.
213
214 =item screenshot id => I<window id>
215
216 =item screenshot id => I<window id>, display => I<display object>
217
218 Retrieve a screenshot under X11, if I<id> is zero, capture the root
219 window.  I<display object> is a integer version of an X11 C< Display *
220 >, if this isn't supplied C<screenshot()> will attempt connect to the
221 the display specified by $ENV{DISPLAY}.
222
223 Note: taking a screenshot of a remote display is slow.
224
225 =item screenshot darwin => 0
226
227 Retrieve a screenshot under Mac OS X.  The only supported value for
228 the C<darwin> parameter is C<0>.
229
230 For a screen capture to be taken, the current user using
231 Imager:Screenshot must be the currently logged in user on the display.
232
233 If you're using fast user switching, the current user must be the
234 active user.
235
236 Note: this means you can ssh into a Mac OS X box and screenshot from
237 the ssh session, if you're the current user on the display.
238
239 =item screenshot widget => I<widget>
240
241 =item screenshot widget => I<widget>, display => I<display>
242
243 =item screenshot widget => I<widget>, decor => I<capture decorations>
244
245 Retrieve a screenshot of a Tk widget, under Win32 or X11, depending on
246 how Tk has been built.
247
248 If Tk was built for X11 then the display parameter applies.
249
250 If Tk was built for Win32 then the decor parameter applies.
251
252 =item screenshot
253
254 If no C<id>, C<hwnd> or C<widget> parameter is supplied:
255
256 =over
257
258 =item *
259
260 if Win32 support is compiled, return screenshot(hwnd => 0).
261
262 =item *
263
264 if Darwin support is compiled, return screenshot(darwin => 0).
265
266 =item *
267
268 if X11 support is compiled, return screenshot(id => 0).
269
270 =item *
271
272 otherwise, die.
273
274 =back
275
276 You can also supply the following parameters to retrieve a subset of
277 the window:
278
279 =over
280
281 =item *
282
283 left
284
285 =item *
286
287 top
288
289 =item *
290
291 right
292
293 =item *
294
295 bottom
296
297 =back
298
299 If left or top is negative, then treat that as from the right/bottom
300 edge of the window.
301
302 If right ot bottom is zero or negative then treat as from the
303 right/bottom edge of the window.
304
305 So setting all 4 values to 0 retrieves the whole window.
306
307   # a 10-pixel wide right edge of the window
308   my $right_10 = screenshot(left => -10, ...);
309
310   # the top-left 100x100 portion of the window
311   my $topleft_100 = screenshot(right => 100, bottom => 100, ...);
312
313   # 10x10 pixel at the bottom right corner
314   my $bott_right_10 = screenshot(left => -10, top => -10, ...);
315
316 If screenshot() fails, it will return nothing, and the cause of the
317 failure can be retrieved via Imager->errstr, so typical use could be:
318
319   my $img = screenshot(...) or die Imager->errstr;
320
321 =item have_win32
322
323 Returns true if Win32 support is available.
324
325 =item have_x11
326
327 Returns true if X11 support is available.
328
329 =item have_darwin
330
331 Returns true if Darwin support is available.
332
333 =item Imager::Screenshot::x11_open
334
335 =item Imager::Screenshot::x11_open I<display name>
336
337 Attempts to open a connection to either the display name in
338 $ENV{DISPLAY} or the supplied display name.  Returns a value suitable
339 for the I<display> parameter of screenshot, or undef.
340
341 =item Imager::Screenshot::x11_close I<display>
342
343 Closes a display returned by Imager::Screenshot::x11_open().
344
345 =back
346
347 =head1 TAGS
348
349 screenshot() sets a number of tags in the images it returns, these are:
350
351 =over
352
353 =item *
354
355 ss_left - the distance between the left side of the window and the
356 left side of the captured area.  The same value as the I<left>
357 parameter when that is positive.
358
359 =item *
360
361 ss_top - the distance between the top side of the window the top side
362 of the captured area.  The same value at the I<top> parameter when
363 that is positive.
364
365 =item *
366
367 ss_window_width - the full width of the window.
368
369 =item *
370
371 ss_window_height - the full height of the window.
372
373 =item *
374
375 ss_type - the type of capture done, either "Win32" or "X11".
376
377 =back
378
379 To cheaply get the window size you can capture a single pixel:
380
381   my $im = screenshot(right => 1, bottom => 1);
382   my $window_width  = $im->tags(name => 'ss_window_width');
383   my $window_height = $im->tags(name => 'ss_window_height');
384
385 =head1 CAVEATS
386
387 It's possible to have more than one grab driver available, for
388 example, Win32 and X11, and which is used can have an effect on the
389 result.
390
391 Under Win32 or OS X, if there's a screesaver running, then you grab
392 the results of the screensaver.
393
394 On OS X, you can grab the display from an ssh session as long as the
395 ssh session is under the same user as the currently active user on the
396 display.
397
398 Grabbing the root window on a rootless server (eg. Cygwin/X) may not
399 grab the background that you see.  In fact, when I tested under
400 Cygwin/X I got the xterm window contents even when the Windows
401 screensaver was running.  The root window captured appeared to be that
402 generated by my window manager.
403
404 Grabbing a window with other windows overlaying it will capture the
405 content of those windows where they hide the window you want to
406 capture.  You may want to raise the window to top.  This may be a
407 security concern if the overlapping windows contain any sensitive
408 information - true for any screen capture.
409
410 =head1 LICENSE
411
412 Imager::Screenshot is licensed under the same terms as Perl itself.
413
414 =head1 TODO
415
416 Future plans include:
417
418 =over
419
420 =item *
421
422 window name searches - currently screenshot() requires a window
423 identifier of some sort, it would be more usable if we could supply
424 some other identifier, either a window title or a window class name.
425
426 =back
427
428 =head1 AUTHOR
429
430 Tony Cook <tonyc@cpan.org>
431
432 =cut
433
434