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